# -*- coding: utf-8 -*-
"""
Authors: Rejane Paulino, Felipe Nincao, Thainara Munhoz
National Institute for Space Research (INPE) - Instrumentation Laboratory for Aquatic Systems (LabISA)

Last update: 08 september 2022
"""

# Library:
import numpy as np
from osgeo import gdal
import numpy as np
import pandas as pd
import json
import os
from PIL import Image

#%%
# Excel file containing the central wavelenght, fwhm, name of each band for the specific image
# IMPORTANT -> The number of bands must be equal to the spectral response function
bands_prisma = pd.read_excel(
    'G:/Outros computadores/Meu modelo Laptop (1)/Documents/Mestrado/BEPE/atmospheric_correction/6S/prisma_bands_data.xlsx', header=0, index_col=0)
bands_prisma_acolite = bands_prisma.iloc[:, 1]

# TOA Reflectance -> each band must be saved in a unique folder
path_to_toa_reflectance = 'G:/Outros computadores/Meu modelo Laptop (1)/Documents/Mestrado/BEPE/atmospheric_correction/6S/PRISMA_04-09_rtoa/rhot_'

# Read the JSON file for the VNIR
with open('G:/Outros computadores/Meu modelo Laptop (1)/Documents/Mestrado/BEPE/atmospheric_correction/6S/PRISMA_04-09-21_resultados/6S_parameters_VNIR.json') as f:
    data = f.read()

dicionario_VNIR = json.loads(data)

# Read the JSON file for the SWIR
with open('G:/Outros computadores/Meu modelo Laptop (1)/Documents/Mestrado/BEPE/atmospheric_correction/6S/PRISMA_04-09-21_resultados/6S_parameters_SWIR.json') as f:
    data = f.read()

dicionario_SWIR = json.loads(data)

dicionario_completo = {**dicionario_VNIR, **dicionario_SWIR}

dic_aux = dicionario_completo

a = 0
for k in list(dic_aux.keys()):
    dicionario_completo[str(bands_prisma_acolite[a])] = dicionario_completo.pop(str(k))
    a = a + 1

#%%
# Apply the radiative transfer equation in each RTOA image considering the parameters from the 6S
for a in bands_prisma_acolite.values:

    string_band = path_to_toa_reflectance + str(a) + ".tiff"
    band_prisma = gdal.Open(string_band, gdal.GA_ReadOnly)
    array_prisma = band_prisma.GetRasterBand(1).ReadAsArray()

    # Atmospheric modeling:
    atmospheric_modeling_py6S_Band = dicionario_completo[str(a)]

    # Atmospheric Correction -> Equation Vermote et al. (2016):
    tg_OG_co = float(atmospheric_modeling_py6S_Band['co_transmittance_total'])
    tg_OG_c02 = float(
        atmospheric_modeling_py6S_Band['co2_transmittance_total'])
    tg_OG_o2 = float(
        atmospheric_modeling_py6S_Band['oxyg_transmittance_total'])
    tg_OG_no2 = float(
        atmospheric_modeling_py6S_Band['no2_transmittance_total'])
    tg_OG_ch4 = float(
        atmospheric_modeling_py6S_Band['ch4_transmittance_total'])

    # Total transmission of Other Gases -> Tg_OG:
    Tg_OG = float(tg_OG_co * tg_OG_c02 * tg_OG_o2 * tg_OG_no2 * tg_OG_ch4)

    # Total transmission of the Ozone -> Tg_O3:
    Tg_O3 = float(atmospheric_modeling_py6S_Band['ozone_transmittance_total'])

    # Total transmission of the Water Vapor -> Tg_H2O:
    Tg_H20 = float(atmospheric_modeling_py6S_Band['water_transmittance_total'])

    # Total transmittance upward (Rayleigh + Aerosol) -> T_upward:
    T_upward = float(
        atmospheric_modeling_py6S_Band['total_scattering_transmittance_upward'])

    # Total transmittance downward (Rayleigh + Aerosol) -> T_downward:
    T_downward = float(
        atmospheric_modeling_py6S_Band['total_scattering_transmittance_downward'])

    # Total transmission of the atmosphere -> T_atm:
    T_atm = float(T_upward * T_downward)

    # Atmosphere intrinsic reflectance -> p_atm:
    p_atm = float(
        atmospheric_modeling_py6S_Band['atmospheric_intrinsic_reflectance'])

    # Atmosphere spherical albedo -> s_atm:
    s_atm = float(atmospheric_modeling_py6S_Band['spherical_albedo'])

    # Equation (Ref: Vermonte et al., 1997)
    f1 = Tg_OG * Tg_O3 * Tg_H20 * T_atm
    f2 = p_atm / (Tg_H20 * T_atm)
    parte_1 = np.divide(array_prisma, f1)
    parte_2 = np.subtract(parte_1, f2)
    parte_3 = np.multiply(parte_2, s_atm)
    parte_4 = np.add(parte_3, 1)
    p_s = parte_2 / parte_4

    rrs = np.divide(p_s, np.pi) # Calculate de Rrs

    rrs[rrs == rrs[0][0]] = 0

    img_tiff = Image.fromarray(rrs,mode='F')
    # Save each surface reflectance image in a separate file
    name = 'C:/Users/thain/Documents/6S_run/rhos_' + str(a) + '.tiff'
    img_tiff.save(name,'TIFF')

    band_prisma = None

    print(a)

print('FIM')

# %%
# Join all the bands in a stack file:
file_list = ['C:/Users/thain/Documents/6S_run/rhos_' +
             str(k) + '.tiff' for k in bands_prisma_acolite.iloc[0:63]] #Considering only the VNIR (bands 0-63)

files_string = " ".join(file_list)

command_to_join = "gdalbuildvrt -separate stack_6s.vrt " + files_string

os.system(command_to_join)

os.system('gdal_translate stack_6s.vrt PRISMA_6s_rrs_VNIR.tif')

#%%
#Clean the folder
for k in bands_prisma_acolite.values:
    if os.path.exists('C:/Users/thain/Documents/6S_run/rhos_' + str(k) + '.tiff'):
        os.remove('C:/Users/thain/Documents/6S_run/rhos_' + str(k) + '.tiff')


import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

path = 'df_train.csv'
data = pd.read_csv(path)

filter_fever = data.loc[data['ONSET_FEVER'] == 1]
filter_cough = data.loc[data['ONSET_COUGH'] == 1]
filter_tired = data.loc[data['ONSET_TIRED'] == 1]
filter_sorethroat = data.loc[data['ONSET_SORETHROAT'] == 1]
filter_respiratory = data.loc[data['ONSET_RESPIRATORY'] == 1]

def get_los(filter_onset):
    los = filter_onset.iloc[:, 17:].values
    return np.reshape(los, len(los)).tolist()

los_fever = get_los(filter_fever)
los_cough = get_los(filter_cough)
los_tired = get_los(filter_tired)
los_sorethroat = get_los(filter_sorethroat)
los_respiratory = get_los(filter_respiratory)

combine_los = [los_fever, los_cough, los_tired, los_sorethroat, los_respiratory]

plt.boxplot(combine_los)
plt.xticks([1, 2, 3, 4, 5], ['FEVER', 'COUGH', 'TIRED', 'SORETHROAT', 'RESPIRATORY'], fontsize=14)
plt.yticks(fontsize=14)
plt.ylabel('Length of stay', fontsize=20)
plt.title('Length of stay with respect to onset symptoms', fontsize=24)
plt.show()


from web3 import Web3, HTTPProvider
import rlp
import json
import math
from ethereum.transactions import Transaction

class Land:
    def run(self):
        # desc
        # -112 <= x <= -68
        # -22 <= y <= 22
        # --
        Land_ADDRESS = "0x1a587212c0e35922ee79e4ff876c5e4e600fc877"
        ETH_RPC = "https://kovan.infura.io/ZWef2NOidUm5XooBYqgl"
        USER_ADDRESS = "0xda7fab79bfd0a27f04367f5b9b9348cb5d1b0023"
        PANGU_ADDRESS = "0xda7fab79bfd0a27f04367f5b9b9348cb5d1b0023"

        CREATE_PRI_KEY = ""

        w3 = Web3(HTTPProvider(ETH_RPC, request_kwargs={'timeout': 120}))
        with open('resource.json', 'r') as resource_definition:
            resource_json = json.load(resource_definition)
        nonce = w3.eth.getTransactionCount(USER_ADDRESS),
        nonce = nonce[0]

        for index, resource in enumerate(resource_json):
            x = -112 + index % 45
            y = 22 - int(index / 45)
            execute_transaction = "0x6bd50a14" + self.u256ToInput(x) + self.u256ToInput(y) + self.pandding(PANGU_ADDRESS)
            tx = Transaction(
                nonce=nonce + index,
                gasprice=2000000000,
                startgas=1000000,
                to=Land_ADDRESS,
                value=0,
                data=w3.toBytes(hexstr=execute_transaction),
            )
            tx.sign(CREATE_PRI_KEY)
            raw_tx = rlp.encode(tx)
            raw_tx_hex = w3.toHex(raw_tx)
            tx = w3.eth.sendRawTransaction(raw_tx_hex)
            print(tx)
            break

    def pandding(self, format):
        if format.startswith('0x'):
            format = format[2:]
        return format.rjust(64, '0')

    def panddingF(self, format):
        if format.startswith('0x'):
            format = format[2:]
        return format.rjust(64, 'f')

    def u256ToInput(self, u):
        if u >= 0:
            hex = "{:x}".format(u)
            return self.pandding(hex)
        else:
            if abs(u) == 1:
                hex = "{:x}".format(16 - abs(u))
            else:
                hex = "{:x}".format(int(pow(16, math.ceil(math.log(abs(u), 16))) + u))
            return self.panddingF(hex)

if __name__ == '__main__':
    ld = Land()
    ld.run()


from sqlalchemy.orm import sessionmaker

from setting_db import engine
import models, valid

models.Base.metadata.create_all(bind=engine)

# This method opens a connection with the database then there is a search by user id then it returns the full user
# data namely phone email and login
def get_id(id: int):
    db = sessionmaker(autocommit=False, autoflush=False, bind=engine)
    session = db()
    user = session.query(models.User).filter(models.User.id == id).first()
    return user

# adding a new user after receiving data recording and saving to the database
def add_user(user: valid.User):
    db = sessionmaker(autocommit=False, autoflush=False, bind=engine)
    session = db()
    db_user = models.User(login=user.login, email=user.email, phone=user.phone)
    session.add(db_user)
    session.commit()
    session.refresh(db_user)
    return db_user


import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
import sys
import math
from pandas.api.types import CategoricalDtype
from scipy import stats as sci
from scipy.stats import linregress
from scipy.stats.mstats import gmean
from scipy.stats import gstd
from sklearn.utils import resample
import pdb
from sklearn.metrics import r2_score
from statistics import median
import scikit_posthocs as sp
import warnings
# np.seterr(all='raise')

def get_pass_grubbs_test(plate_df, groupby_list, col="Cq"):
  # make list that will become new df
  plate_df_with_grubbs_test = pd.DataFrame()

  # iterate thru the dataframe, grouped by Sample
  # this gives us a mini-df with just one sample in each iteration
  for groupby_list, df in plate_df.groupby(groupby_list,  as_index=False):
    d = df.copy() # avoid set with copy warning

    # make new column 'grubbs_test' that includes the results of the test
    if (len(d[col].dropna())<3): #cannot evaluate for fewer than 3 values
        if (len(d[col].dropna())==2): #no outlier removal if just 2 pts
            d.loc[:, 'grubbs_test'] = True
            plate_df_with_grubbs_test=plate_df_with_grubbs_test.append(d)
        else:
            d.loc[:, 'grubbs_test'] = False
            plate_df_with_grubbs_test=plate_df_with_grubbs_test.append(d)

    else:

        b=list(d[col]) #needs to be given unindexed list
        if all([element == b[0] for element in b]): #grubbs doesn't like when all are the same
            d.loc[:, 'grubbs_test'] = True
            plate_df_with_grubbs_test=plate_df_with_grubbs_test.append(d)
        else:
            nonoutliers= sp.outliers_grubbs(b)
            outlier_len=len(b)-len(nonoutliers)
            if outlier_len > 0:
                d.loc[:, 'grubbs_test'] = False
                d.loc[d[col].isin(nonoutliers), 'grubbs_test'] = True
                plate_df_with_grubbs_test=plate_df_with_grubbs_test.append(d)
            else:
                d.loc[:, 'grubbs_test'] = True
                plate_df_with_grubbs_test=plate_df_with_grubbs_test.append(d)
  return(plate_df_with_grubbs_test)

def compute_linear_info(plate_data):
    '''compute the information for linear regression

    Params
        plate_data: pandas dataframe with columns
            Cq_mean (already processed to remove outliers)
            log_Quantity
    Returns
        slope, intercept, r2, efficiency
    '''
    y = plate_data['Cq_mean']
    x = plate_data['log_Quantity']
    model = np.polyfit(x, y, 1)
    predict = np.poly1d(model)
    r2 = r2_score(y, predict(x))
    slope, intercept = model
    efficiency = (10**(-1/slope)) - 1

    return(slope, intercept, r2, efficiency )

def combine_triplicates(plate_df_in, checks_include, master, use_master_curve):
    '''
    Flag outliers via grubbs test
    Calculate the Cq means, Cq stds, counts before & after removing outliers

    Params
    plate_df_in:
        qpcr data in pandas df, must be 1 plate with 1 target
        should be in the format from QuantStudio3 with
        columns 'Target', 'Sample', 'Cq'
    checks_include: must be set to 'grubbs_only'

    Returns
    plate_df: same data, with additional columns depending on checks_include
        grubbs_test (True or False) -- did it pass
        Cq_mean (calculated mean of Cq after excluding outliers)

    Note: Cq_raw preserves the raw values, Cq_fin is after subbing and outlier removal, and plain Cq_subbed is after subbing (so that it goes through grubbs)

    '''

    if (checks_include not in ['grubbs_only']):
        raise ValueError('''invalid input, must be grubbs_only''')

    if len(plate_df_in.Target.unique()) > 1:
        raise ValueError('''More than one target in this dataframe''')

    target= plate_df_in.Target.unique()
    plate_df = plate_df_in.copy() # fixes pandas warnings

    groupby_list = ['plate_id', 'Sample', 'sample_full','Sample_plate',
                    'Target','Task', 'inhibition_testing','is_dilution',"dilution"]

    # make copy of Cq column and later turn this to np.nan for outliers
    plate_df['Cq_raw'] = plate_df['Cq'].copy()
    plate_df["master_curve_bloq_qpcr_reps"]=False
    if ((use_master_curve) & (target[0] != "Xeno")):
        plate_df.loc[ (np.isnan(plate_df.Cq))| (plate_df.Cq>40), "master_curve_bloq_qpcr_reps"]= True
        plate_df.loc[ (np.isnan(plate_df.Cq))| (plate_df.Cq>40), "Cq"]= master.loc[master.Target==target[0], "LoD_Cq"].item()

    plate_df['Cq_subbed'] = plate_df['Cq'].copy()
    plate_df['Cq_fin'] = plate_df['Cq'].copy()

    # grubbs with scikit
    if checks_include == 'grubbs_only':
       plate_df = get_pass_grubbs_test(plate_df, ['Sample'])
       plate_df.loc[plate_df.grubbs_test== False, 'Cq_fin'] = np.nan

    # summarize to get mean, std, counts with and without outliers removed
    plate_df_avg = plate_df.groupby(groupby_list).agg(
                                               raw_Cq_values=('Cq_raw',list),
                                               sub_Cq_values=('Cq_subbed',list),
                                               outlier_Cq_values=('Cq_fin',list),
                                               template_volume=('template_volume','max'),
                                               Q_init_mean=('Quantity','mean'), #only needed to preserve quantity information for standards later
                                               Q_init_std=('Quantity','std'),
                                               Q_init_gstd=('Quantity', lambda x: np.nan if ( (len(x.dropna()) <2 )| all(np.isnan(x)) ) else (sci.gstd(x.dropna(),axis=0))),
                                               Cq_init_mean=('Cq_raw', 'mean'),
                                               Cq_init_std=('Cq_raw', 'std'),
                                               Cq_init_min=('Cq_raw', 'min'),
                                               replicate_init_count=('Cq','count'),
                                               Cq_mean=('Cq_fin', 'mean'),
                                               Cq_std=('Cq_fin', 'std'),
                                               replicate_count=('Cq_fin', 'count'),
                                               is_undetermined_count=('is_undetermined', 'sum'),
                                               is_bloq_count=('master_curve_bloq_qpcr_reps', 'sum')
                                               )
    plate_df_avg = plate_df_avg.reset_index()
    return(plate_df, plate_df_avg)

def process_standard(plate_df):
    '''
    from single plate with single target, calculate standard curve

    Params:
        plate_df: output from combine_triplicates(); df containing Cq_mean
        must be single plate with single target
    Returns
        num_points: number of points used in new std curve
        Cq_of_lowest_std_quantity: the Cq value of the lowest pt used in the new std curve
        lowest_std_quantity: the Quantity value of the lowest pt used in the new std curve
        Cq_of_lowest_std_quantity_gsd: geometric standard dviation of the Cq of the lowest standard quantity
        slope:
        intercept:
        r2:
        efficiency:
    '''
    if len(plate_df.Target.unique()) > 1:
        raise ValueError('''More than one target in this dataframe''')

    #what is the lowest sample Cq and quantity on this plate
    standard_df = plate_df[plate_df.Task == 'Standard'].copy()

    # require at least 2 triplicates or else convert to nan
    standard_df = standard_df[standard_df.replicate_count > 1]

    standard_df['log_Quantity'] = np.log10(standard_df['Q_init_mean'])
    std_curve_df = standard_df[['Cq_mean', 'log_Quantity', "Cq_std"]].drop_duplicates().dropna()
    num_points = std_curve_df.shape[0]

    if (all(standard_df.Cq_mean == "") | len(standard_df.Cq_mean) <2):
        slope, intercept, r2, efficiency,Cq_of_lowest_std_quantity,Cq_of_lowest_std_quantity_gsd,lowest_std_quantity =  np.nan, np.nan, np.nan,np.nan, np.nan,np.nan, np.nan
    else:
        #find the Cq of the lowest standard quantity
        Cq_of_lowest_std_quantity = max(standard_df.Cq_mean)
        sort_a=standard_df.sort_values(by='Cq_mean',ascending=True).copy().reset_index()
        sort_a=standard_df.sort_values(by='Cq_mean',ascending=True).copy().reset_index()
        Cq_of_lowest_std_quantity_gsd = sort_a.Cq_std[0]

        # the  lowest standard quantity
        lowest_std_quantity = np.nan
        sort_b=standard_df.sort_values(by='Q_init_mean',ascending=True).copy().reset_index()
        slope, intercept, r2, efficiency = (np.nan, np.nan, np.nan, np.nan)

        if num_points > 2:
            lowest_std_quantity = sort_b.Q_init_mean.values[0]
            slope, intercept, r2, efficiency = compute_linear_info(std_curve_df)

    return(num_points, Cq_of_lowest_std_quantity,  lowest_std_quantity, Cq_of_lowest_std_quantity_gsd,  slope, intercept, r2, efficiency)

def process_unknown(plate_df, std_curve_info, use_master_curve, master):
    '''
    Calculates quantity based on Cq_mean and standard curve
    Params
        plate_df: output from combine_triplicates(); df containing Cq_mean
        must be single plate with single target
        std_curve_info: output from process_standard() as a list
    Returns
        unknown_df: the unknown subset of plate_df, with new columns
        Quantity_mean
        q_diff
        Cq_of_lowest_sample_quantity: the Cq value of the lowest pt used on the plate
        these columns represent the recalculated quantity using Cq mean and the
        slope and intercept from the std curve
        qpcr_coefficient_var the coefficient of variation for qpcr technical triplicates
        intraassay_var intraassay variation (arithmetic mean of the coefficient of variation for all triplicates on a plate)
    '''

    [num_points, Cq_of_lowest_std_quantity,  lowest_std_quantity, Cq_of_lowest_std_quantity_gsd, slope, intercept, r2, efficiency] = std_curve_info
    unknown_df = plate_df[plate_df.Task != 'Standard'].copy()
    unknown_df['Cq_of_lowest_sample_quantity'] = np.nan
    unknown_df['percent_CV']=(unknown_df['Q_init_gstd']-1)*100#the geometric std - 1 is the coefficient of variation using quant studio quantities to capture all the variation in the plate
    if all(np.isnan(unknown_df['percent_CV'])):
        unknown_df['intraassay_var'] = np.nan #avoid error
    else:
        unknown_df['intraassay_var']= np.nanmean(unknown_df['percent_CV'])

    # Set the Cq of the lowest std quantity for different situations
    if len(unknown_df.Task) == 0: #only standard curve plate
        unknown_df['Cq_of_lowest_sample_quantity'] = np.nan
    else:
        if all(np.isnan(unknown_df.Cq_mean)): #plate with all undetermined samples
            unknown_df['Cq_of_lowest_sample_quantity']= np.nan #avoid error
        else:
            targs=unknown_df.Target.unique() #other  plates (most  cases)
            for target in targs:
                unknown_df.loc[(unknown_df.Target==target),'Cq_of_lowest_sample_quantity']=np.nanmax(unknown_df.loc[(unknown_df.Target==target),'Cq_mean']) #because of xeno

    unknown_df['Quantity_mean'] = np.nan
    unknown_df['q_diff'] = np.nan

    if ~use_master_curve:
        unknown_df["blod_master_curve"]=False
        unknown_df['Quantity_mean'] = 10**((unknown_df['Cq_mean'] - intercept)/slope)

        #initialize columns
        unknown_df['Quantity_std_combined_after']=np.nan
        unknown_df['Quantity_mean_combined_after']=np.nan
        for row in unknown_df.itertuples():
            ix=row.Index
            filtered_1= [element for element in row.raw_Cq_values if ~np.isnan(element) ] #initial nas
            filtered= [10**((element - intercept)/slope) for element in filtered_1]
            if(len(filtered)>1):
                    filtered= [element for element in filtered if ~np.isnan(element) ] #nas introduced when slope and interceptna
                    if(len(filtered)>1):
                        if (row.Target != "Xeno"):
                            unknown_df.loc[ix,"Quantity_mean_combined_after"]=sci.gmean(filtered)
                            if(all(x >0 for x in filtered)):
                                unknown_df.loc[ix,"Quantity_std_combined_after"]=sci.gstd(filtered)
    if use_master_curve:
        targs=unknown_df.Target.unique()
        for targ in targs:
            if targ != "Xeno":
                unknown_df["blod_master_curve"]=False
                m_b=master.loc[master.Target==targ, "b"].item()
                m_m=master.loc[master.Target==targ, "m"].item()
                lowest=master.loc[master.Target==targ, "lowest_quantity"].item()
                lod=master.loc[master.Target==targ, "LoD_quantity"].item()
                unknown_df.loc[unknown_df.Target==targ, 'Quantity_mean'] = 10**((unknown_df.loc[unknown_df.Target==targ, 'Cq_mean'] - m_b)/m_m)
                unknown_df.loc[unknown_df.Quantity_mean< lowest, "blod_master_curve"] = True
                unknown_df.loc[unknown_df.Quantity_mean< lowest, 'Quantity_mean'] = lod

    unknown_df.loc[unknown_df[unknown_df.Cq_mean == 0].index, 'Quantity_mean'] = np.nan
    unknown_df['q_diff'] = unknown_df['Q_init_mean'] - unknown_df['Quantity_mean']

    return(unknown_df)

def process_ntc(plate_df):
    ntc = plate_df[plate_df.Task == 'Negative Control']
    ntc_result = np.nan
    if ntc.is_undetermined.all():
        ntc_result = 'negative'
    else:
        if all(np.isnan(ntc.Cq)):
            ntc_result = np.nan #avoid error
        else:
            ntc_result = np.nanmin(ntc.Cq)
    return(ntc_result)

def determine_samples_BLoD(raw_outliers_flagged_df, checks_include):
        '''
        For each target in raw qpcr data, this function defines the limit of detection as the fraction of qpcr replicates at a quantity that are detectable
        It works depending on which test was selected, so if grubbs was selected, it only evaluates for replicates that pass grubbs

        Params:
            Task
            Quantity
            Target
            Cq
            Sample
        prints a dataframe with Target and the limit of detection
        '''
        dfm= raw_outliers_flagged_df
        dfm=dfm[dfm.Task=='Standard'] #only standards
        dfm=dfm[dfm.Quantity!=0] #no NTCs
        assay_assessment_df=pd.DataFrame(columns=["Target","LoD_Cq","LoD_Quantity"]) #empty dataframe with desired columns

        #iterate through targets, groupby quantity, and determine the fraction of the replicates that were detectable
        targs=dfm.Target.unique()
        for target in targs:
            print(target)
            df_t=dfm[dfm.Target==target].copy()
            out=df_t.groupby(["Quantity"]).agg(
                                    Cq_mean=('Cq', 'mean'),
                                    negatives=('is_undetermined','sum'),
                                    total=('Sample', 'count')).reset_index()
            out['fr_pos']=(out.total-out.negatives)/out.total
            print(out)
        return (assay_assessment_df)

def determine_samples_BLoQ(qpcr_p):
    '''
    from processed unknown qpcr data this will return qpcr_processed with a boolean column indicating samples bloq
    (as defined as Cq < 40 and within the standard curve)
    samples that have Cq_mean that is nan are classified as bloq (including true negatives and  samples removed during processing)
    Params:
        Cq_mean the combined triplicates of the sample
        Cq_of_lowest_sample_quantity the max cq of the samples on the plate

    Returns
        same data with column bloq a boolean column indicating if the sample is below the limit of quantification
    '''
    qpcr_p['bloq']=np.nan
    qpcr_p.loc[(np.isnan(qpcr_p.Cq_mean)),'bloq']= True
    qpcr_p.loc[(qpcr_p.Cq_mean >= 40),'bloq']= True
    qpcr_p.loc[(qpcr_p.Cq_mean > qpcr_p.Cq_of_lowest_std_quantity),'bloq']= True
    qpcr_p.loc[(qpcr_p.Cq_mean <= qpcr_p.Cq_of_lowest_std_quantity)&(qpcr_p.Cq_mean < 40),'bloq']= False
    return(qpcr_p)

def process_qpcr_raw(qpcr_raw, master=np.nan, use_master_curve=False, checks_include='grubbs_only'):
    '''wrapper to process whole sheet at once by plate_id and Target
    params
    qpcr_raw: df from read_qpcr_data()
    checks_include must be grubbs_only
    '''
    if (checks_include not in ['grubbs_only']):
        raise ValueError('''invalid input, must be grubbs_only''')
    std_curve_df = []
    qpcr_processed = []
    raw_outliers_flagged_df = []
    for [plate_id, target], df in qpcr_raw.groupby(["plate_id", "Target"]):

        ntc_result = process_ntc(df)
        outliers_flagged, no_outliers_df = combine_triplicates(df, checks_include, master, use_master_curve)

        # define outputs and fill with default values
        num_points,  Cq_of_lowest_std_quantity,lowest_std_quantity, Cq_of_lowest_std_quantity_gsd, slope, intercept, r2, efficiency = np.nan,np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan

        # if there are >3 pts in std curve, calculate stats and recalculate quants
        num_points = no_outliers_df[no_outliers_df.Task == 'Standard'].drop_duplicates('Sample').shape[0]
        num_points,  Cq_of_lowest_std_quantity, lowest_std_quantity, Cq_of_lowest_std_quantity_gsd, slope, intercept, r2, efficiency = process_standard(no_outliers_df)
        std_curve_info = [num_points,  Cq_of_lowest_std_quantity, lowest_std_quantity, Cq_of_lowest_std_quantity_gsd, slope, intercept, r2, efficiency]
        unknown_df = process_unknown(no_outliers_df, std_curve_info, use_master_curve, master)
        std_curve_df.append([plate_id, target, num_points,  Cq_of_lowest_std_quantity, lowest_std_quantity, Cq_of_lowest_std_quantity_gsd, slope, intercept, r2, efficiency, ntc_result])
        qpcr_processed.append(unknown_df)
        raw_outliers_flagged_df.append(outliers_flagged)

    # compile into dataframes
    raw_outliers_flagged_df = pd.concat(raw_outliers_flagged_df)
    assay_assessment_df=determine_samples_BLoD(raw_outliers_flagged_df, checks_include) #only prints a dataframe
    std_curve_df = pd.DataFrame.from_records(std_curve_df,
                                             columns = ['plate_id',
                                                        'Target',
                                                        'num_points',
                                                        'Cq_of_lowest_std_quantity',
                                                        'lowest_std_quantity',
                                                        'Cq_of_lowest_std_quantity_gsd',
                                                        'slope',
                                                        'intercept',
                                                        'r2',
                                                        'efficiency',
                                                        'ntc_result'])
    qpcr_processed = pd.concat(qpcr_processed)
    qpcr_processed = qpcr_processed.merge(std_curve_df, how='left', on=['plate_id', 'Target'])
    control_df=qpcr_processed[(qpcr_processed.Sample.str.contains("control"))|(qpcr_processed.Task!="Unknown")].copy()
    qpcr_processed=qpcr_processed[qpcr_processed.Task=="Unknown"].copy()

    #make  columns calculated in other functions to go in the standard curve info
    qpcr_m=qpcr_processed[["plate_id","Target","Cq_of_lowest_sample_quantity",'intraassay_var']].copy().drop_duplicates(keep='first')
    std_curve_df=std_curve_df.merge(qpcr_m, how='left') # add Cq_of_lowest_sample_quantity and intraassay variation

    if ~use_master_curve:
        qpcr_processed= determine_samples_BLoQ(qpcr_processed)
    std_curve_df=std_curve_df[std_curve_df.Target != "Xeno"].copy()

    #check for duplicates
    a=qpcr_processed[(qpcr_processed.Sample!="__")&(qpcr_processed.Sample!="")]
    a=a[a.duplicated(["Sample","Target"],keep=False)].copy()
    if len(a) > 0:
        plates=a.plate_id.unique()
        l=len(plates)
        warnings.warn("\n\n\n {0} plates have samples that are double listed in qPCR_Cts spreadsheet. Check the following plates and make sure one is_primary_value is set to N:\n\n\n{1}\n\n\n".format(l,plates))

    return(qpcr_processed, std_curve_df, raw_outliers_flagged_df, control_df)


"""Library to perform various corrections on native 6X imagery."""

import re
import setuptools

VERSIONFILE = "correct6x/_version.py"
verstrline = open(VERSIONFILE, "rt").read()
VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]"
mo = re.search(VSRE, verstrline, re.M)
if mo:
    verstr = mo.group(1)
else:
    raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,))

setuptools.setup(
    name="py6x",
    version=verstr,
    description="Correction library for Sentera 6X imagery.",
    packages=setuptools.find_packages(),
    install_requires=[
        "Pillow",
        "numpy",
        "tifffile",
        "pandas",
        "tqdm",
        "opencv-contrib-python",
        "imgparse @ git+https://github.com/SenteraLLC/py-image-metadata-parser.git@v1.9.2"
    ],
    extras_require={
        "dev": ["pytest", "sphinx_rtd_theme", "pre-commit", "m2r", "sphinx"],
    },
)


from flask import render_template,url_for,redirect,request,flash
from . import db,app
from .forms import ClientForm,DoctorForm,MedicalHistoryForm
from .models import Client,Doctor,MedicalHistory

def index():
    return 'arl kot'

def client_create():
    form=ClientForm()
    if request.method=='POST':
        if form.validate_on_submit():
            client=Client()
            form.populate_obj(client)
            db.session.add(client)
            db.session.commit()
            flash("успешно",'succes')
            return redirect(url_for('client_list'))
        else:
            print(form.errors)
    return render_template('standart_form.html',form=form)

def doctor_create():
    form=DoctorForm()
    if request.method=='POST':
        if form.validate_on_submit():
            doctor=Doctor()
            form.populate_obj(doctor)
            db.session.add(doctor)
            db.session.commit()
            flash("успешно",'succes')
            return redirect(url_for('doctor_list'))
        else:
            flash('ошибка', 'danger')
    return render_template('standart_form.html',form=form)

def history():
    form=MedicalHistoryForm()
    form.doctor_id.choices=[(g.id, g.fio) for g in Doctor.query.order_by('fio')]
    form.client_id.choices=[(g.id, g.fio) for g in Client.query.order_by('fio')]
    if request.method=="POST":
        if form.validate_on_submit():
            history=MedicalHistory()
            form.populate_obj(history)
            db.session.add(history)
            db.session.commit()
            flash("история успешно создана","succes")
            return redirect(url_for('history_list'))
        else:
            flash('ошибка','danger')
    return render_template('standart_form.html',form=form)

def doctor_list():
    doctors=Doctor.query.all()
    return render_template('doctor_list.html',doctors=doctors)

def client_list():
    clients=Client.query.all()
    return render_template('client_list.html',clients=clients)

def history_list():
    histories=MedicalHistory.query.all()
    return render_template('history_list.html',histories=histories)


def polegada_para_cm(polegada):
    return polegada * 2.54

def pe_para_cm(pe):
    return pe * 30.48

def main():
    i = int(input("Selecione: (1) polegada->cm (2) pé->cm: "))
    n = int(input("Digite o valor: "))
    if i == 1:
        unidade = "polegadas"
        resultado = polegada_para_cm(n)
    elif i == 2:
        unidade = "pés"
        resultado = pe_para_cm(n)
    else:
        print("Você tá louco. Tente novamente")
        main()

    print("{n} {unidade} equivale a {resultado} cm".format(
        n=n,
        unidade=unidade,
        resultado=resultado
    ))

print()
main()


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

import numpy as np

def full_generator(X, y1, y2, y3, y4, batch_size, number_of_batches, shuffle, infinite=True):
    #number_of_batches = X.shape[0]/batch_size

    sample_index = np.arange(X.shape[0])

    counter = 0
    if shuffle:
        np.random.shuffle(sample_index)

    while True:
        batch_index = sample_index[batch_size*counter:batch_size*(counter+1)]

        tmp_batch_size = len(X[batch_index])
        X_batch = np.empty((tmp_batch_size, X[0].shape[0]))
        y_batch1 = np.empty((tmp_batch_size, y1[0].shape[1]))
        y_batch2 = np.empty((tmp_batch_size, y2[0].shape[1]))
        y_batch3 = np.empty((tmp_batch_size, y3[0].shape[1]))
        y_batch4 = np.empty((tmp_batch_size, y4[0].shape[1]))
        counter += 1

        for b in range(tmp_batch_size):
            X_text  =  X[batch_index][b]
            y_sparse1 = y1[batch_index][b]
            y_sparse2 = y2[batch_index][b]
            y_sparse3 = y3[batch_index][b]
            y_sparse4 = y4[batch_index][b]

            X_batch[b,] = [X_text][0]
            y_batch1[b,] = y_sparse1.toarray()
            y_batch2[b,] = y_sparse2.toarray()
            y_batch3[b,] = y_sparse3.toarray()
            y_batch4[b,] = y_sparse4.toarray()

        yield X_batch, [y_batch1, y_batch2, y_batch3, y_batch4]

        if (counter == number_of_batches):
            if not infinite:
                break
            if shuffle:
                np.random.shuffle(sample_index)
            counter = 0


"""
Vous allez definir une classe pour chaque algorithme que vous allez développer,
votre classe doit contenit au moins les 3 méthodes definies ici bas,
	* train 	: pour entrainer le modèle sur l'ensemble d'entrainement.
	* predict 	: pour prédire la classe d'un exemple donné.
	* evaluate 		: pour evaluer le classifieur avec les métriques demandées.
vous pouvez rajouter d'autres méthodes qui peuvent vous etre utiles, mais la correction
se fera en utilisant les méthodes train, predict et evaluate de votre code.
"""
import math
import time
from classifier import Classifier

# le nom de votre classe
# BayesNaif pour le modèle bayesien naif
# Knn pour le modèle des k plus proches voisins

class BayesNaif(Classifier): #nom de la class à changer
    """
    C'est un Initializer.
    Vous pouvez passer d'autre paramètres au besoin,
    c'est à vous d'utiliser vos propres notations
    """
    def __init__(self, **kwargs):
        self.training_data = None
        self.training_labels = None
        self.possibleClasses = None
        self.means = None
        self.variances = None
        self.classProbabilities = None

    """
    C'est la méthode qui va entrainer votre modèle,
    train est une matrice de type Numpy et de taille nxm, avec
    n : le nombre d'exemple d'entrainement dans le dataset
    m : le mobre d'attribus (le nombre de caractéristiques)

    train_labels : est une matrice numpy de taille nx1

    vous pouvez rajouter d'autres arguments, il suffit juste de
    les expliquer en commentaire

    """
    def train(self, train, train_labels): #vous pouvez rajouter d'autres attributs au besoin
        startTime = time.time()
        self.training_data = train
        self.training_labels = train_labels
        self.possibleClasses = list(set(train_labels))
        numberTrainCases = len(train)
        numberClasses = len(self.possibleClasses)
        numberFeatures = len(train[0])
        self.means = [[] for _ in range(numberClasses)]
        self.variances = [[] for _ in range(numberClasses)]
        self.classProbabilities = [0 for _ in range(numberClasses)]
        for numClass in range(numberClasses):
            indices = [i for i in range(numberTrainCases) if train_labels[i] == self.possibleClasses[numClass]]
            self.classProbabilities[numClass] = len(indices) / float(numberTrainCases)
            for feature in range(numberFeatures):
                featureValues = [train[clazz][feature] for clazz in indices]
                mean = sum(featureValues) / float(len(featureValues))
                variance = sum([(f - mean)**2 for f in featureValues]) / float(len(featureValues) - 1)
                self.means[numClass].append(mean)
                self.variances[numClass].append(variance)
        print("Elapsed time training: " + str(time.time() - startTime))

    """
    Prédire la classe d'un exemple x donné en entrée
    exemple est de taille 1xm
    """
    def predict(self, data):
        maxProbability = -1
        bestClass = -1
        for clazz in range(len(self.possibleClasses)):
            probability = self.classProbabilities[clazz]
            for feature in range(len(self.means[clazz])):
                mean = self.means[clazz][feature]
                variance = self.variances[clazz][feature]
                x = data[feature]
                probability *= (1 / (math.sqrt(2 * math.pi * variance))) * math.exp(-((x - mean)**2) / (2 * variance))
            if probability > maxProbability:
                maxProbability = probability
                bestClass = self.possibleClasses[clazz]
        return bestClass


import logging
import threading
from typing import List, Optional

from injector import singleton, inject

from gst.model.monitored_item import MonitoredItem
from gst.model.system_info import SystemInfo
from gst.util import sensors
from gst.util.concurrency import synchronized_with_attr
from gst.util.sensors import FeatureType

_LOG = logging.getLogger(__name__)
_SHORT_NAME_AVERAGE = 'average'
_SHORT_NAME_INPUT = 'input'
_SENSOR_MIN_TEMP = -127
_SENSOR_MAX_TEMP = 215

@singleton
class LmSensorsRepository:
    @inject
    def __init__(self) -> None:
        self._lock = threading.RLock()

    @synchronized_with_attr("_lock")
    def refresh(self, system_info: SystemInfo) -> SystemInfo:
        sensors.init()
        for chip in sensors.ChipIterator():
            chip_name = sensors.chip_snprintf_name(chip)
            for feature in sensors.FeatureIterator(chip):
                subfeatures = list(sensors.SubFeatureIterator(chip, feature))  # get a list of all subfeatures

                item_id = feature.name.decode("utf-8")
                item_name = sensors.get_label(chip, feature)
                item_value: Optional[float] = None
                item_average_value: Optional[float] = None
                item_type = sensors.FeatureType(feature.type)

                skipname = len(feature.name) + 1  # skip common prefix
                additional_values: List[str] = []
                for subfeature in subfeatures:
                    short_name = subfeature.name[skipname:].decode("utf-8")
                    try:
                        value = sensors.get_value(chip, subfeature.number)
                    except Exception:
                        _LOG.warning(
                            f"Unable to read "
                            f"{chip.path.decode('utf-8')}/{subfeature.name.decode('utf-8')} ({chip_name})")
                        value = None
                    if short_name == _SHORT_NAME_INPUT:
                        item_value = self._filter_value(item_type, item_value, value)
                    elif short_name == _SHORT_NAME_AVERAGE:
                        item_average_value = self._filter_value(item_type, item_average_value, value)
                    else:
                        self._add_additional_value(additional_values, short_name, value)

                if item_value is None:
                    item_value = item_average_value
                elif item_average_value is not None:
                    self._add_additional_value(additional_values, _SHORT_NAME_AVERAGE, item_average_value)

                if additional_values:
                    item_name = "{} ({})".format(item_name, ", ".join(additional_values))
                item = MonitoredItem(item_id, item_name, item_value, item_type)
                system_info.hwmon.set_hw_monitored_item(chip_name, item)
        sensors.cleanup()
        return system_info

    @staticmethod
    def _filter_value(feature_type: FeatureType, item: Optional[float], value: Optional[float]) -> Optional[float]:
        if value is None:
            return None
        if feature_type == FeatureType.TEMP:
            item = value if _SENSOR_MIN_TEMP < value < _SENSOR_MAX_TEMP else None
        else:
            item = value
        return item

    @staticmethod
    def _add_additional_value(additional_values: List[str], short_name: str, value: float) -> None:
        formatted_value = "{:.2f}".format(value).rstrip('0').rstrip('.')
        additional_values.append(f"{short_name}: {formatted_value}")


from pywebio.output import *
from pywebio.input import *
from pywebio.session import set_env

set_env(title="Path Finder",auto_scroll_bottom=True)

#dijkstra's algorithm
def solution(graph,src,dest,visited=[],distances={},predecessors={}):
    if src == dest:
        path=[]
        pred=dest
        while pred != None:
            path.append(pred)
            pred=predecessors.get(pred,None)
        readable=path[0]
        for index in range(1,len(path)): readable = path[index]+'--->'+readable
        put_html(' PATH : %s' % (readable))
        put_html('DISTANCE : %s units' % (str(distances[dest])))
        visited.clear()
        distances.clear()
        predecessors.clear()
    else :
        if not visited:
            distances[src]=0

        for neighbor in graph[src] :
            if neighbor not in visited:
                new_distance = distances[src] + graph[src][neighbor]
                if new_distance < distances.get(neighbor,float('inf')):
                    distances[neighbor] = new_distance
                    predecessors[neighbor] = src

        visited.append(src)

        unvisited={}
        for k in graph:
            if k not in visited:
                unvisited[k] = distances.get(k,float('inf'))
        x=min(unvisited, key=unvisited.get)
        solution(graph,x,dest,visited,distances,predecessors)
#building gui
def gui():
    graph = {
                'main gate': {"admin block":100},
                'admin block': {"main gate":100, "bio block":39, "junction a":8, "junction g":7, "junction f":17, "mba college":60},
                'mba college': {"admin block":60},
                'decinial block': {'college ground':14, "junction e":5},
                'church': {'junction d':15, 'library':10, 'junction a':10, 'junction g':10},
                'bio block': {'junction b':27, 'admin block':39, 'service gate':33},
                'library': {'junction b':9, 'junction a':22, 'church':10},
                'auditorium': {'junction g':6},
                'canteen': {'junction c':9},
                'service gate': {'bio block':33},
                'boys hostel': {'junction c':12, 'junction b':13},
                'girls hostel': {'junction c':11},
                'college ground': {'decinial block':14, 'junction f':22},

                'junction a': {'library':22, 'church':10, 'admin block':8},
                'junction b': {'boys hostel':13, 'library':9, 'bio block':27},
                'junction c': {'canteen':9, 'girls hostel':11, 'junction d':19, 'boys hostel':12},
                'junction d': {'junction e':8, 'church':15, 'junction c':19},
                'junction e': {'junction d':8, "decinial block":5, "junction g":27},
                'junction f': {"admin block":17,  "junction g":15, "college ground":22},
                'junction g':{'church':10, 'auditorium':6, 'junction e':27, 'junction f':15, 'admin block':7}
            }

    data=input_group('select a location', [
        select('Source', options=graph.keys(), name='source'),
        select('Destination', options=graph.keys(), name='destination')
    ])

    if data['source'] == data['destination']:
        popup('ERROR', 'Source and destination are same!', size=PopupSize.SMALL)
        check()
        quit()

    put_text('\n\n')
    put_table([
        [data['source'], data['destination']]
    ],header=['SOURCE', 'DESTINATION'])
    put_text('Please wait...')

    put_html("Here is your shortest path! Enjoy")

    solution( graph, data['source'], data['destination'])
    check()

#try again button
def check():
    again=radio('Try again',['Yes', 'No'])
    if again == 'Yes':
        gui()
    else:
        return style(put_text('Have a good day!'),'color:green')

if __name__=='__main__':
    put_html("
SAHRDAYA PATH FINDER
")
    put_image('https://static.wixstatic.com/media/2f31ab_be7a01c97a5c43e3a8e3a08306bd4819~mv2.png/v1/fill/w_653,h_685,al_c,q_90,usm_0.66_1.00_0.01/directedMap.webp').style('width: 75%; max-width: 100%; height: auto; margin-left: auto; display: block; margin-right: auto')

gui()


#dfs 리컬젼에러땜에 다른 솔루션 봤는데 c++은 재귀 되나보더라,,,부럽,,
class Point:
    def __init__(self, x,y, color ):
        self.x = x
        self.y = y
        self.color = color

#p랑 똑같은 color들을 모두 visited 해버리기
def dfs(p, depth):
    global grid, visited
    # if depth>100: return []
    dx=[-1,0,1,0]
    dy=[0,1,0,-1]
    nearlist=[]
    abnormalNearlist = []
    visited[p.x][p.y]=1 #일단 visited 처리

    #grid 좌표 값 안에 있는 것들 중에
    #위,아래,왼,오 색상 같은 것들 -> 그 주변에 색상 같은 애 있나 찾기
    #색상 다른 것 -> nearlist에 (x,y) 추가
    for i in range(4):
        if p.x+dx[i]<0 or p.x+dx[i]+1>len(grid) or p.y+dy[i]<0 or p.y+dy[i]+1>len(grid):
            continue
        if visited[p.x+dx[i]][p.y+dy[i]]==1: continue
        if p.color == grid[p.x+dx[i]][p.y+dy[i]]:
            nList = dfs(Point(p.x+dx[i], p.y+dy[i], p.color), depth+1)
            nearlist += nList
        else:
            nearlist.append( (p.x+dx[i], p.y+dy[i]) )
    #색상 다른 주변 좌표 리스트 리턴
    return list(set(nearlist))

def bfs(initP):
    global grid, visited
    # print('bfs calling: (%d,%d)'%(initP[0], initP[1]))
    normal = 0
    colorCount = 0
    dx=[-1,0,1,0]
    dy=[0,1,0,-1]
    Q=[initP]

    while Q:
        curr = Q.pop(0)
        if visited[curr[0]][curr[1]]==1: continue
        else: visited[curr[0]][curr[1]]=1
        for i in range(4):
            newX = curr[0] + dx[i]
            newY = curr[1] + dy[i]
            if newX>=0 and newX<len(grid) and newY>=0 and newY<len(grid) and visited[newX][newY]==0:
                #범위 내에 있고 한번도 보지 방문하지 않은 좌표 -> 색상 같을 때만 Q에 추가
                if grid[newX][newY] == grid[curr[0]][curr[1]]:
                    Q.append((newX,newY))

    return

N = int(input())
grid = []
visited = [[0]*N for _ in range(N)]
# visited2 = visited.copy()
for _ in range(N):
    grid.append(list(input()))

# normal = bfs((0,0))
normal = 0
for r in range(N):
    for c in range(N):
        if visited[r][c]==0:
            bfs((r,c))
            normal += 1

for r in range(N):
    for c in range(N):
        if grid[r][c]=="G":
            grid[r][c]="R"

visited = [[0]*N for _ in range(N)]
# abnormal = bfs((0,0))
# print('next: abnormal')
abnormal = 0
for r in range(N):
    for c in range(N):
        if visited[r][c]==0:
            bfs((r,c))
            abnormal += 1

print('%d %d'%(normal, abnormal))


# -*- coding: utf-8 -*-
"""
Created on Sun Sep 27 22:43:17 2020

@author: Sam
"""

#impoty librarys
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit as cv
#Import the data from the Text File

#This is inefficiant, i dont care
data10k = np.genfromtxt("ACresonance10kNew.txt",skip_header =3,delimiter=",")

frequency=data10k[:, 0]
rlV_out10k=data10k[:,1]
imV_out10k=data10k[:,2]

data1k = np.genfromtxt("ACresonance1kNew.txt",skip_header =3,delimiter=",")
rlV_out1k=data1k[:,1]
imV_out1k=data1k[:,2]

data100 = np.genfromtxt("ACresonance100New.txt",skip_header =3,delimiter=",")
rlV_out100=data100[:,1]
imV_out100=data100[:,2]

data10 = np.genfromtxt("ACresonance10New.txt",skip_header =3,delimiter=",")
rlV_out10=data10[:,1]
imV_out10=data10[:,2]

data2 = np.genfromtxt("ACresonance2New.txt",skip_header =3,delimiter=",")
rlV_out2=data2[:,1]
imV_out2=data2[:,2]

"""
plt.figure(figsize=(20, 10))
plt.xscale("log")
plt.xlabel("frequency / Hz")
plt.ylabel("Voltage / V")
plt.plot(frequency,rlV_out10k, "g", label = "V_out_real for 10k Ohms for the resistors")
plt.plot(frequency,rlV_out1k, "b", label = "V_out_real for 1k Ohms for the resistors")
plt.plot(frequency,rlV_out100, "pink", label = "V_out_real for 100 Ohms for the resistors")
plt.plot(frequency,rlV_out10, "r", label = "V_out_real for 10 Ohms for the resistors")
plt.plot(frequency,rlV_out2, "black", label = "V_out_real for 2 Ohms for the resistors")
plt.title("AC Resonance graph")
plt.legend()
"""

x = lambda x, y : (x**2 + y**2)**0.5

V_out10k= []
for i in range (len(rlV_out10k)):
    V_out10k.append(x(rlV_out10k[i], imV_out10k[i]))

V_out1k= []
for i in range (len(rlV_out1k)):
    V_out1k.append(x(rlV_out1k[i], imV_out1k[i]))

V_out100= []
for i in range (len(rlV_out100)):
    V_out100.append(x(rlV_out100[i], imV_out100[i]))

V_out10= []
for i in range (len(rlV_out10)):
    V_out10.append(x(rlV_out10[i], imV_out10[i]))

V_out2= []
for i in range (len(rlV_out2)):
    V_out2.append(x(rlV_out2[i], imV_out2[i]))

plt.figure(figsize=(20, 10))
plt.xscale("log")
plt.xlabel("frequency / Hz")
plt.ylabel("Voltage / V")
plt.plot(frequency,V_out10k, "g", label = "V_out for 10k Ohms for the resistors (Magnitude)")
plt.plot(frequency,V_out1k, "b", label = "V_out for 1k Ohms for the resistors (Magnitude)")
plt.plot(frequency,V_out100, "r", label = "V_out for 100 Ohms for the resistors (Magnitude)")
plt.plot(frequency,V_out10, "orange", label = "V_out for 10 Ohms for the resistors (Magnitude)")
plt.plot(frequency,V_out2, "black", label = "V_out for 2 Ohms for the resistors (Magnitude)")
plt.title("AC Resonance graph (Magnitudes)")
plt.legend()

def freqAtHalfAmp (V, f):
    for i in range (len(V)):
        if V[i] > 0.244 and V[i] < 0.256:
            print(f[i])
def resonantFreq (V, f):
    for i in range (len(V)):
        if V[i] > 0.49 and V[i] < 0.51:
            print(f[i])

"""
freqAtHalfAmp(V_out1k, frequency)
freqAtHalfAmp (V_out100, frequency)
freqAtHalfAmp (V_out10, frequency)
freqAtHalfAmp (V_out2, frequency)
"""


class Solution:
    def storeProfit(self, profit):
        print(self.profits, profit)
        store_idx = -1
        min = None
        print(self.profits)
        for i, val in enumerate(self.profits):
            if min is None:
                min = val
                store_idx = i

            if val == 0:
                self.profits[i] = profit
                return
            elif val < min:
                store_idx = i
                min = val

        if store_idx > -1 and profit > self.profits[store_idx]:
            self.profits[store_idx] = profit

    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        self.profits = [0, 0]
        min_val = None
        max_val = None

        for i in prices:
        #    print(i, min_val, max_val, profit)
        # if first, then register it is min_val
            if min_val is None:
                min_val = max_val = i
                continue

        # if greater than the previous store it as max_val, but continue
            if i >= max_val:
                max_val = i
        # if lesser than the previous
            else:
                if max_val > min_val:
        # calculate profit as max_val - min_val
                    profit = max_val - min_val
                    self.storeProfit(profit)

                min_val = i
        # store it as the new min_val
        # initialize max_val
                max_val = i

        if max_val is not None and max_val > min_val:
            profit = max_val - min_val
            self.storeProfit(profit)

        print(self.profits)
        return sum(self.profits)

sol = Solution()
print(sol.maxProfit([7,1,5,3,6,4]))
print(sol.maxProfit([1,2,3,4,5]))
print(sol.maxProfit([7,6,4,3,1]))
print(sol.maxProfit([3,3,5,0,0,3,1,4]))
print(sol.maxProfit([6,1,3,2,4,7]))
print(sol.maxProfit([1,2,4,2,5,7,2,4,9,0]))


r"""\
A :class:`~dvbcss.protocol.ts.SetupData` object represents a setup-data message sent by a client to a server
immediately after opening a CSS-TS protocol connection.

A :class:`ControlTimestamp` object represents a Control Timestamp message sent by the server
to the client.

A :class:`AptEptLpt` object represents an Actual, Earliest and Latest Presentation Timestamp
message that may be sent by a client to the server.

The :class:`Timestamp` objects are used in the above message objects to represent the
relationship between wall clock time and content (timeline) time.

Examples
--------

SetupData examples:

.. code-block:: python

    >>> from dvbcss.protocol.ts import SetupData
    >>> from dvbcss.protocol import OMIT

    >>> s = SetupData(timelineSelector="urn:dvb:css:timeline:pts", ciStem="dvb://1004")
    >>> s.pack()
    '{"timelineSelector": "urn:dvb:css:timeline:pts", "contentIdStem": "dvb://1004"}'

.. code-block:: python

    >>> jsonMessage = \"""\
    ... { "timelineSelector":"urn:dvb:css:timeline:temi:1:1",
    ...   "contentIdStem":""
    ... }
    ... \"""
    >>> SetupData.unpack(jsonMessage)
    SetupData(ciStem="", timelineSelector="urn:dvb:css:timeline:temi:1:1", private=OMIT)

ControlTimestamp examples:

.. code-block:: python

    >>> from dvbcss.protocol.ts import ControlTimestamp, Timestamp

    >>> t = Timestamp(contentTime=12345, wallClockTime=900028432)
    >>> ct = ControlTimestamp(timestamp=t, timelineSpeedMultiplier=1)
    >>> ct.pack()
    '{"timelineSpeedMultiplier": 1.0, "wallClockTime": "900028432", "contentTime": "12345"}'

.. code-block:: python

    >>> jsonMessage = \"""\
    ... { "contentTime" : "1003847",
    ...   "wallClockTime" : "348957623498576",
    ...   "timelineSpeedMultiplier" : 2.0
    ... }
    ... \"""
    >>> c = ControlTimestamp.unpack(jsonMessage)
    >>> c.timestamp.contentTime
    1003847
    >>> c.timestamp.wallClockTime
    348957623498576
    >>> c.timelineSpeedMultiplier
    2.0

Actual, Earliest and Latest Presentation Timestamp examples:

.. code-block:: python

    >>> from dvbcss.protocol.ts import AptEptLpt, Timestamp

    >>> te = Timestamp(contentTime=123465, wallClockTime=float("-inf"))
    >>> tl = Timestamp(contentTime=123465, wallClockTime=float("+inf"))
    >>> ael = AptEptLpt(earliest=te, latest=tl)
    >>> ael.pack()
    '{"earliest": {"wallClockTime": "minusinfinity", "contentTime": "123465"}, "latest": {"wallClockTime": "plusinfinity", "contentTime": "123465"}}'

.. code-block:: python

    >>> jsonMessage = \"""\
    ... { "earliest" : { "contentTime" : "1000", "wallClockTime": "10059237" },
    ...   "latest"   : { "contentTime" : "1000", "wallClockTime": "19284782" },
    ...   "actual"   : { "contentTime" : "1005", "wallClockTime": "10947820" }
    ... }
    ... \"""
    >>> ael=AptEptLpt.unpack(jsonMessage)
    >>> ael.actual.contentTime
    1005
    >>> ael.actual.wallClockTime
    10947820

.. _plus-minus-infinity:

+/- infinity
------------

For certain timestamp messages it is permissible to convey a time value that is either plus or minus infinity.
Use the python :class:`float` to express these values as follows:

.. code-block:: python

    >>> float("+inf")
    inf

    >>> float("-inf")
    -inf

"""

import json
import logging

from dvbcss.protocol.transformers import encodeOneOf, decodeOneOf
from dvbcss.protocol.transformers import Transformer
from dvbcss.protocol import OMIT

class SetupData(object):
    def __init__(self, contentIdStem, timelineSelector, private=OMIT):
        """\
        Object representing a CSS-TS Setup-Data message.

        This carries a content identifier stem and a timeline selector string, and is used, in effect,
        to request the timeline to be synchronised to via the CSS-TS protocol.

        **Initialisation takes the following parameters:**

        :param str contentIdStem: The content identifier stem.
        :param str timelineSelector: The timeline selector
        :param private: Optional private data.
        :type private: :obj:`~dvbcss.protocol.OMIT` or :ref:`private-data`

        The attributes of the object have the same name as the SetupData message properties:

        * :data:`contentIdStem`
        * :data:`timelineSelector`
        * :data:`private`

        Converting to and from JSON representation is performed using the :func:`pack` method and :func:`unpack` class method.
        Properties set to equal :data:`~dvbcss.protocol.OMIT` will be omitted when the message
        is packed to a JSON representation.
        """
        super(SetupData,self).__init__()

        self.contentIdStem = contentIdStem       #: (read/write :class:`str`) The stem (subset starting from the LHS) of a content identifier
        self.timelineSelector = timelineSelector #: (read/write :class:`str`) The timeline selector
        self.private = private                   #: (read/write :obj:`~dvbcss.protocol.OMIT` or :ref:`private-data`) Optional private data.

        self.log = logging.getLogger("dvbcss.protocol.ts.SetupData")

    def pack(self):
        """\
        :returns: string containing JSON representation of this message.
        :throws ValueError: if there are values for properties that are not permitted.
        """
        struct = {}
        struct["contentIdStem"] = str(self.contentIdStem)
        struct["timelineSelector"] = str(self.timelineSelector)
        if self.private is not OMIT:
            struct["private"] = encodeOneOf(self.private,"Not a valid private property.", Transformer.private)
        return json.dumps(struct)

    @classmethod
    def unpack(cls, msg):
        """\
        Convert JSON string representation of this message encoded as a :class:`SetupData` object.

        :throws ValueError: if not possible.
        """
        struct = json.loads(msg)
        opt={}
        if "private" in struct:
            opt["private"] = decodeOneOf(struct["private"],"Not a valid private property.", Transformer.private)
        try:
            return SetupData(contentIdStem = struct["contentIdStem"], timelineSelector = struct["timelineSelector"], **opt)
        except KeyError:
            raise ValueError("Not all fields in SetupData message present as expected")

    def __str__(self):
        return self.__repr__()

    def __repr__(self):
        return 'SetupData(contentIdStem="%s", timelineSelector="%s", private=%s)' % (self.contentIdStem, self.timelineSelector, repr(self.private))

    def copy(self):
        """:returns: a copy of this SetupData object. Note that this does NOT deep copy any private data."""
        return SetupData(self.contentIdStem, self.timelineSelector, self.private)

class Timestamp(object):

    def __init__(self, contentTime, wallClockTime):
        """\
        Object representing a Timestamp part(s) of a :class:`ControlTimestamp` or :class:`AptEptLpt` object.

        **Initialisation takes the following parameters:**

        :param contentTime: The content time (time on timeline) part of a timestamp
        :type contentTime: :obj:`None` or :class:`int`
        :param wallClockTime: The wall clock time part of a timestamp
        :type wallClockTime: :class:`int` or :ref:`plus-minus-infinity` :class:`float` ("+inf") or :class:`float` ("-inf")

        The values for contentTime and wallClockTime are allowed to be arbitrarily large precision integers because they are carried as a string
        in the JSON representation.

        The attributes of the object have the same name as the corresponding message properties:

        * :data:`contentTime`
        * :data:`wallClockTime`

        Converting to and from JSON representation is performed using the :func:`pack` method and :func:`unpack` class method.
        """
        super(Timestamp,self).__init__()
        self.contentTime=contentTime    #: (read/write :obj:`None` or large :class:`int`) The content time part of a timestamp
        self.wallClockTime=wallClockTime #: (read/write large :class:`int` or :class:`float("+inf")` or :class:`float("-inf")` ) The wall clock time part of a timestamp
        self.log = logging.getLogger("dvbcss.protocol.ts.Timestamp")

    def __str__(self):
        return self.__repr__()

    def __repr__(self):
        return 'Timestamp(contentTime=%s, wallClockTime=%s)' % (repr(self.contentTime), repr(self.wallClockTime))

    def copy(self):
        return Timestamp(self.contentTime, self.wallClockTime)

class ControlTimestamp(object):
    def __init__(self, timestamp, timelineSpeedMultiplier):
        """\
        Object representing a CSS-TS Control Timestamp message.

        **Initialisation takes the following parameters:**

        :param Timestamp timestamp: carries the `contentTime` and `wallClockTime` properties of the Control Timestamp
        :param timelineSpeedMultiplier: the timeline speed multiplier
        :type timelineSpeedMultiplier: :class:`float` or :obj:`None`

        The attributes of the object have the following relationship to the message properties:

        * :data:`timestamp`
        * :data:`timelineSpeedMultiplier`

        Converting to and from JSON representation is performed using the :func:`pack` method and :func:`unpack` class method.
        """
        super(ControlTimestamp,self).__init__()
        self.timestamp = timestamp #: (read/write :class:`Timestamp`) :class:`Timestamp` object representing the contentTime and wallClockTime parts of the timestamp)
        self.timelineSpeedMultiplier = timelineSpeedMultiplier #: (read/write :class:`float` or :obj:`None`) Timeline speed. For example: 1 = normal, 0 = pause, -0.5 = half speed reverse. Use `None` only when the Control Timestamp is supposed to indicate that the timeline is unavailable.
        self.log = logging.getLogger("dvbcss.protocol.ts.ControlTimestamp")

    def pack(self):
        """\
        :returns: string containing JSON representation of this message.
        :throws ValueError: if there are values for properties that are not permitted.
        """
        struct = {}

        struct["contentTime"]             = encodeOneOf(self.timestamp.contentTime,   "Not a valid Control Timestamp contentTime.",             Transformer.null, Transformer.intAsString)
        struct["wallClockTime"]           = encodeOneOf(self.timestamp.wallClockTime, "Not a valid Control Timestamp wallClockTime.",           Transformer.intAsString)
        struct["timelineSpeedMultiplier"] = encodeOneOf(self.timelineSpeedMultiplier, "Not a valid Control Timestamp timelineSpeedMultiplier.", Transformer.null, Transformer.float)
        return json.dumps(struct)

    @classmethod
    def unpack(cls, msg):
        """\
        Convert JSON string representation of this message encoded as a :class:`ControlTimestamp` object.

        :throws ValueError: if not possible.
        """
        struct = json.loads(msg)
        contentTime             = decodeOneOf(struct["contentTime"],             "Not a valid Control Timestamp contentTime.",             Transformer.null, Transformer.intAsString)
        wallClockTime           = decodeOneOf(struct["wallClockTime"],           "Not a valid Control Timestamp wallClockTime.",           Transformer.intAsString)
        timelineSpeedMultiplier = decodeOneOf(struct["timelineSpeedMultiplier"], "Not a valid Control Timestamp timelineSpeedMultiplier.", Transformer.null, Transformer.float)

        if (contentTime is None) != (timelineSpeedMultiplier is None):
            raise ValueError("Both contentTime and timelineSpeedMutliplier must be null, or neither must be null. Cannot be only one of them.")

        return ControlTimestamp(Timestamp(contentTime, wallClockTime), timelineSpeedMultiplier)

    def __str__(self):
        return self.__repr__()

    def __repr__(self):
        return 'ControlTimestamp(timestamp=%s, timelineSpeedMultiplier=%s)' % (repr(self.timestamp), repr(self.timelineSpeedMultiplier))

    def copy(self):
        """:returns: a deep copy of this Control Timestamp object"""
        return ControlTimestamp(self.timestamp.copy(), self.timelineSpeedMultiplier)

class AptEptLpt(object):

    def __init__(self, actual=OMIT, earliest=Timestamp(0,float("-inf")), latest=Timestamp(0,float("+inf"))):
        """\
        Object representing a CSS-TS Actual, Earliest and Latest Presentation Timestamp message.

        **Initialisation takes the following parameters:**

        :param actual: Optional timestamp representing the actual presentation timing
        :type actual: :obj:`~dvbcss.protocol.OMIT` or :class:`Timestamp`
        :param earliest: Timestamp representing the earliest possible presentation timing
        :type earliest: :obj:`~dvbcss.protocol.OMIT` or :class:`Timestamp`
        :param latest: Timestamp representing the latest possible presentation timing
        :type latest: :obj:`~dvbcss.protocol.OMIT` or :class:`Timestamp`

        For the *actual presentation timestamp*, the contentTime and wallClockTime must both be non-null integer values.

        For the *earliest presentation timestamp*, the contentTime must be a non-null integer. wallClockTime can be a
        non-null integer or :ref:`plus infinity <plus-minus-infinity>`

        For the *latest presentation timestamp*, the contentTime must be a non-null integer. wallClockTime can be a
        non-null integer or :ref:`minus infinity <plus-minus-infinity>`

        The attributes of the object have the same names as the Actual, Earliest and Latest presentation timestamp message properties:

        * :data:`actual`
        * :data:`earliest`
        * :data:`latest`

        Converting to and from JSON representation is performed using the :func:`pack` method and :func:`unpack` class method.
        If values of properties do not meet the requirements described above, then :func:`pack` will raise :class:`ValueError` exceptions.
        """
        super(AptEptLpt,self).__init__()
        self.actual=actual     #: (read/write :data:`OMIT` or :class:`Timestamp`) Actual presentation timestamp
        self.earliest=earliest #: (read/write :class:`Timestamp`) Earliest presentation timestamp. The wallClockTime property must be an :class:`int` or :class:`float("+inf")`. It must not be :class:`float("-inf")`.
        self.latest=latest     #: (read/write :class:`Timestamp`) Latest presentation timestamp. The wallClockTime property must be an :class:`int` or :class:`float("-inf")`. It must not be :class:`float("+inf")`.
        self.log = logging.getLogger("dvbcss.protocol.ts.AptEptLpt")

    def pack(self):
        """\
        :returns: string containing JSON representation of this message.
        :throws ValueError: if there are values for properties that are not permitted.
        """
        struct={}
        if self.actual != OMIT:
            struct["actual"] = {
                "contentTime"   : encodeOneOf(self.actual.contentTime,   "Not a valid APT contentTime.",   Transformer.intAsString),
                "wallClockTime" : encodeOneOf(self.actual.wallClockTime, "Not a valid APT wallClockTime.", Transformer.intAsString)
            }
        struct["earliest"] = {
            "contentTime"   : encodeOneOf(self.earliest.contentTime,   "Not a valid EPT contentTime.",   Transformer.intAsString),
            "wallClockTime" : encodeOneOf(self.earliest.wallClockTime, "Not a valid EPT wallClockTime.", Transformer.intAsString, Transformer.minusInf)
        }
        struct["latest"] = {
            "contentTime"   : encodeOneOf(self.latest.contentTime,   "Not a valid LPT contentTime.",   Transformer.intAsString),
            "wallClockTime" : encodeOneOf(self.latest.wallClockTime, "Not a valid LPT wallClockTime.", Transformer.intAsString, Transformer.plusInf)
        }
        return json.dumps(struct)

    @classmethod
    def unpack(cls,msg):
        """\
        Convert JSON string representation of this message encoded as a :class:`AptEptLpt` object.

        :throws ValueError: if not possible.
        """
        struct=json.loads(msg)
        opt={}
        try:
            if "actual" in struct:
                opt["actual"] = Timestamp(
                    contentTime   = decodeOneOf(struct["actual"]["contentTime"],   "Not a valid APT contentTime.",   Transformer.intAsString),
                    wallClockTime = decodeOneOf(struct["actual"]["wallClockTime"], "Not a valid APT wallClockTime.", Transformer.intAsString)
                )
            earliest = Timestamp(
                contentTime   = decodeOneOf(struct["earliest"]["contentTime"],   "Not a valid EPT contentTime.",   Transformer.intAsString),
                wallClockTime = decodeOneOf(struct["earliest"]["wallClockTime"], "Not a valid EPT wallClockTime.", Transformer.intAsString, Transformer.minusInf)
            )
            latest = Timestamp(
                contentTime   = decodeOneOf(struct["latest"]["contentTime"],   "Not a valid LPT contentTime.",   Transformer.intAsString),
                wallClockTime = decodeOneOf(struct["latest"]["wallClockTime"], "Not a valid LPT wallClockTime.", Transformer.intAsString, Transformer.plusInf)
            )
            return AptEptLpt(earliest=earliest, latest=latest, **opt)
        except KeyError:
            raise ValueError("Not all fields in SetupData message present as expected")

    def __str__(self):
        return self.__repr__()

    def __repr__(self):
        return 'AptEptLpt(actual=%s, earliest=%s, latest=%s' % (repr(self.actual), repr(self.earliest), repr(self.latest))

    def copy(self):
        """:returns: a deep copy of this AptEptLpt object"""
        actual = self.actual
        earliest = self.earliest
        latest = self.latest
        if actual != OMIT:
            actual = actual.copy()
        if earliest != OMIT:
            earliest = earliest.copy()
        if latest != OMIT:
            latest = latest.copy()
        return AptEptLpt(actual, earliest, latest)

__all__ = [
    "SetupData",
    "Timestamp",
    "ControlTimestamp",
    "AptEptLpt",
]


from PyQt5 import QtWidgets as QtW
from PyQt5 import QtCore as QtC
from PyQt5 import QtGui as QtG
import time

class PrepareButtonView(QtW.QPushButton):
    def __init__(self, name, controller):
        super(QtW.QPushButton, self).__init__(name)
        self.__controller = controller

    def prepare_images(self, nb_images):
        self.__controller.create_tumors(nb_images)

class SelectButtonView(QtW.QPushButton):
    def __init__(self, name, controller):
        super(QtW.QPushButton, self).__init__(name)
        self.__controller = controller

class LearnButtonView(QtW.QPushButton):
    def __init__(self, name, controller):
        super(QtW.QPushButton, self).__init__(name)
        self.__controller = controller

    def learning(self):
        self.__controller.learn()

class ApplicationMenu(QtW.QWidget):
    def __init__(self, parent):
        super().__init__()
        self.__parent = parent
        self.__label = QtW.QLabel('Number of images (minimum 500):')
        self.__nb_images = QtW.QLineEdit()
        self.__nb_images.setMaximumWidth(150)

        self.__prepare = None
        self.__learn = None

        self.__select = None
        self.__path = QtW.QLineEdit(' ')
        self.__path.setReadOnly(True)

        self.__label_SaltNPepper = QtW.QLabel('Salt and Pepper noise')
        self.__checkSaltNPepper = QtW.QCheckBox()
        self.__label_Gaussian = QtW.QLabel('Gaussian noise')
        self.__checkGaussian = QtW.QCheckBox()

        self.bg = QtW.QButtonGroup()
        self.bg.addButton(self.__checkSaltNPepper,1)
        self.bg.addButton(self.__checkGaussian,2)

        #Apply Gaussian noise by default
        self.__checkGaussian.setChecked(True)

    def set_layouts(self):
        self.layoutHv1 = QtW.QHBoxLayout()
        self.layoutHv1.addWidget(self.__label)
        self.layoutHv1.addWidget(self.__nb_images)

        self.layoutHv2 = QtW.QHBoxLayout()
        self.layoutHv2.addWidget(self.__prepare)
        self.layoutHv2.addWidget(self.__learn)

        self.layoutHv3 = QtW.QGridLayout()
        self.layoutHv3.addWidget(self.__label_SaltNPepper, 1, 1)
        self.layoutHv3.addWidget(self.__checkSaltNPepper, 1, 2)
        self.layoutHv3.addWidget(self.__label_Gaussian, 2, 1)
        self.layoutHv3.addWidget(self.__checkGaussian, 2, 2)

        self.layoutHv4 = QtW.QHBoxLayout()
        self.layoutHv4.addWidget(self.__select)
        self.layoutHv4.addWidget(self.__path)

        self.main_layout = QtW.QVBoxLayout()
        self.main_layout.addLayout(self.layoutHv1)
        self.main_layout.addLayout(self.layoutHv2)
        self.main_layout.addLayout(self.layoutHv3)
        self.main_layout.addLayout(self.layoutHv4)

        self.setLayout(self.main_layout)

    def connect(self):
        self.__select.clicked.connect(self.open_file_dialog)
        self.__prepare.clicked.connect(self.prepare)
        self.__learn.clicked.connect(self.__learn.learning)

    def prepare(self):
        if self.__nb_images.text() != '':
            self.__prepare.prepare_images(int(self.__nb_images.text()))

    def open_file_dialog(self):
        options = QtW.QFileDialog.Options()
        filename, _ = QtW.QFileDialog.getOpenFileName(self,'Choose your image', '','All Files (*);;Python Files (*.py)', options=options)

        if filename:
            self.set_path(filename)
            self.__parent.update_image(filename)

    def set_path(self, filename):
        self.__path.setText(filename)

    @property
    def path(self):
        return self.__path

    def initialize_buttons(self, select_button, prepare_button, learn_button):
        self.__select = select_button
        self.__prepare = prepare_button
        self.__learn = learn_button

class ApplicationCanvas(QtW.QWidget):
    def __init__(self, parent):
        super().__init__()
        self.__parent = parent

    def set_canvas(self):
        self.__image = QtG.QPixmap()
        self.setStyleSheet('background-color : black;')
        self.__label = QtW.QLabel()
        self.__label.setMinimumWidth(400)
        self.__label.setMaximumHeight(700)
        self.__label.setPixmap(self.__image)

        self.layout = QtW.QGridLayout()
        self.layout.addWidget(self.__label,1,1)
        self.setLayout(self.layout)

    def update_image(self,file_path):
        self.__image.load(file_path)
        self.__label.setPixmap(self.__image)

class MainWindow(QtW.QWidget):
    def __init__(self, width = 1000, height = 800):
        self.__application = QtW.QApplication([])
        super().__init__()
        self.title = "Tumor recognition"
        self.__width = width
        self.__height = height
        self.__menu = ApplicationMenu(self)
        self.__canvas = ApplicationCanvas(self)

    def initUI(self):

        self.setWindowTitle(self.title)
        self.setGeometry(0, 0, self.__width, self.__height)
        self.__layout = QtW.QGridLayout()
        self.__layout.addWidget(self.__menu, 1, 1, 1, 1)
        self.__layout.addWidget(self.__canvas, 1, 2, 1, 4)
        self.__menu.set_layouts()
        self.__menu.connect()
        self.__canvas.set_canvas()
        self.setLayout(self.__layout)
        self.show()
        self.__application.exec_()

    def update_image(self, image_path):
        self.__canvas.update_image(image_path)

    def menu(self):
        return self.__menu

    def selected_noise_Strategy(self):
        return self.__menu.bg.checkedId()


import open3d as o3d
from PIL import Image
import numpy as np
import os
import cv2
import pandas
import copy

def readfile():
    X = pandas.read_csv('./3dx.csv', header = 0, dtype=np.float64)
    track3d = X.to_numpy()

    Col = pandas.read_csv('./color.csv', header = 0, dtype=np.float64)
    colors = Col.to_numpy() / 255.0

    P = pandas.read_csv('./pose.csv', header = 0, dtype=np.float64)
    Pose = P.to_numpy()
    R =[]
    C = []
    for row in Pose:
        R.append(row[:9].reshape(3,3))
        C.append(row[9:])
    R = np.asarray(np.stack(R))
    C = np.asarray(np.stack(C))

    return track3d, R, C, colors

def ShowPC(track3d, R, C, colors):
    All = []

    all_mesh = []
    for i in range(len(C)):
        all_mesh.append(o3d.geometry.TriangleMesh.create_coordinate_frame(size=1).rotate(R[i], C[i]))
        all_mesh[i].scale(1, center=all_mesh[i].get_center())
    o3d.io.write_triangle_mesh("./cam_scipy.ply", all_mesh[0])
    All = all_mesh

    maska = np.sum(track3d, axis=1) != -3
    maskb = np.logical_and( np.logical_and(abs(track3d[:,0]) < 30 ,  abs(track3d[:,1]) < 30), track3d[:,2] <30)
    mask = np.logical_and(maska, maskb)
    X = track3d[mask]

    pcd = o3d.geometry.PointCloud()
    pcd.points = o3d.utility.Vector3dVector(X)
    pcd.colors = o3d.utility.Vector3dVector(colors[mask])
    All.append(pcd)

    o3d.visualization.draw_geometries(All)
    o3d.io.write_point_cloud("./pc_scipy.pcd", pcd)

def main():
    K = np.asarray([
    [350, 0, 480],
    [0, 350, 270],
    [0, 0, 1] ])
    track3d, R, C, colors = readfile()

    ShowPC(track3d, R, C, colors)

if __name__ == '__main__':
    main()


from random import SystemRandom
from typing import TYPE_CHECKING, Optional, Tuple

import sydent.util.tokenutils
from sydent.util import time_msec
from sydent.validators import (
    THREEPID_SESSION_VALID_LIFETIME_MS,
    IncorrectClientSecretException,
    InvalidSessionIdException,
    SessionExpiredException,
    SessionNotValidatedException,
    TokenInfo,
    ValidationSession,
)

if TYPE_CHECKING:
    from sydent.sydent import Sydent

class ThreePidValSessionStore:
    def __init__(self, syd: "Sydent") -> None:
        self.sydent = syd
        self.random = SystemRandom()

    def getOrCreateTokenSession(
        self, medium: str, address: str, clientSecret: str
    ) -> Tuple[ValidationSession, TokenInfo]:
        """
        Retrieves the validation session for a given medium, address and client secret,
        or creates one if none was found.

        :param medium: The medium to use when looking up or creating the session.
        :param address: The address to use when looking up or creating the session.
        :param clientSecret: The client secret to use when looking up or creating the
            session.

        :return: The session that was retrieved or created.
        """
        cur = self.sydent.db.cursor()

        cur.execute(
            "select s.id, s.medium, s.address, s.clientSecret, s.validated, s.mtime, "
            "t.token, t.sendAttemptNumber from threepid_validation_sessions s,threepid_token_auths t "
            "where s.medium = ? and s.address = ? and s.clientSecret = ? and t.validationSession = s.id",
            (medium, address, clientSecret),
        )
        row: Optional[
            Tuple[int, str, str, str, Optional[int], int, str, int]
        ] = cur.fetchone()

        if row:
            session = ValidationSession(
                row[0], row[1], row[2], row[3], bool(row[4]), row[5]
            )
            token_info = TokenInfo(row[6], row[7])
            return session, token_info

        sid = self.addValSession(
            medium, address, clientSecret, time_msec(), commit=False
        )

        tokenString = sydent.util.tokenutils.generateTokenForMedium(medium)

        cur.execute(
            "insert into threepid_token_auths (validationSession, token, sendAttemptNumber) values (?, ?, ?)",
            (sid, tokenString, -1),
        )
        self.sydent.db.commit()

        session = ValidationSession(
            sid,
            medium,
            address,
            clientSecret,
            False,
            time_msec(),
        )
        token_info = TokenInfo(tokenString, -1)
        return session, token_info

    def addValSession(
        self,
        medium: str,
        address: str,
        clientSecret: str,
        mtime: int,
        commit: bool = True,
    ) -> int:
        """
        Creates a validation session with the given parameters.

        :param medium: The medium to create the session for.
        :param address: The address to create the session for.
        :param clientSecret: The client secret to use when looking up or creating the
            session.
        :param mtime: The current time in milliseconds.
        :param commit: Whether to commit the transaction after executing the insert
            statement.

        :return: The ID of the created session.
        """
        cur = self.sydent.db.cursor()

        # Let's make up a random sid rather than using sequential ones. This
        # should be safe enough given we reap old sessions.
        sid = self.random.randint(0, 2 ** 31)

        cur.execute(
            "insert into threepid_validation_sessions ('id', 'medium', 'address', 'clientSecret', 'mtime')"
            + " values (?, ?, ?, ?, ?)",
            (sid, medium, address, clientSecret, mtime),
        )
        if commit:
            self.sydent.db.commit()
        return sid

    def setSendAttemptNumber(self, sid: int, attemptNo: int) -> None:
        """
        Updates the send attempt number for the session with the given ID.

        :param sid: The ID of the session to update
        :param attemptNo: The send attempt number to update the session with.
        """
        cur = self.sydent.db.cursor()

        cur.execute(
            "update threepid_token_auths set sendAttemptNumber = ? where id = ?",
            (attemptNo, sid),
        )
        self.sydent.db.commit()

    def setValidated(self, sid: int, validated: bool) -> None:
        """
        Updates a session to set the validated flag to the given value.

        :param sid: The ID of the session to update.
        :param validated: The value to set the validated flag.
        """
        cur = self.sydent.db.cursor()

        cur.execute(
            "update threepid_validation_sessions set validated = ? where id = ?",
            (validated, sid),
        )
        self.sydent.db.commit()

    def setMtime(self, sid: int, mtime: int) -> None:
        """
        Set the time of the last send attempt for the session with the given ID

        :param sid: The ID of the session to update.
        :param mtime: The time of the last send attempt for that session.
        """
        cur = self.sydent.db.cursor()

        cur.execute(
            "update threepid_validation_sessions set mtime = ? where id = ?",
            (mtime, sid),
        )
        self.sydent.db.commit()

    def getSessionById(self, sid: int) -> Optional[ValidationSession]:
        """
        Retrieves the session matching the given sid.

        :param sid: The ID of the session to retrieve.

        :return: The retrieved session, or None if no session could be found with that
            sid.
        """
        cur = self.sydent.db.cursor()

        cur.execute(
            "select id, medium, address, clientSecret, validated, mtime from "
            + "threepid_validation_sessions where id = ?",
            (sid,),
        )
        row: Optional[Tuple[int, str, str, str, Optional[int], int]] = cur.fetchone()

        if not row:
            return None

        return ValidationSession(row[0], row[1], row[2], row[3], bool(row[4]), row[5])

    def getTokenSessionById(
        self, sid: int
    ) -> Optional[Tuple[ValidationSession, TokenInfo]]:
        """
        Retrieves a validation session using the session's ID.

        :param sid: The ID of the session to retrieve.

        :return: The validation session, or None if no session was found with that ID.
        """
        cur = self.sydent.db.cursor()

        cur.execute(
            "select s.id, s.medium, s.address, s.clientSecret, s.validated, s.mtime, "
            "t.token, t.sendAttemptNumber from threepid_validation_sessions s,threepid_token_auths t "
            "where s.id = ? and t.validationSession = s.id",
            (sid,),
        )
        row: Optional[Tuple[int, str, str, str, Optional[int], int, str, int]]
        row = cur.fetchone()

        if row:
            s = ValidationSession(row[0], row[1], row[2], row[3], bool(row[4]), row[5])
            t = TokenInfo(row[6], row[7])
            return s, t

        return None

    def getValidatedSession(self, sid: int, client_secret: str) -> ValidationSession:
        """
        Retrieve a validated and still-valid session whose client secret matches the
        one passed in.

        :param sid: The ID of the session to retrieve.
        :param client_secret: A client secret to check against the one retrieved from
            the database.

        :return: The retrieved session.

        :raise InvalidSessionIdException: No session could be found with this ID.
        :raise IncorrectClientSecretException: The session's client secret doesn't
            match the one passed in.
        :raise SessionExpiredException: The session exists but has expired.
        :raise SessionNotValidatedException: The session exists but hasn't been
            validated yet.
        """
        s = self.getSessionById(sid)

        if not s:
            raise InvalidSessionIdException()

        if not s.client_secret == client_secret:
            raise IncorrectClientSecretException()

        if s.mtime + THREEPID_SESSION_VALID_LIFETIME_MS < time_msec():
            raise SessionExpiredException()

        if not s.validated:
            raise SessionNotValidatedException()

        return s

    def deleteOldSessions(self) -> None:
        """Delete old threepid validation sessions that are long expired."""

        cur = self.sydent.db.cursor()

        delete_before_ts = time_msec() - 5 * THREEPID_SESSION_VALID_LIFETIME_MS

        sql = """
            DELETE FROM threepid_validation_sessions
            WHERE mtime < ?
        """
        cur.execute(sql, (delete_before_ts,))

        sql = """
            DELETE FROM threepid_token_auths
            WHERE validationSession NOT IN (
                SELECT id FROM threepid_validation_sessions
            )
        """
        cur.execute(sql)

        self.sydent.db.commit()


import csv
import numpy as np
import os

# This class is specific to process the normlized saliency data processing.
# All the fucntions related to normalized saliency mappin is included here
class ProcNorSalMaps:
    mulVideo = []
    limitOfLargestElements = 40

    def __init__(self, normSalList):
        self.normSaLlist = normSalList

        return

    # This function returns the saliency score from the files for each vidoe.
    #@
    def readData(self):
        filePath = "E:/Dataset/SaliencyScore"

        for i in range(len(self.normSaLlist)):  # len(self.normSaLlist)
            tempFilePathFile = filePath + "/" + self.normSaLlist[i]

            singleVideoMulUser = []
            for userNum in range(50):
                num = '{:02d}'.format(userNum)
                tempFilePathFileUser = tempFilePathFile + "/" + "userNum" + str(num) + ".csv"
                singleVideoSinglUserMulFramesets = []
                with open(tempFilePathFileUser, 'rt')as f:
                    data = csv.reader(f)
                    rowCount = 0
                    framSets = []
                    isFovTile = []
                    normalizeScore = []
                    for row in data:
                        isFovTile.append(row[0])
                        normalizeScore.append(row[2])
                        if rowCount % 200 == 199:
                            framSets.append([isFovTile.copy(), normalizeScore.copy()])
                            isFovTile.clear()
                            normalizeScore.clear()
                        rowCount += 1
                singleVideoMulUser.append(framSets.copy())

            self.mulVideo.append(singleVideoMulUser.copy())

        return

    # This function process the read data (normalized saliency map for 500ms time (15 frames)) with relevant to the
    # given parameter
    # @isRelative : Specify whether to consider relative or absolute percentage saliency on tiles
    # If relative - get the relative percentage saliency of tiles considering the first 40 tiles containing the highest
    # saliency and how many FoV and OoV tiles overlap on those tiles
    # if absolute = get the absolute saliency on the FoV and OoV tiles considering the normalized saliency of those areas
    # separatley
    def getPercentageSaliencyOnTiles(self, isRelative):

        mulVideoData = []
        for videoNum in range(len(self.mulVideo)):  # len(self.mulVideo)
            print("Video Num: ", videoNum)
            singleVideoData = []
            for userNum in range(len(self.mulVideo[videoNum])):  # len(self.mulVideo[videoNum])
                print("                 USer Num: ", userNum)
                singleVideoSingleUserData = []
                for frameSet in self.mulVideo[videoNum][userNum]:  # len(self.mulVideo[videoNum][userNum])

                    isInFoV = frameSet[0]
                    normSalVal = frameSet[1]

                    npInFoV = np.asarray(isInFoV)
                    npInFoV = npInFoV.astype(np.int)
                    npNormSalVal = np.asarray(normSalVal)
                    npNormSalVal = npNormSalVal.astype(np.float)
                    # if relative percentage of saliency requested

                    if isRelative:
                        largest40Elements = np.argpartition(npNormSalVal, -self.limitOfLargestElements)[
                                            -self.limitOfLargestElements:]
                        # for ind in largest40Elements:
                        #     print(npNormSalVal[ind])
                        # npNormSalVal.sort()

                        numOfFoVTilesInSal = 0
                        numofOoVTilesInSal = 0

                        for ind in largest40Elements:
                            if int(isInFoV[ind]) == 1:
                                numOfFoVTilesInSal += 1
                            else:
                                numofOoVTilesInSal += 1

                        percFoVTilesRelative2LargestSalValues = numOfFoVTilesInSal * 100 / self.limitOfLargestElements
                        percOoVTilesRelative2LargestSalValues = numofOoVTilesInSal * 100 / self.limitOfLargestElements

                        totalFoVTiles = sum((npInFoV) > 0)

                        percFoVTilesRelative2TotFoVTiles = numOfFoVTilesInSal * 100 / totalFoVTiles
                        percOoVTilesRelative2TotOoVTiles = numofOoVTilesInSal * 100 / (200 - totalFoVTiles)

                        singleFramestData = [percFoVTilesRelative2LargestSalValues,
                                             percOoVTilesRelative2LargestSalValues, percFoVTilesRelative2TotFoVTiles,
                                             percOoVTilesRelative2TotOoVTiles]

                    # if the absolute saliency is requested
                    else:
                        indFoVTiles = np.where(npInFoV == 1)
                        indOoVTiles = np.where(npInFoV == 0)

                        # get the sum of normalized saliency value in a given region FoV or OoV
                        x = npNormSalVal[indFoVTiles]
                        totFoVSaliency = sum(npNormSalVal[indFoVTiles[0]])
                        totOoVSaliency = sum(npNormSalVal[indOoVTiles[0]])

                        # get the percentage value of absolute normalized saliecny for FoV or OoV.
                        # formula = (sum of normalized saliency in the FoV/OoV region)*100
                        #           -------------------------------------------------------
                        #           (Maximum normalized saliency that a FoV/OoV region can have)
                        #           denominator is equal to the number of FoV/OoV tiles in the frame
                        lenF = len(indFoVTiles[0])
                        percentageSaliencyFoV = totFoVSaliency * 100 / len(indFoVTiles[0])
                        percentageSaliencyOoV = totOoVSaliency * 100 / len(indOoVTiles[0])

                        singleFramestData = [percentageSaliencyFoV, percentageSaliencyOoV]

                    singleVideoSingleUserData.append(singleFramestData)
                singleVideoData.append(singleVideoSingleUserData)
            mulVideoData.append(singleVideoData)

        self.writePercentageSaliency(mulVideoData, isRelative)

        return

    def writePercentageSaliency(self, mulVideoData, isRelative):

        for videoNum in range(len(self.normSaLlist)):
            filePath = "E:\Dataset\PercentageSaliency" + "\\" + self.normSaLlist[videoNum] + "_percentageSaliency"
            if isRelative:
                filePath = filePath + "_Reltive"
            else:
                filePath = filePath + "_Absolute"
            if not os.path.exists(filePath):
                os.makedirs(filePath)

            singleVideo = mulVideoData[videoNum]

            for userNum in range(len(singleVideo)):
                num = '{:02d}'.format(userNum)
                userFilePath = filePath + "\\" + "userNum" + str(num) + ".csv"
                singelUser = singleVideo[userNum]
                with open(userFilePath, 'w', newline='') as writeFile:
                    writer = csv.writer(writeFile)
                    # print(len(oneVideoSaliencyScore[userNum]))
                    if isRelative:
                        writer.writerow(['% FoV tiles/TotTiles in HighSal', '% OoV tiles/TotTiles in HighSal',
                                     '% FoV tiles/TotFovTiles', '% OoV tiles/TotOovTiles'])
                    else:
                        writer.writerow(['percentageSaliencyFoV', 'percentageSaliencyOoV'])
                    for i in range(len(singelUser)):
                        # print(len(oneVideoSaliencyScore[userNum][i]))
                        # for j in range(len(oneVideoSaliencyScore[userNum][i])):
                        singleFrameSetData = singelUser[i]
                        tempList = [str(item) for item in singleFrameSetData]
                        writer.writerow(tempList)

                writeFile.close()

        return


import os
import argparse
import sys

"""ap = argparse.ArgumentParser()
ap.add_argument('-t', '--target', required=True,
                help = 'Target Path (Path where files to be renamed are in)')
args = ap.parse_args()"""

#TARGET_PATH=args.target+'/'
TARGET_PATH="/media/ronit/DATA21/Programming/License_Plate_Detection/data/Google_Search2"
DEST_PATH="/media/ronit/DATA21/Programming/License_Plate_Detection/data/Google_Search2"

if(DEST_PATH==TARGET_PATH):
	count=1
else:
	count=len(os.listdir(DEST_PATH))+1

files=os.listdir(TARGET_PATH)
for f in files:
	f2=f.split('.')
	#print(f,f2)
	#sys.stdin.read(2)

	if(f2[-1]=='jpg' or f2[-1]=='jpeg' or f2[-1]=='png'):
		print(f,f2)
		f3="i"+str(count)+"."+f2[-1]
		count=count+1
		os.rename(TARGET_PATH+'/'+f,TARGET_PATH+'/'+f3)
	else:
		os.remove(TARGET_PATH+'/'+f)


"""
在一个 m*n 的棋盘的每一格都放有一个礼物，每个礼物都有一定的价值（价值大于 0）。你可以从棋盘的左上角开始拿格子里的礼物，并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值，请计算你最多能拿到多少价值的礼物？

示例 1:

输入:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物

提示：

0 < grid.length <= 200
0 < grid[0].length <= 200

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
"""

class Solution:
    def maxValue(self, grid: List[List[int]]) -> int:

        dp = [[0] * len(grid[0]) for i in range(len(grid))]

        cum = 0
        for i, num in enumerate(grid[0]):
            cum += num
            dp[0][i] = cum

        cum = 0
        for i, num in enumerate([grid[i][0] for i in range(len(grid))]):
            cum += num
            dp[i][0] = cum

        for i in range(1,len(grid)):
            for j in range(1,len(grid[0])):
                dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + grid[i][j]

        return dp[-1][-1]