import numpy as np                                # For matrix operations and numerical processing
import pandas as pd                               # For munging tabular data
import sklearn as sk                              # For access to a variety of machine learning models
import matplotlib.pyplot as plt                   # For charts and visualizations
from IPython.display import Image                 # For displaying images in the notebook
from IPython.display import display               # For displaying outputs in the notebook
from sklearn.datasets import dump_svmlight_file   # For outputting data to libsvm format for xgboost
from time import gmtime, strftime                 # For labeling SageMaker models, endpoints, etc.

from sklearn.model_selection import train_test_split
from sklearn import datasets
from sklearn import svm
from datetime import datetime
import datetime as dt
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from time import gmtime, strftime
from sklearn.externals.six import StringIO
from IPython.display import Image
from sklearn.tree import export_graphviz
import time
from Preprocessing import get_category
import seaborn as sn

from TestMQTT import setup
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import logging
import time
import argparse
import json
from math import sqrt

topic = 'project/lutron'

#import anaconda_project
#!pip install pydotplus

df = pd.read_csv('/home/ec2-user/SageMaker/IoTAnalytics/Clean_Data.csv')
Output_lookup = pd.read_csv('/home/ec2-user/SageMaker/lookup Tables - Output.csv')

# Function for random forest to predict room category

def random_forest_cat(X_train,X_test,y_train,y_test):
    random_forest = RandomForestClassifier(n_estimators=50, oob_score=True)
    random_forest.fit(X_train, y_train)

    Y_train_pred = random_forest.predict(X_train)
    Y_test_pred = random_forest.predict(X_test)

    random_forest.score(X_train, y_train)
    acc_random_forest = round(random_forest.score(X_train, y_train) * 100, 2)

    predicted = random_forest.predict(X_test)
    accuracy = accuracy_score(y_test, predicted)
    #print(f'Out-of-bag score estimate: {random_forest.oob_score_:.3}')
    #print(f'Mean accuracy score: {accuracy:.3}')
    #print(accuracy)

    report = classification_report(y_test, predicted)
    #print(report)
    matrix = confusion_matrix(y_test, predicted)
    #print(matrix)
    #sn.heatmap(matrix)
    return random_forest

def lutron_input(room,brightness):

    brightness_prediction = str(round(brightness))
    room_prediction = int(room)
    Output_Room = Output_lookup[(Output_lookup.RoomLabel ==room_prediction)]
    brightness_prediction= brightness_prediction.replace('.0', '')
    Output_Room['Output_w_Brightness'] = Output_Room['DL Zone Input'].astype(str)+ brightness_prediction
    string_list = Output_Room['Output_w_Brightness'].values.tolist()
    Output_string = '\r'.join(string_list)
    print(Output_string)
    return Output_string

# Predict Room

#predict Room top features
X1 = df.iloc[:,[9,10,13,15,17,18,20]]
Y1 = df.iloc[:,19]

#Run simulation
X1_train, X1_test, y1_train, y1_test= train_test_split(X1, Y1, test_size=0.3, shuffle=True)
room_forest = random_forest_cat(X1_train,X1_test,y1_train,y1_test)

#Predict Brightness

X = df.iloc[:,[9,10,13,15,17,18,19,20]]
Y = df.iloc[:,5]

# based on feature extraction tidy up data
X_train, X_test, y_train, y_test= train_test_split(X, Y, test_size=0.3, shuffle=True)
brightness_forest = random_forest_cat(X_train,X_test,y_train,y_test)

# Real Time DataFrame

sunrise = pd.read_csv('/home/ec2-user/SageMaker/Sunrise - Sheet1.csv')
sunrise['time0'] = pd.to_datetime(sunrise['time0'],format ='%m/%d/%Y')

# Defining Day _Label
Day_Label = {'Category': 'Day_Label','Morning': 0,'Day': 1,'Evening': 2, 'Night':3}
Day_Label = {'Category' : pd.Series(['Morning', 'Day', 'Evening','Night'], index=[0, 1, 2, 3]),'Day_Label' : pd.Series([0, 1, 2,3], index=[0, 1, 2, 3])}
Day_Label_df = pd.DataFrame(Day_Label)

MyMQTTClient = setup()
MyMQTTClient
room_forest = random_forest_cat(X1_train,X1_test,y1_train,y1_test)
brightness_forest = random_forest_cat(X_train,X_test,y_train,y_test)

Floor = 0
loopcount =0
while loopcount <10:
    # Define now
    now_time= datetime.now()

    # Get Num_Week and Weekday
    Num_Week =now_time.isocalendar()[1]
    weekday = now_time.weekday()

    # Get string time
    string_times = strftime("%Y-%m-%d %H:%M:%S", gmtime())
    date, times =string_times.split(' ')
    hour,minute,second = times.split(':')

    # Get Total minutes since Midnight
    minutes = (int(hour))*60 + int(minute)

    # Get Temp & Cloud Amount !!!!!!!!!

    # Define input data in DataFrame
    data = {'DateTime':string_times,'Num_Week' : Num_Week, 'weekday' : weekday,'Minute': minutes,'Floor': Floor,'temp':20,'cloud_amt':5 }
    predict_df = pd.DataFrame(data,index=[1])

    # Format DateTime to get sunrise & sunset times
    predict_df = predict_df.join(predict_df['DateTime'].str.split(' ', expand=True).add_prefix('time'))
    predict_df['time0'] = pd.to_datetime(predict_df['time0'],format ='%Y-%m-%d')

    predict_df = predict_df.merge(sunrise,on='time0',how="left")

    # Get Category of Day/Night/Morning/Evning
    predict_df = predict_df.join(predict_df['Sunrise'].str.split(':', expand=True).add_prefix('Sunrise'))
    predict_df = predict_df.join(predict_df['Sunset'].str.split(':', expand=True).add_prefix('Sunset'))

    predict_df['Sunrise0'] = predict_df['Sunrise0'].apply(pd.to_numeric, errors='coerce')
    predict_df['Sunrise1'] = predict_df['Sunrise1'].apply(pd.to_numeric, errors='coerce')
    predict_df['Sunset0'] = predict_df['Sunset0'].apply(pd.to_numeric, errors='coerce')
    predict_df['Sunset1'] = predict_df['Sunset0'].apply(pd.to_numeric, errors='coerce')

    predict_df['Sunrise_Sec'] = predict_df['Sunrise0']*60 + predict_df['Sunrise1']
    predict_df['Sunset_Sec'] = predict_df['Sunset0']*60 + predict_df['Sunset1']

    predict_df = predict_df.drop(['Sunrise','Sunset','Sunrise0','Sunrise1','Sunset0','Sunset1','Sunrise2','Sunset2'],axis = 1)

    predict_df['Category'] = predict_df.apply(get_category, axis = 1)
    predict_df = predict_df.merge(Day_Label_df,on='Category',how="left")
    predict_df = predict_df.drop(['Category','Sunrise_Sec','Sunset_Sec','time0','time1','DateTime'], axis=1)
    print(predict_df)

    real_time_room = room_forest.predict(predict_df)
    print (real_time_room)
    predict_df['RoomLabel'] = real_time_room
    real_time_brightness = brightness_forest.predict(predict_df)
    print (real_time_brightness)

    DL_string = lutron_input(real_time_room[0],real_time_brightness[0])
    my_list = DL_string.split('\r')
    message = {}

    for x in my_list:
        if (len(x)>0):
            message['message'] = x
            message['sequence'] = loopcount
            message['timestamp'] = string_times
            message['unique_key'] = string_times + str(loopcount)
            message['Source'] = "Model"

            messageJson = json.dumps(message)
            MyMQTTClient.publish(topic, messageJson, 1)
            print('Published topic %s: %s\n' % (topic, messageJson))
            loopcount=loopcount+1
    if Floor == 0:
        print(1)
        Floor =1
    elif Floor ==1:
        Floor = 0
    time.sleep(60)


import torch
import torch_tensorrt
import time
import numpy as np
import torch.backends.cudnn as cudnn
import PIL.Image as pil
from torchvision import transforms
import argparse

def parse_args():
    parser = argparse.ArgumentParser(
        description='Simple testing funtion for Monodepthv2 models.')

    parser.add_argument('--image_dir', type=str,
                        help='path to folder images, for inference mode')
    parser.add_argument('--output_dir', type=str,
                        help='path to save images, for inference mode')
    parser.add_argument('--load_weights_path', type=str,
                        help='Path contain tensorrt ckpts', required=True)
    parser.add_argument('--benchmark',
                        help='Benchmark mode',
                        action="store_true")

    return parser.parse_args()

def save_depth(depth, name, out_dir):
    depth = depth.reshape((1, 1, 256, 512))
    depth = 1 / (depth + 1e-9)
    scaled_depth = (depth - np.min(depth)) / (np.max(depth) - np.min(depth))
    scaled_depth = np.squeeze(scaled_depth)
    scaled_depth = np.repeat(scaled_depth[None, :, :], 3, 0)
    scaled_depth = np.transpose(scaled_depth, (1, 2, 0))
    scaled_depth = np.clip(scaled_depth * 255, 0, 255).astype(np.uint8)
    scaled_depth = pil.fromarray(scaled_depth)
    scaled_depth.save(os.path.join(out_dir, "{:010d}.jpg".format(name)))

def load_input(image_path):
    input_image = pil.open(image_path).convert('RGB')
    input_image = transforms.ToTensor()(input_image).unsqueeze(0)
    input_image = input_image
    return input_image

cudnn.benchmark = True

def benchmark(model, use_cuda = True, input_shape=(1024, 3, 512, 512), dtype='fp32', nwarmup=50, nruns=1000):
    input_data = torch.randn(input_shape)
    if use_cuda:
        input_data = input_data.to("cuda")
    if dtype=='fp16':
        input_data = input_data.half()

    print("Warm up ...")
    with torch.no_grad():
        for _ in range(nwarmup):
            features = model(input_data)
    torch.cuda.synchronize()
    print("Start timing ...")
    timings = []
    with torch.no_grad():
        for i in range(1, nruns+1):
            start_time = time.time()
            pred_loc  = model(input_data)
            torch.cuda.synchronize()
            end_time = time.time()
            timings.append(end_time - start_time)
            if i%10==0:
                print('Iteration %d/%d, avg batch time %.2f ms'%(i, nruns, np.mean(timings)*1000))

    print("Input shape:", input_data.size())
    print('Average throughput: %.2f images/second'%(input_shape[0]/np.mean(timings)))

if __name__ == "__main__":
    args = parse_args()
    tensorrt_path = args.load_weights_path
    trt_model = torch.jit.load(tensorrt_path)

    if args.benchmark:
        benchmark(trt_model, use_cuda = True, input_shape=(1, 3, 256, 512), nruns=100, dtype="fp32")
    else:
        with open("splits/day_val_451.txt", "r") as file:
            img_names = file.readlines()
        img_names = [int(img_name) for img_name in img_names]

        for name in img_names:
            input = load_input(os.path.join(args.image_dir, "{:010d}.png".format(name)))
            output = trt_model(input.cuda())
            output = output.detach().cpu().numpy()
            save_depth(output, name)


# Find all triplets with zero sum
# Given an array of distinct elements.
# The task is to find triplets in array whose sum is zero.

import collections

def Combinations_recur(lst,cnt,tmp,output_lst):

    if len(tmp)==3:
        val_sum=sum(tmp)
        if val_sum==0:
            if sorted(tmp) not in output_lst:
                output_lst.append(sorted(tmp.copy()))

    for i in range(0,len(lst)):
        if cnt[i]==0:
            continue
        tmp.append(lst[i])
        cnt[i]=cnt[i]-1
        Combinations_recur(lst, cnt, tmp, output_lst)
        cnt[i]=cnt[i]+1
        tmp.pop()

def TripletSumZero1(ary):

    dict=collections.Counter(ary)
    lst=[]
    cnt=[]
    for key,val in dict.items():
        lst.append(key)
        cnt.append(val)
    tmp=[]
    output_lst=[]
    Combinations_recur(lst,cnt,tmp,output_lst)
    return output_lst

def TripletSumZero2(ary):

    ary.sort()
    output_lst=[]
    for i in range(0,len(ary)):
        left=i+1
        right=len(ary)-1
        while left < right:
            if ary[left]+ary[right]+ary[i]==0:
                tup=(ary[i],ary[left],ary[right])
                if tup not in output_lst:
                    output_lst.append(tup)
                left=left+1
                right=right-1
            elif ary[left]+ary[right]+ary[i]<0:
                left=left+1
            else:
                right=right-1
    return output_lst

def main():

    ary=[0, -1, 2, -3, 1]
    print(TripletSumZero1(ary))
    print(TripletSumZero2(ary))

    ary = [1, -2, 1, 0, 5]
    print(TripletSumZero1(ary))
    print(TripletSumZero2(ary))

    ary=[-1, 0, 1, 2, -1, -4]
    print(TripletSumZero1(ary))
    print(TripletSumZero2(ary))

if __name__=='__main__':
    main()


import requests
import json

def send_post_request_to_insert_multiple_working_hero(base_url, uri, list_person):
    url = base_url + uri
    payload = json.dumps(list_person, default=vars)
    headers = {
        'Content-Type': 'application/json'
    }
    print(type(payload))
    response = requests.request("POST", url, headers=headers, data=payload)
    return response


# -*- coding: utf-8 -*-
# @Author: Arius
# @Email: arius@qq.com
# @Date:   2019-01-23 11:27:29

import signal
from functools import partial
from tornado import (
    web,
    ioloop,
    httpserver,
)
import os

from shutdown import sig_handler
from route import urls

settings = {
    'static_path': os.path.join(os.path.dirname(__file__), 'cache'),
    'debug': True,
}

class TornadoMain(web.Application):
    def __init__(self):
        web.Application.__init__(self, urls, **settings)

def main():
    app = TornadoMain()
    server = httpserver.HTTPServer(app)
    server.listen(3154)
    # signal.signal(signal.SIGTERM, partial(sig_handler, server))
    # signal.signal(signal.SIGINT, partial(sig_handler, server))
    ioloop.IOLoop.instance().start()

if __name__ == '__main__':
    main()


from typing import Union, Optional

import shelve
import torch
from uuid import uuid4
from torch import autocast
from fastapi import FastAPI
from fastapi import Response
from diffusers import StableDiffusionPipeline
from PIL import Image

app = FastAPI()

@app.on_event("startup")
def load_pipeline():
    app.pipe = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
    if torch.cuda.is_available():
        app.pipe.to("cuda")

@app.on_event("shutdown")
def load_pipeline():
    app.pipe = None

@app.get("/draw")
def drawing_pictures(prompt: Optional[str] = None):
    if torch.cuda.is_available():
        with autocast("cuda"):
            image = app.pipe(prompt).images[0]
    else:
        image = app.pipe(prompt).images[0]

    image_id = uuid4()
    image_path = f"out/{image_id}.png"
    image.save(image_path)
    with open(image_path, 'rb') as f:
        image_bytes = f.read()

    if prompt:
        with shelve.open("prompts") as db:
            db[image_id] = prompt
        return {"status": "success"}
    else:
        return {"error": "No prompt provided"}

    return Response(content=image_bytes, media_type="image/png")

@app.get("/prompts")
def list_prompts():
    with shelve.open("prompts") as db:
        return list(db.values())


import pandas as pd
import matplotlib.pyplot as plt
import statistics as sta
import numpy as np
from sklearn.metrics import r2_score

data=pd.read_csv('C:/Users/SUDHANSHU/Downloads/car data.csv')
# data.info() # To know about your Data

# Getting the dummie variables
dummy1=pd.get_dummies(data.Fuel_Type)
dummy2=pd.get_dummies(data.Transmission)
dummy3=pd.get_dummies(data.Seller_Type)

data=pd.concat([data,dummy1,dummy2,dummy3],axis=1)
data=data.drop(['Car_Name','CNG','Dealer','Manual','Transmission','Seller_Type','Fuel_Type'],axis=1)

price1=data.get('Present_Price')
year1=data.get('Year')
sp1=data.get('Selling_Price')
kmd1=data.get('Kms_Driven')
disel11=data.get('Diesel')
disel22=data.get('Petrol')
auto1=data.get('Automatic')
deal1=data.get('Individual')
data[['Diesel','Petrol','Automatic','Individual']]=data[['Diesel','Petrol','Automatic','Individual']].astype(int)

price=[]
year=[]
sp=[]
kmd=[]
disel1=[]
disel2=[]
auto=[]
deal=[]

def Normalization(A,B):
    for i in range(len(A)):
        B.append((A[i]-sta.mean(A))/sta.stdev(A))

#  Normalization of all the data

Normalization(price1,price)
Normalization(year1,year)
Normalization(sp1,sp)
Normalization(kmd1,kmd)
Normalization(disel11,disel1)
Normalization(disel22,disel2)
Normalization(auto1,auto)
Normalization(deal1,deal)
print(type(deal1),type(deal))
# initionalization of the varibles
m1=0
m2=0
m3=0
m4=0
m5=0
m6=0
m7=0
c=0

L=0.01 # LEARNING RATE

def Grad_decent(A,B):
    Sa=0
    for i in range(len(A)):
        if type(B)==int:
            s = (m1 * year[i] + m2 * sp[i] + m3 * kmd[i]+m4*disel1[i]+m5*disel2[i]+m6*auto[i]+m7*deal[i]+ c - price[i])
        else:
            s = (m1 * year[i] + m2 * sp[i] + m3 * kmd[i]+m4*disel1[i]+m5*disel2[i]+m6*auto[i]+m7*deal[i] + c - price[i]) * B[i]
        Sa=Sa+s
    return Sa
# For undating the variables

def Update(A,B):
    A=A-(L*B)/len(price)
    return A

JJ=[] # for Storing the values of the Cost function only for graph purpose
ii=[]

for i in range(10000):
    ii.append(i)
    J = 0
    for l in range(len(price)):
        ss = (c + m1 * year[l] + m2 * sp[l] + m3 * kmd[l] + m4 * disel1[l] + m5 * disel2[l] + m6 * auto[l] + m7 * deal[l] - price[l]) ** 2
        J = J + ss
    J1 = J / (2 * len(price))
    JJ.append(J1)

    S1 = Grad_decent(price, 1)
    S2 = Grad_decent(year, year)
    S3 = Grad_decent(sp, sp)
    S4 = Grad_decent(kmd, kmd)
    S5= Grad_decent(disel1,disel1)
    S6=Grad_decent(disel2,disel2)
    S7=Grad_decent(auto,auto)
    S8=Grad_decent(deal1,deal1)
    c = Update(c, S1)
    m1 = Update(m1, S2)
    m2 = Update(m2, S3)
    m3 = Update(m3, S4)
    m4 = Update(m4, S5)
    m5 = Update(m5, S6)
    m6 = Update(m6, S7)
    m7 = Update(m7, S8)

# print(m1,m2,m3,m4,m5,m6,m7,c) to get the values.

# Next we are changing the data types for calculation purpose
price=np.array(price)
year=np.array(year)
sp=np.array(sp)
kmd=np.array(kmd)
disel1=np.array(disel1)
disel2=np.array(disel2)
auto=np.array(auto)
deal=np.array(deal)

y=(m1 * year + m2 * sp + m3 * kmd+m4*disel1+m5*disel2+m6*auto+m7*deal)
r2=r2_score(price,y)

print('The R Sq is :',r2)
# This is the graph between the Cost function an no. of iterations , it helps in deciding the values of Learning rate and no of iteration.
plt.scatter(ii,JJ)
plt.show()


# Import Python functions
import numpy as np
import matplotlib.pyplot as plt
import datetime
import pandas as pd
import random, sys, os, glob
import pvlib
from pvlib.pvsystem import PVSystem
from pvlib.location import Location
from pvlib.modelchain import basic_chain, ModelChain
from pvlib.temperature import TEMPERATURE_MODEL_PARAMETERS
import emcee
from multiprocessing import Pool
from collections import Counter
from operator import itemgetter
from IPython.display import clear_output, Image
import warnings
warnings.simplefilter("ignore")

# Import custom functions
from clustering_functions_4D import ln_p_clustering, optimalK, best_walkers
from plot_functions_4D import burnin_chains, sample_chains, autocorrelation
from data_processing_4D import overwrite_files

# Assign guess values for theta, phi and Np. These are subsequently used in get_starting_values_ball below.
def guess_values():
    #params_pred = input('input predicted values for theta, phi and Np = ').split()
    #a, b, c = params_pred.split(',')

    theta_guess, phi_guess, Np_guess, sigma_guess = [int(x) for x in input("input predicted values (separated by a space) for theta, phi, Np and sigma = : ").split()]

    if (theta_guess < 0):
        print('a negative tilt angle is not possible. Exiting. Please try again'); sys.exit()
    if (theta_guess > 90):
        print('an angle larger than 90 degrees is not possible for the tilt angle. Exiting. Please try again.'); sys.exit()
    if (phi_guess < 0):
        phi_guess += 360
        print('Warning: a negative angle is possible; this is the same as phi += 360. Adding 360 degrees.')
    if (phi_guess > 360):
        phi_guess -= 360
        print('Warning: an angle larger than 360 degrees is possible; this is the same as phi -= 360. Subtracting 360 degrees.')
    if (Np_guess > 100):
        print('Warning: you are running an MCMC simulation for a very large system size. Are you sure?')
    if (sigma_guess < 0):
        print('a negative sigma is not possible. Exiting. Please try again'); sys.exit()

    return theta_guess, phi_guess, Np_guess, sigma_guess

# Assign MCMC starting values for nwalkers in 3D parameter space (theta, phi and Np).
def get_starting_values_ball(guess_values, ndim, nwalkers, variation):
    values = [guess_values + 1e-4*np.random.randn(ndim) for i in range(nwalkers)]

    return values

# Obtain PVlib energy day series for a chosen set of PV system characteristics using the Sandia module and SAPM inverter databases.
# Here, a SunPower module and AE Solar inverter were chosen. These may be substituted with other choices.
def get_energy_day(lat, lon, theta, phi, Np, year, month, day, naive_times, sandia_modules, sapm_inverters, timezone):

    module = sandia_modules['SunPower_SPR_230_WHT__2007__E__']
    inverter = sapm_inverters['AE_Solar_Energy__AE5_0__208V_']
    system = PVSystem(surface_tilt = theta, surface_azimuth = phi, module_parameters = module, modules_per_string = int(Np), strings_per_inverter = 1, inverter_parameters = inverter)
    location = Location(lat, lon, name='Amsterdam', altitude=10, tz=timezone)
    mc = ModelChain(system, location, orientation_strategy=None)
    mc.run_model(location.get_clearsky(naive_times))

    return [0 if np.isnan(e) else int(e) for e in mc.ac]

# Define the log likelihood function to be evaluated by Emcee.
def lnlike(params, dict_observed, times, hm, d0, lon, lat, sandia_modules, sapm_inverters, timezone):

    theta, phi, Np, sigma = params
    Np = int(Np)
    E_mod = get_energy_day(lat, lon, theta, phi, Np, d0.year, d0.month, d0.day, times, sandia_modules, sapm_inverters, timezone)
    dict_model = dict(list(zip(hm, E_mod)))
    obsmod = [(k, dict_observed[k], dict_model[k]) for k in sorted(dict_observed)]

    # Could define the value of N*log*2pi to speed up code.
    return (((-1*np.sum([((val[1]-val[2])**2) for val in obsmod])/(2*(sigma**2))))-(len(obsmod)*np.log(sigma)))
    #-(len(obsmod)*np.log(np.sqrt(2*3.14)))

# Define the prior for the MCMC. A uniform prior is defined which allows for all orientations and tilts and number of panels ranging
# between 1 and 100. Future improvement will include allowing for the prior to be constrained.
def lnprior(params):

    theta, phi, Np, sigma = params
    if 0.0 < theta < 90.0 and 0.0 < phi < 360.0 and 1 < Np < 100 and 0 < sigma < 1000:
        return 0.0
    return -np.inf

# Define the log probability as the sum of lnprior and lnlike. If phi is smaller than 0 or larger than 360, then phi is re-calculated.
def lnprob(params, dict_observed, times, hm, d0, lon, lat, sandia_modules, sapm_inverters, timezone):

    theta, phi_tmp, Np, sigma = params

    if (params[1]>360.0):
        params[1]-=360.0
    elif (params[1]<0.0):
        params[1]+=360.0
    else:
        params[1]=params[1]

    lp = lnprior(params)
    if not np.isfinite(lp):
        return -np.inf

    return lp + lnlike(params, dict_observed, times, hm, d0, lon, lat, sandia_modules, sapm_inverters, timezone)

# This function is employed in the sampling function (below) to check whether the chains have converged. The lines of code here come from
# the Emcee manual.
def check_convergence(tau, old_tau, iteration):
    converged = np.all(tau * 50 < iteration)
    print('50*tau/iteration = ', tau * 50/iteration)
    print('(old tau - tau)/tau = ', np.abs(old_tau - tau) / tau)
    converged &= np.all(np.abs(old_tau - tau) / tau < 0.01)
    return converged

# This function performs MCMC sampling up until the burn in phase is deemed completed. This is determined by clustering the walker chains
# and checking how close to each other the chains are in parameter space. For more information, look at the individual comments in the function.
def burnin(system_meta, system_measurements, date, mcmc_config, pvlib_databases, clustering_params, paths):
    # Assign variable values from tuples.
    (sid, lon, lat, timezone) = system_meta
    (dict_measurement, times, hm) = system_measurements
    (nwalkers, ndim, nproc, iterations, values) = mcmc_config
    (sandia_modules, sapm_inverters) = pvlib_databases
    (minClusters, maxClusters) = clustering_params
    (chains_path, plots_path) = paths

    nwalkers_initial = nwalkers
    year = int(date[0:4]); month = int(date[4:6]); day = int(date[6:8])
    d0 = datetime.datetime(year, month, day)

    # Check whether the MCMC chain files already exist.
    overwrite_files(chains_path, sid, date, nwalkers_initial, iterations)

    index = 0; index_burnin = -1; niters = 50; storage = True; ln_p_lastiters = []; index_var = 0

    # Define MCMC chain file which will be used by the Emcee backend function.
    filename = chains_path + 'chain_id%s_%s_w%s_i%s.h5' %(str(sid), date, str(nwalkers_initial), str(iterations))
    backend = emcee.backends.HDFBackend(filename); backend.reset(nwalkers, ndim)

    with Pool(processes=nproc) as pool:
        sampler = emcee.EnsembleSampler(nwalkers, ndim, lnprob, args=([dict_measurement, times, hm, d0, lon, lat, sandia_modules, sapm_inverters, timezone]), pool=pool, backend=backend, moves=emcee.moves.WalkMove())
        # The while loop keeps running until the end of the burn in period has been reached.
        # The end is determined on the basis of statistics applied to the remaining number of clustered walkers.
        while (index == 0):
            index_burnin += 1
            # The MCMC sampling is performed for 50 iterations afte
            for sample in sampler.sample(initial_state = values, iterations = niters, progress=True, store=storage):
                ln_p_lastiters.extend(sample.log_prob)
                # Ignore all calculations in this loop unless the number of iterations (sampler.iteration) equals niters.
                if sampler.iteration % niters:
                    continue
                clear_output(wait=True)
                # All code within this if statement is concerned with the plotting of the MCMC chains.
                # This is not performed on the first run, since no chains have been generated yet.
                if (index_burnin > 0):
                    #files = sorted(glob.glob(chains_path + '*i10000*h5'))
                    files = sorted(glob.glob(chains_path + 'chain_id%s_%s_w%s_i%s*.h5' %(str(sid), date, str(nwalkers_initial), str(iterations))))
                    samples, log_samples = get_last_sample(files)
                    # Create plot for the first set of chains and keep appending plot afterwards.
                    if (index_burnin == 1):
                        fig, axes = plt.subplots(6, figsize=(15, 11), sharex=True)
                    starter_val = index_burnin*niters
                    burnin_chains(fig, axes, starter_val, starter_val + niters, samples, log_samples, plots_path, \
                                  sid, nwalkers_initial, iterations, date)

#                    display(Image(filename = plots_path + 'mcmc_id%s_%s_w%s_i%s.png' %(str(sid), date, str(nwalkers_initial), str(iterations))))

                # Perform k means clustering. See functions ln_p_clustering and optimalK for more info.
                ln_p_mean, kmeans = ln_p_clustering(ln_p_lastiters, nwalkers, minClusters, maxClusters)
                occurrences = Counter(kmeans.labels_)
                walker_group = list(zip([i for i in range(len(kmeans.labels_))], kmeans.labels_))
                # Calculate the variance (spread) of the mean log posterior per walker.
                ln_p_var = np.var(ln_p_mean)

                # Check whether the variance is small or large.
                print(ln_p_var)
                if (ln_p_var > 5):
                    index=0
                    # Check whether the number of clustered groups is larger than 1.
                    if (len(occurrences)>1):
                        # Determine which walkers belong to which group.
                        min_key, min_count = min(occurrences.items(), key=itemgetter(1))
                        min_val = kmeans.cluster_centers_[min_key][0]
                        if (abs(np.min(kmeans.cluster_centers_)-min_val)<1e-5):
                            id_walkers = [num[0] for num in walker_group if num[1] != min_key]
                        else:
                            id_walkers = [num[0] for num in walker_group]
                    # If there is only one group of walkers, then all walkers are retained for the next 50 iterations.
                    else:
                        id_walkers = [num[0] for num in walker_group]

                # If the variance is smaller than 5, this could indicate that the chains are starting to converge towards the same point.
                # To test whether this is the case, a counter (index_var) is initialised. If the algorithm ends up five successive times
                # in this else statement, the MCMC burn in is considered finished.
                else:
                    index=0
                    id_walkers = [num[0] for num in walker_group]
                    index_var += 1
                    print('Index var equals ', index_var)
                    # Set a check index to the burn in index. The difference between the indices must be five if else statement was performed
                    # 5 successive times.
                    if index_var == 1:
                        check_first = index_burnin
                    if index_var == 6:
                        check_last = index_burnin
                        if ((check_last - check_first) == 5):
                            index = 1
                        else:
                            index_var = 0

                # Define a new filename for the new backend. Please see explanation below as to why this is necessary.
                filename = chains_path + 'chain_id%s_%s_w%s_i%s_' %(str(sid), date, str(nwalkers_initial), str(iterations)) + "{:02}".format(index_burnin) + '.h5'
                new_backend = emcee.backends.HDFBackend(filename)
                state = sampler.get_last_sample()

                # Account for larger or smaller angles for orientation and subtract or add 360 degrees.
                for i in range(len(state.coords)):
                    if state.coords[i][1]>360.0:
                        state.coords[i][1] = state.coords[i][1]-360.0
                    if state.coords[i][1]<0.0:
                        state.coords[i][1] = state.coords[i][1]+360.0

                # Change Emcee's 'state' to allow for the clustering approach above. Only want to retain the relevant walkers.
                state.log_prob = np.array([i for j, i in enumerate(state.log_prob) if j in id_walkers])
                state.coords = np.array([i for j, i in enumerate(state.coords) if j in id_walkers])
                print('Best walker value is ', np.min(state.log_prob))
                state.random_state = None
                # Determine the new number of walkers, after clustering.
                nwalkers = len(state.log_prob)
                # Reset the backend with the new number of walkers.
                backend.reset(nwalkers, ndim)
                ndim = 4
                print('new number of walkers is ', nwalkers)
                # Define the sampler with the new backend. This is necessary because it is not possible to append to the same h5 file, when the
                # number of chains decreases.
                sampler = emcee.EnsembleSampler(nwalkers, ndim, lnprob, args=([dict_measurement, times, hm, d0, lon, lat, sandia_modules, sapm_inverters, timezone]), backend = new_backend, pool = pool, moves = emcee.moves.WalkMove())
                values = state; storage = True; ln_p_lastiters = []

            # Check whether the burn in phase is completed. Else continue.
            if (index == 1):
                print('Burn in phase completed')
                break
            else:
                print('Burn in phase is still happening')
                os.system("clear")

    clear_output(wait=True)
    print('MCMC sampling can now commence')

    # Having exited the while loop, the best 8 walkers are obtained with the function best_walkers. User can choose to keep more walkers
    # if desired, though bear in mind that this number also depends on the number of walkers used to start with. Here we used 40, so this number
    # should also be increased.
    nwalkers = 8
    state = best_walkers(state)
    return state

# This function is performed after the burnin function (above).
def sampling(system_meta, system_measurements, date, mcmc_config, pvlib_databases, clustering_params, paths):
    # Assign variable values from tuples.
    (sid, lon, lat, timezone) = system_meta
    (dict_measurement, times, hm) = system_measurements
    (nwalkers, ndim, nproc, iterations, values) = mcmc_config
    (sandia_modules, sapm_inverters) = pvlib_databases
    (minClusters, maxClusters) = clustering_params
    (chains_path, plots_path) = paths

    nwalkers_initial = nwalkers
    year = int(date[0:4]); month = int(date[4:6]); day = int(date[6:8])
    d0 = datetime.datetime(year, month, day)
    filename = chains_path + 'chain_id%s_%s_w%s_i%s_sample.h5' %(str(sid), date, str(nwalkers_initial), str(iterations))
    filename_plot = plots_path + 'autocorrelation_id%s_%s_w%s_i%s.png' %(str(sid), date, str(nwalkers_initial), str(iterations))
    new_backend = emcee.backends.HDFBackend(filename)
    max_n = iterations
    storage = True
    autocorr = np.empty(max_n)
    index = 0
    niters = 50
    # Necessary to initialise old tau at infinity (see Emcee documentation)
    old_tau = np.inf

    # Similar to burnin function.
    with Pool(processes=nproc) as pool:
        sampler = emcee.EnsembleSampler(nwalkers, ndim, lnprob, args=([dict_measurement, times, hm, d0, lon, lat, sandia_modules, sapm_inverters, timezone]), pool = pool, backend = new_backend, moves = emcee.moves.WalkMove())
        for sample in sampler.sample(initial_state = values, iterations = max_n, progress = True, store = storage):
            if sampler.iteration % niters:
                continue

            # Compute the autocorrelation time so far. See Emcee documentation for this snippet.
            clear_output(wait = True)
            tau = sampler.get_autocorr_time(tol = 0)
            autocorr[index] = np.mean(tau)
            index += 1

            # Check convergence
            converged = check_convergence(tau, old_tau, sampler.iteration)

            # Plot the auto correlation time
            autocorrelation(index, autocorr, filename_plot)

            # Check if convergence has occurred
            if converged:
                break
            old_tau = tau

            sample_chains(filename, plots_path, sid, nwalkers, iterations, date)
#            display(Image(filename = plots_path + 'mcmc_id%s_w%s_i%s_%s.png' %(str(sid), str(nwalkers), str(iterations), date)))

#    display(Image(filename = plots_path + 'mcmc_id%s_w%s_i%s_%s.png' %(str(sid), str(nwalkers), str(iterations), date)))

    print("Mean acceptance fraction:{0:.3f}".format(np.mean(sampler.acceptance_fraction)))

# Obtain the last MCMC chain sample. The output of this function is used as input for the burnin_chains function.
def get_last_sample(files):
    all_samples = []; all_log_samples = []
    for file in files[-1:]:
        reader = emcee.backends.HDFBackend(file)
        total_samples = reader.get_chain()
        length = total_samples.shape[0]
        log_prob_samples = reader.get_log_prob()
        for sample in total_samples:
            all_samples.append(sample)
        for logprob in log_prob_samples:
            all_log_samples.append(logprob)

    samples = np.asarray(all_samples)
    log_samples = np.array(all_log_samples)

    return samples, log_samples


import sys, os, csv

sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
from tools import path as p
from tools import collector as c

def parse_timeline_json(tier, division):
    """timeline json파일을 csv파일로 paring하여 저장한다.

    Args:
        tier: parsing하고자 하는 tier
        division: parsing하고자 하는 division
    """
    # parsing해야하는 timeline json들이 저장되어 있는 경로
    timelines_path = p.get_parent_data_path("timelines", tier, division)
    print(timelines_path)
    timelines_dir_list = os.listdir(timelines_path)
    print(timelines_dir_list)

    # 디렉토리에 폴더가 없다면 parsing 불가
    if len(timelines_dir_list) == 0:
        print("no timeline data")
        return

    # timeline json들이 저장된 디렉토리 중 가장 마지막 폴더 번호
    last_timeline_dir_num = int(sorted(timelines_dir_list)[-1])

    # timeline csv저장될 경로.
    timeline_csv_path = p.get_additional_data_path(
        "timeline_csv", tier, division, last_timeline_dir_num
    )

    # csv fields
    fields = [
        "tier",
        "division",
        "match_id",
        "timestamp",
        "type",
        "winningTeam",
        "afterId",
        "ascendedType",
        "beforeId",
        "buildingType",
        "creatorId",
        "eventType",
        "framesInterval",
        "itemId",
        "killerId",
        "laneType",
        "levelUpType",
        "monsterSubType",
        "monsterType",
        "participantId",
        "pointCaptured",
        "skillSlot",
        "teamId",
        "towerType",
        "victimId",
        "wardType",
    ]
    # csv중 특정 column에 값을 넣기 위한 dix dictionary
    field_idx = {f: i for i, f in enumerate(fields)}

    # 마지막 수집한 timeline 데이터들이 담긴 디렉토리 경로, json 리스트
    timeline_json_path = p.get_additional_data_path(
        "timelines", tier, division, last_timeline_dir_num
    )
    timeline_json_list = os.listdir(timeline_json_path)
    for i, timeline_json_file_name in enumerate(timeline_json_list):
        try:
            # 로드할 timeline json 경로와, 파일
            timeline_json_file_path = timeline_json_path + timeline_json_file_name
            timeline_json_file = c.get_json_dict(timeline_json_file_path)

            # parsing 기본사항들
            match_id = timeline_json_file["metadata"]["matchId"]
            row = [None for _ in range(len(fields))]
            row[0], row[1], row[2] = tier, division, match_id

            # timeline csv 경로 설정.
            timeline_csv_name = p.timeline_csv_name(match_id)
            final_timeline_csv_path = timeline_csv_path + timeline_csv_name

            if os.path.exists(final_timeline_csv_path):
                print("이미 csv파일이 존재함")
                continue

            # csv 파일 생성 및 field 입력
            out_file = open(final_timeline_csv_path, "w", newline="")
            write = csv.writer(out_file)
            write.writerow(fields)

            # parsing, csv write
            frames = timeline_json_file["info"]["frames"]
            for frame_n, frame in enumerate(frames):
                events = frame["events"]
                for event_n, event in enumerate(events):
                    for key, value in event.items():
                        if key in field_idx:
                            row[field_idx[key]] = value
                    write.writerow(row)
            out_file.close()

            # 진행도
            if (i + 1) % 1000 == 0:
                percent = (i + 1) / len(timeline_json_list) * 100
                print(f"{tier}, {division} timeline {percent}% 처리")

        except IndexError as e:
            print(e)
            print("에러 발생 생략")
    print(f"{final_timeline_csv_path} 저장")

if __name__ == "__main__":
    tiers = ["SILVER", "GOLD", "PLATINUM", "DIAMOND"]
    divisions = ["I", "II", "III", "IV"]
    for tier in tiers:
        for division in divisions:
            parse_timeline_json(tier, division)


from datetime import timedelta, datetime
from dateutil.relativedelta import relativedelta
import pytz
from odoo import models, fields, api, _
from odoo.addons.calendar.models.calendar_recurrence import (
    weekday_to_field,
    RRULE_TYPE_SELECTION,
    END_TYPE_SELECTION,
    MONTH_BY_SELECTION,
    WEEKDAY_SELECTION,
    BYDAY_SELECTION
)

class Contract(models.Model):
    _inherit = "contract.contract"

    @api.depends("sale_id")
    def _compute_sales_count(self):
        for rec in self:
            if rec.sale_id:
                rec.sale_count = len(rec.sale_id)
            else:
                rec.sale_count = 0

    @api.depends("name")
    def _compute_calendar_count(self):
        for rec in self:
            rec.calendar_ids = self.env["calendar.event"].search([("contract_id", "=", self.id)]).ids
            rec.calendar_count = len(rec.calendar_ids)

    sale_id = fields.Many2one("sale.order", string="Sale")
    sale_count = fields.Integer(string="Sale Count", compute=_compute_sales_count)

    calendar_ids = fields.Many2many("calendar.event", string="Schedule", compute=_compute_calendar_count)
    calendar_count = fields.Integer(string="Calendar Count", compute=_compute_calendar_count)

    # SCHEDULE FIELD
    recurrency = fields.Boolean('Recurrent', help="Recurrent Event")
    end_type = fields.Selection(END_TYPE_SELECTION, string='Recurrence Termination', readonly=False, default='count')
    count = fields.Integer(string='Repeat', help="Repeat x times", readonly=False, default=1)
    interval = fields.Integer(string='Repeat Every', help="Repeat every (Days/Week/Month/Year)", default=1)
    rrule_type = fields.Selection(RRULE_TYPE_SELECTION, string='Recurrence',
                                  help="Let the event automatically repeat at that interval", readonly=False,
                                  default='weekly')

    month_by = fields.Selection(MONTH_BY_SELECTION, string='Option', readonly=False, default='date')
    day = fields.Integer('Date of month', readonly=False)
    weekday = fields.Selection(WEEKDAY_SELECTION, readonly=False, default='TU')
    byday = fields.Selection(BYDAY_SELECTION, readonly=False, default='3')
    until = fields.Date(string="Until")

    mo = fields.Boolean('Mon', readonly=False)
    tu = fields.Boolean('Tue', readonly=False)
    we = fields.Boolean('Wed', readonly=False)
    th = fields.Boolean('Thu', readonly=False)
    fr = fields.Boolean('Fri', readonly=False)
    sa = fields.Boolean('Sat', readonly=False)
    su = fields.Boolean('Sun', readonly=False)

    duration = fields.Float('Duration')

    start = fields.Datetime(
        'Start', required=True, tracking=True, default=fields.Date.today,
        help="Start date of an event, without time for full days events")
    stop = fields.Datetime(
        'Stop', required=True, tracking=True, default=lambda self: fields.Datetime.today() + timedelta(hours=1),
        readonly=False, store=True,
        help="Stop date of an event, without time for full days events")

    def action_view_sales(self):
        self.ensure_one()
        ctx = dict(self.env.context)

        action = {
            "type": "ir.actions.act_window",
            "name": "Contract Sale",
            "res_model": "sale.order",
            "view_mode": "form",
            "domain": [("id", "=", self.sale_id.id)],
            'res_id': self.sale_id.id,
            "context": ctx,
        }
        return action

    def action_create_calendar(self):
        self._clean_existing_calendar()
        calendar_event_id = self.env["calendar.event"].create(self._prepare_event_calendar_values())
        self.calendar_ids = [(4, calendar_event_id.id)]
        return calendar_event_id

    def _clean_existing_calendar(self):
        calendar_event_id = self.env["calendar.event"].search([('contract_id', '=', self.id)])
        if calendar_event_id:
            calendar_event_id.unlink()

    def _prepare_event_calendar_values(self):
        start = datetime.strftime(fields.Datetime.context_timestamp(self, self.start), "%Y-%m-%d %H:%M:%S")
        stop = datetime.strftime(fields.Datetime.context_timestamp(
            self, self.start + relativedelta(hours=self.duration)), "%Y-%m-%d %H:%M:%S")
        values = {
            "name": f"{self.name}",
            "partner_ids": [(4, self.partner_id.id)],
            "start": start,
            "stop": stop,
            "duration": self.duration,
            "user_id": self.user_id.id,
            "show_as": "busy",
            "contract_id": self.id,
        }
        if self.recurrency:
            values.update({
                "recurrency": self.recurrency,
                "interval": self.interval,
                "rrule_type": self.rrule_type,
                "end_type": self.end_type,
                "count": self.count,
                "month_by": self.month_by,
                "byday": self.byday,
                "weekday": self.weekday,
                "mo": self.mo,
                "tu": self.tu,
                "we": self.we,
                "th": self.th,
                "fr": self.fr,
                "sa": self.sa,
                "su": self.su,
                "until": self.until
            })
        return values

    def action_view_schedules(self):
        self.ensure_one()
        tree_view = self.env.ref("calendar.view_calendar_event_tree", raise_if_not_found=False)
        form_view = self.env.ref("calendar.view_calendar_event_form", raise_if_not_found=False)
        calendar_view = self.env.ref("sale_contract.view_calendar_event_calendar_month_mode", raise_if_not_found=False)
        ctx = dict(self.env.context)

        action = {
            "type": "ir.actions.act_window",
            "name": "Contract Schedule",
            "res_model": "calendar.event",
            "view_mode": "calendar,tree,form",
            "domain": [("id", "in", self.calendar_ids.ids)],
            "context": ctx,
        }
        if tree_view and form_view and calendar_view:
            action["views"] = [(calendar_view.id, "calendar"), (tree_view.id, "tree"), (form_view.id, "form")]
        return action


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

import http

class Spider(object):
      def __init__(self, homeUrl, parser):
            super(Spider, self).__init__()
            self.homeUrl = homeUrl
            self.parser = parser

      def getAMessage(self):
            html = http.get(self.homeUrl)
            self.parser.feed(html)
            return self.parser.getMsg()

if __name__ == '__main__':
      import techweb
      import cnbeta
      import cnblog
      import tuicool

      spiders = [
            Spider(cnbeta.HOME_URL, cnbeta.CnbetaParser()),
            Spider(cnblog.HOME_URL, cnblog.CnblogParser()),
            Spider(techweb.HOME_URL, techweb.TechwebParser()),
            Spider(tuicool.HOME_URL, tuicool.TuicoolParser()),
      ]

      count = len(spiders)
      for i in range(count):
            spider = spiders[i]
            print ("-----------------------------")
            print (spider.homeUrl)
            for j in range(3):
                  text = spider.getAMessage()
                  print (text)


import cv2
import numpy as np

image = cv2.imread('nature.jpg', 1)
blur = cv2.blur(image, (5, 5))
gaussian = cv2.GaussianBlur(image, (5, 5), 0)
cv2.imshow('org', image)
cv2.imshow('blur', blur)
cv2.imshow('gaussian', gaussian)
cv2.waitKey(0)
cv2.destroyAllWindows()


from classify import Zucchini
from coordinate import Yolo
from device import Camera

import threading
import cv2

class Result():
    def __init__(self, width, height):
        self.zuc = Zucchini()
        self.yolo = Yolo()
        self.width = width
        self.height = height

    def initialize(self,WEIGHTS="", CFG="", H5=""):
        self.weights = WEIGHTS
        self.cfg = CFG
        self.h5 = H5
        return self.check_file()

    def check_file(self):
        if self.weights == "" or self.cfg == "" or self.h5 =="":
            print("WARNING: please select all files")
            ret = 0
        print("--WEIGHTS:", self.weights.split(sep="/")[-1])
        print("--CFG:", self.cfg.split(sep="/")[-1])
        print("--H5:",self.h5.split(sep="/")[-1])

        if self.h5 !="":
            self.zuc.initialize(self.h5)
            ret = 1

        if self.weights != "" and self.cfg != "":
            self.yolo.initialize(self.width, self.height, self.weights, self.cfg)
            ret = 2

        if self.h5 !="" and self.weights != "" and self.cfg != "":
            ret = 3

        return ret

    def get_class(self, frame):
        return self.zuc.detect_zucchini(frame)

    def get_xy(self):
        if self.yolo.found:
            label, x, y, w, h = self.yolo.get_xy()
            tmp = "애호박 "+label+", 좌표:("+str(x)+", "+str(y)+")"
            return tmp
        else:
            return "Not Found"

    def get_res(self,frame):
        if self.yolo.found:
            label, x, y, w, h = self.yolo.get_xy()
            img = self.zuc.crop(frame, x,y,w,h)
            classname= self.zuc.detect_zucchini(img)
            tmp = classname+" "+label+", 좌표:("+str(x)+", "+str(y)+")"
            return tmp
        else:
            return "Not Found"

if __name__ == '__main__':
    vs = cv2.VideoCapture("zuc/zuc4.avi")
    if not vs.isOpened:
        print('Cannot load video')
        exit(0)
    w = int(vs.get(cv2.CAP_PROP_FRAME_WIDTH))
    h = int(vs.get(cv2.CAP_PROP_FRAME_HEIGHT))

    result = Result(w,h)
    result.initialize("zuc/z-yolo.weights", "zuc/zuc.cfg", "zuc/best_model.h5")
    chk = result.check_file()
    print(chk)

    t1 = threading.Thread(target=result.yolo.find_xy, daemon=True)
    t1.start()
    tmp = 0

    while True:
        ret, frame = vs.read()
        if frame is None:
            print('No frame')
            vs.release()
            break

        result.yolo.update_frame(frame)
        if result.yolo.found:
            label, x, y, w, h = result.yolo.get_xy()
            if tmp != x:
                print(result.get_res(frame))
                tmp = x
            frame = result.yolo.print_rec(frame)
        cv2.imshow('', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break


from django.shortcuts import render_to_response
from django.template import RequestContext
from apps.producto.models import producto
from apps.producto.forms import productoForm
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required

@login_required(login_url='/personal/login')
def view_add(request):
	if request.method == "POST":
		form = productoForm(request.POST)
		if form.is_valid():
			form.save()
			return HttpResponseRedirect("/productos")
		else:
			form  = productoForm()
			msg="Revisa bien los datos"
			ctx = {'form':form,'msg':msg}
			return render_to_response('producto/add.html',ctx,
				context_instance=RequestContext(request))

	else:
		form = productoForm()
		msg="Ingresa los datos"
		ctx = {'form':form,'msg':msg}
		return render_to_response('producto/add.html',ctx,
				context_instance=RequestContext(request))

@login_required(login_url='/personal/login')
def view_edit(request,id):
	p = producto.objects.get(pk=id)
	if request.method == "POST":
		form = productoForm(request.POST,instance=p)
		if form.is_valid():
			form.save()
			return HttpResponseRedirect("/productos/")
		else:
			form = productoForm(p)
			msg="Revisa bien los datos"
			ctx = {'form':form,'msg':msg}
			return render_to_response('producto/edit.html',ctx,
				context_instance=RequestContext(request))

	else:
		form = productoForm(instance=p)
		msg="Ingresa los datos"
		ctx = {'form':form,'msg':msg}
		return render_to_response('producto/edit.html',ctx,
				context_instance=RequestContext(request))

@login_required(login_url='/personal/login')
def view_del(request,id):
	p = producto.objects.get(pk=id)
	p.delete()
	return HttpResponseRedirect("/productos/")

@login_required(login_url='/personal/login')
def view_lista(request):
    contact_list = producto.objects.all()
    paginator = Paginator(contact_list, 5) # Show 25 contacts per page

    page = request.GET.get('page')
    try:
        productos = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        productos = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        productos = paginator.page(paginator.num_pages)

    return render_to_response('producto/lista.html', {"lista": productos},
				context_instance=RequestContext(request))


#!/usr/bin/python

# importing libraries
import paho.mqtt.client as paho
import os
import socket
import ssl
import ast
import json
import os
import logging

# read AWS parametars json
json_path = "/home/pi/WorkSpace/IoT_test/AWS_IoT.txt"
connect_json = open(json_path,'r')
connect_dict = json.load(connect_json)

# AWS parameters
awshost = connect_dict["ENDPOINT"]
awsport = 8883
clientId  = "IoT_test_1"
thingName = "IoT_test"
caPath = "root-CA.crt"
certPath = "IoT_test.cert.pem"
keyPath = "'IoT_test.private.key'"
mode='both'
pub_message='Hello World!'
SUB_topic="#"

# Configure logging
logger = logging.getLogger("AWSIoTPythonSDK.core")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)

# Custom MQTT message callback
def on_message(client, userdata, message):
    print("--------------")
    print("Received a new message: ")
    print(message.payload)
    print("from topic: ")
    print(message.topic)
    print("--------------\n")

def on_connect(client, userdata, flags, rc):                # func for making connection
    print("Connection returned result: " + str(rc) )
    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.subscribe(SUB_TOPIC , 1)

def on_log(client, userdata, level, msg):
    print(msg.topic+" "+str(msg.payload))

# Publish to the same topic in a loop forever
loopCount = 0
mqttc = paho.Client()                                       # mqttc object
mqttc.on_connect = on_connect                               # assign on_connect func
mqttc.on_message = on_message                               # assign on_message func
mqttc.on_log = on_log

mqttc.tls_set(caPath, certfile=certPath, keyfile=keyPath, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)      # pass parameters

mqttc.connect(awshost, awsport, keepalive=60*10)               # connect to aws server

mqttc.loop_forever()


import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

from numpy.core.numeric import NaN
from numpy.lib.function_base import rot90
import pandas as pd
import sys
import os
import ast

import copy as cp
import numpy as np
from pandas.core import series

# filename = 'Jun-20-2021  19:13:01/__Jun-20-2021  19:13:01'
filename = 'Jun-20-2021  20:09:54/__Jun-20-2021  20:09:54'

df = pd.read_csv(filename + '.csv')
df_events = pd.read_csv(filename + '-events.csv')
df_missions = pd.read_csv(filename + '-missions.csv')

try:
    action = sys.argv[2]
except:
    action = 'show'

if action == 'save':
    output_dir = filename.replace('.csv','')
    try:
        os.stat(output_dir)
    except:
        os.mkdir(output_dir)

try:
    x_axis_type = sys.argv[3]
except:
    x_axis_type = 'time'

if x_axis_type not in ['events','time']:
    print('Wrong argument for x axis. Assuming time')
    x_axis_type = 'time'

# print(df.head())
# print(df_events.head())
# print(df_missions.head())

#####################################################################################
MAX_TIME = 2300
robots = ['pioneer3at_1', 'pioneer3at_2', 'UAV_1', 'UAV_2']
bat_low = {'pioneer3at_1': [(1628.86,24.66)], 'pioneer3at_2': [(1600.14,24.19)], 'UAV_1': [(2252.93,24.32)], 'UAV_2': [(1698.99,24.96)]}
fail = {'pioneer3at_1': [], 'pioneer3at_2': [461.18], 'UAV_1': [1426.93,2083.82], 'UAV_2': []}
victim = {'pioneer3at_1': [1518.94], 'pioneer3at_2': [1255.51], 'UAV_1': [806.29], 'UAV_2': []}

## List of events by robot
events = {}
events['pioneer3at_1']  = pd.Series(index = [1518.94,1628.86], data = ['v_found','bat_low'])
events['pioneer3at_2']  = pd.Series(index = [461.18,1255.51,1600.14], data = ['fail','v_found','bat_low'])
events['UAV_1']         = pd.Series(index = [806.29,1426.93,2083.82,2252.93], data = ['uav_v_found','uav_fail', 'uav_fail','uav_bat_low'])
events['UAV_2']         = pd.Series(index = [1698.99], data = ['uav_bat_low'])

for r in robots:
    fig = plt.figure(constrained_layout=True, figsize=(18,10))
    fig.suptitle(r, fontsize="x-large")
    gs = fig.add_gridspec(3, 2)
    ax1 = fig.add_subplot(gs[0,0])
    ax1.spines['right'].set_visible(False)
    ax1.spines['top'].set_visible(False)
    ax1.spines['bottom'].set_visible(False)
    ax1.set_xlim(0, MAX_TIME)
    # ax1.set_title('Current maneuver')

    ax2 = fig.add_subplot(gs[1,0])
    ax2.spines['right'].set_visible(False)
    ax2.spines['top'].set_visible(False)
    ax2.spines['bottom'].set_visible(False)
    ax2.set_xlim(0, MAX_TIME)
    # ax2.set_title('Battery level (%)')

    ax3 = fig.add_subplot(gs[2,0])
    ax3.spines['right'].set_visible(False)
    ax3.spines['top'].set_visible(False)
    ax3.spines['left'].set_visible(False)
    ax3.set_ylim(-1, 4)
    ax3.set_xlim(0, MAX_TIME)
    # ax2.set_title('events (%)')

    ax4 = fig.add_subplot(gs[:, 1], projection = '3d')
    ax4.set_title('Robot trajectory')

    #####-- CURRENT MANEUVER GRAPH --###############################################################################
    ax1.plot(df.iloc[:,0].values, df['{}_cur_maneuver'.format(r)].values, 'k', label='_nolegend_')
    # ax1.tick_params(axis='x', rotation=90)
    ax1.set_xticks([])
    ax1.set_yticks(['None','teleoperation',
                    'return to base',
                    'surroundings verification',
                    'safe land',
                    'approach',
                    'exploration',
                    'assessment',
                    'victim search'])

    for e in events[r].index:
        ax1.axvline(e, color ='r', lw = 1.5, ls='-.', alpha = 0.75)

    ax1.set_ylabel('Current maneuver', rotation='vertical')
    # ax1.legend(loc = 'best')

    #####-- BATTERY LEVEL GRAPH --##################################################################################
    ax2.plot(df.iloc[:,0].values, df['{}_battery'.format(r)].values, 'b', label='_nolegend_')
    # ax2.tick_params(axis='x', rotation=90)
    # ax2.set_xticks(range(0,2400,100))
    ax2.set_xticks([])
    ax2.set_yticks(range(0,110,10))

    # ax2.set_xlabel('Time (s)')
    ax2.set_ylabel('Battery Level (%)', rotation='vertical')

    #Scatter points
    x = [b[0] for b in bat_low[r]]
    y = [b[1] for b in bat_low[r]]
    ax2.scatter(x, y, marker='o', color='r', zorder=10)

    for e in events[r].index:
        ax2.axvline(e, color ='r', lw = 1.5, ls='-.', alpha = 0.75)

    #####-- EVENTS TIMELINE GRAPH --################################################################################
    levels = np.tile([3.5, 4], int(np.ceil(len(events[r])/2)))[:len(events[r])]

    # Create figure and plot a stem plot with the date
    ax3.vlines(events[r].index, 0, levels, color="tab:red")  # The vertical stems.
    ax3.plot(events[r].index, np.zeros_like(events[r].index), "-o", color="k", markerfacecolor="w")  # Baseline and markers on it.

    # annotate lines
    for d, l, e in zip(events[r].index, levels, events[r].values):
        ax3.annotate(e, xy=(d, l),
                    xytext=(-3, np.sign(l)*3), rotation=90, textcoords="offset points",
                    horizontalalignment="right",
                    verticalalignment="top")

    ax3.tick_params(axis='x', rotation=90)
    ax3.set_xticks(range(0,MAX_TIME+100,100))
    ax3.set_yticks([])
    ax3.set_xlabel('Time (s)')
    ax3.set_ylabel('Event', rotation='vertical')

    #####-- ROBOTS TRAJECTORIES GRAPH --###########################################################################
    graphs = {'normal': 'k', 'vsv': 'b', 'rb': 'r'}
    t = {'x':[], 'y':[], 'z':[]}
    m_trajectories = {'normal': [], 'vsv': [], 'rb': []}

    last_pose = None
    last_m_type = None
    for i in df[(df['{}_pose'.format(r)] != '[]')].index:
        pose = ast.literal_eval(df.loc[i, '{}_pose'.format(r)])
        if not df.loc[i,'{}_cur_maneuver'.format(r)] in ['surroundings verification', 'return to base']:
            m_type = 'normal'
        elif df.loc[i,'{}_cur_maneuver'.format(r)] == 'surroundings verification':
            m_type = 'vsv'
        elif df.loc[i,'{}_cur_maneuver'.format(r)] == 'return to base':
            m_type = 'rb'

        if (m_type != last_m_type) and (m_type != None):
            m_trajectories[m_type].append(cp.deepcopy(t))
            if last_pose:
                m_trajectories[m_type][len(m_trajectories[m_type])-1]['x'].append(last_pose[0])
                m_trajectories[m_type][len(m_trajectories[m_type])-1]['y'].append(last_pose[1])
                m_trajectories[m_type][len(m_trajectories[m_type])-1]['z'].append(last_pose[2])
        m_trajectories[m_type][len(m_trajectories[m_type])-1]['x'].append(pose[0])
        m_trajectories[m_type][len(m_trajectories[m_type])-1]['y'].append(pose[1])
        m_trajectories[m_type][len(m_trajectories[m_type])-1]['z'].append(pose[2])

        last_pose = pose
        last_m_type = m_type

    #Plot maneuvers trajectory
    for m in m_trajectories:
        for t in m_trajectories[m]:
            ax4.plot3D(t['x'], t['y'], t['z'], graphs[m])

    ax4.set_xlabel('X (m)')
    ax4.set_ylabel('Y (m)')
    ax4.set_zlabel('Z (m)')
    # ax4.set_xlim3d(0, 75)
    # ax4.set_ylim3d(0, 40)
    ax4.set_zlim3d(0, 15)

    # Save the figure
    if action == 'save':
        plt.savefig(output_dir + '/{}.png'.format(r))

#############################
# SHOW GRAPHS
if action == 'show':
    plt.show()


import docker
import pytest
from docker.errors import NotFound

from srsran_controller.common.docker.entity import Entity

TEST_IMAGE_DOCKER = 'ubuntu'
TEST_COMMAND = '/bin/yes'

@pytest.fixture(scope='function')
def container():
    client = docker.from_env()
    return client.containers.run(TEST_IMAGE_DOCKER, TEST_COMMAND, auto_remove=True, detach=True)

def test_shutting_down(container):
    client = docker.from_env()
    entity = Entity(container)
    entity.shutdown()
    with pytest.raises(NotFound):
        assert client.containers.get(container.id)

def test_shutting_down_removed_container(container):
    client = docker.from_env()
    entity = Entity(container)
    container.kill()
    try:
        container.wait(condition='removed')
    except NotFound:
        pass
    entity.shutdown()
    with pytest.raises(NotFound):
        assert client.containers.get(container.id)


from molmod import deg
from molmod.ic import bend_angle, dihed_angle
from molmod.molecules import Molecule

from collections import deque

# generator for bonds of length k
def kth_neighbor(mol, start, k):
    que = deque()
    que.append([start])
    current_level = 1

    # level order bfs
    while len(que) > 0 and current_level < k:
        level_size = len(que)
        current_level += 1

        # iterate through the next level
        for _ in range(level_size):
            path = que.popleft()
            current_node = path[-1]

            for next_node in mol.graph.neighbors[current_node]:
                # make sure we do not visit the same node
                if next_node not in path:
                    que.append(path+[next_node])

    # if there is nothing left, there are no bonds of degree k
    while len(que) > 0:
        yield que.popleft()

# list of all unique bonds of length k
def kth_bonds(mol, k=4):
    # inner help function to check if suspect is already in unique
    def is_unique(suspect):
        for bond in unique:
            if sorted(bond) == sorted(suspect):
                return False
        return True

    # result list of unique bonds
    unique = list()

    # iterate through each atom as the starting point
    for i in range(mol.size):
        # find kth degree neighbors
        for bond in kth_neighbor(mol, i, k):
            # add bond to result set if it is unique
            if is_unique(bond):
                unique.append(bond)
                yield bond

# util to print
def pretty(it, delimiter="\n"):
    print(delimiter.join(map(str, it)))

# util to print symbols
def symbolify(mol, it):
    return map(lambda x: mol.symbols[x], it)

# initialize molecule from pdb
def setup(filename="ethane.pdb"):
    mol = Molecule.from_file(filename)

    # setup stuff
    mol.set_default_graph()
    mol.set_default_symbols()

    return mol

if __name__ == "__main__":
    # initialize molecule
    mol = setup("1IRA_R_B_clean.pdb")

    # all bonds of degree 3
    for bond in kth_bonds(mol, 3):
        # find the coordinates of the bonds
        bond_coor = list(map(lambda x: mol.coordinates[x], bond))

        # print symbols of bond and bond angle in degrees
        to_print = [bond]+symbolify(mol, bond)+[bend_angle(bond_coor)[0]/deg]
        pretty(to_print, "\t")

    # all bonds of degree 4
    for bond in kth_bonds(mol, 4):
        # find the coordinates of the bonds
        bond_coor = list(map(lambda x: mol.coordinates[x], bond))

        # print symbols of bond and dihed angle in degrees
        to_print = [bond]+symbolify(mol, bond)+[dihed_angle(bond_coor)[0]/deg]
        pretty(to_print, "\t")


#
# loss.py
# loss functions for RGBD-GAN
#

import torch
import torch.nn.functional as F
import numpy as np

from util.warp import warp, inv_warp, bilinear_sampling

def loss_gen_bce(y_fake):
    """
    loss function with binary cross entropy on generator
    """
    label_real = torch.ones_like(y_fake)
    loss = F.binary_cross_entropy_with_logits(y_fake, label_real, reduction='none')
    return loss

def loss_gen_wasserstein(y_fake):
    """
    loss function with wasserstein distance on generator
    """
    return -torch.mean(y_fake)

def loss_dis_bce(y_fake, y_real):
    """
    loss function with binary cross entropy on discriminator
    """
    label_fake = torch.zeros_like(y_fake)
    label_real = torch.ones_like(y_real)
    fake_loss = F.binary_cross_entropy_with_logits(y_fake, label_fake, reduction='none')
    real_loss = F.binary_cross_entropy_with_logits(y_real, label_real)

    return (torch.mean(fake_loss) + real_loss) / 2, real_loss, fake_loss

def loss_dis_wasserstein(y_fake, y_real):
    return (torch.mean(y_fake) + torch.mean(-y_real)) / 2

class Rotate3dLoss:
    """
    class for calculating 3d loss for two camera parameters' images
    """
    def __init__(self, K=None, norm='l1', lambda_geometric=3, device=torch.device('cuda')):
        self.size = None
        self.K = K
        self.inv_K = None
        self.norm = norm
        self.lambda_geometric = lambda_geometric
        self.p = None
        self.device = device

    def init_params(self, size=4):
        """
        initialize camera intrinsic parameter and image pixel homogeneous coordinate
        """
        # camera intrinsic parameter and inverse (3, 3)
        if self.size is None:
            if self.K is not None:
                self.K = torch.tensor(self.K[:3, :3], dtype=torch.float32)
                self.K[:2] *= size / self.K[0, 2] / 2
                self.size = size
            else:
                self.size = size
                self.K = torch.tensor([[size * 2, 0, size / 2], [0, size * 2, size / 2], [0, 0, 1]], dtype=torch.float32)
        else:
            self.size = size
            self.K[:2] *= size / self.K[0, 2] / 2

        self.K = self.K.to(self.device)
        self.inv_K = torch.linalg.inv(self.K)

        # homogeneous grid of image pixels (3, h * w)
        self.p = torch.tensor(np.asarray(
            np.meshgrid(np.arange(size), np.arange(size)) + [np.ones((size, size))]
        ).reshape(3, -1), dtype=torch.float32).to(self.device)

    def __call__(self, img_1, theta_1, img_2, theta_2, occlusion_aware=False, debug=False, max_depth=None, min_depth=None):
        """
        calculate 3d loss of image and warped image
        img : (b, 4, h, w) -> rgb and depth
        theta : (b, 3, 4) -> rotation and translation
        img_1 : theta_1 camera extrinsic parameter image
        img_2 : theta_2 camera extrinsic parameter image
        """
        # check image size
        if self.size != img_1.shape[-1]:
            self.init_params(size=img_1.shape[-1])

        # get depth from images
        # (b, 1, h, w) -> (b, 1, h * w)
        d_1 = img_1[:, -1:].reshape(img_1.shape[0], 1, -1)
        d_2 = img_2[:, -1:].reshape(img_2.shape[0], 1, -1)

        # if theta is not tensor type, change type to tensor
        if not isinstance(theta_1, torch.Tensor):
            theta_1 = torch.tensor(theta_1).to(self.device)
        if not isinstance(theta_2, torch.Tensor):
            theta_2 = torch.tensor(theta_2).to(self.device)

        # split rotation and translation from theta
        R1 = theta_1[:, :3, :3]
        R2 = theta_2[:, :3, :3]
        t1 = theta_1[:, :3, -1:]
        t2 = theta_2[:, :3, -1:]

        # calculate R and t between img_1 and img_2
        R = torch.matmul(R2.transpose(2, 1), R1)
        inv_R = R.transpose(2, 1)
        t = torch.matmul(R1.transpose(2, 1), t2 - t1)

        # img_1's depth * pixels projected from c2
        new_dp_1 = warp(self.K, self.inv_K, R, t, d_1, self.p)

        # img_2's depth * pixels projected from c1
        new_dp_2 = inv_warp(self.K, self.inv_K, inv_R, t, d_2, self.p)

        # use new_dp and image for bilinear sampling to warp RGBD image
        # warp img_2 to c1 using new_dp_1
        warped_1, not_out_1 = bilinear_sampling(img_2, new_dp_1)
        # warp img_1 to c2 using new_dp_2
        warped_2, not_out_2 = bilinear_sampling(img_1, new_dp_2)

        # make original target to calculate loss with warped one
        warped_1_target = torch.cat([img_1[:, :-1].permute(0, 2, 3, 1).reshape(-1, img_1.shape[1] - 1),
                                     new_dp_1[:, :, 2].reshape(-1, 1)], dim=1) * not_out_1[:, None]
        warped_2_target = torch.cat([img_2[:, :-1].permute(0, 2, 3, 1).reshape(-1, img_2.shape[1] - 1),
                                     new_dp_2[:, :, 2].reshape(-1, 1)], dim=1) * not_out_2[:, None]

        if occlusion_aware:
            # calculate occlusion
            not_occluded_1 = warped_1[:, -1:] > new_dp_1[:, :, 2].reshape(-1, 1)
            not_occluded_2 = warped_2[:, -1:] > new_dp_2[:, :, 2].reshape(-1, 1)
            warped_1 = warped_1 * not_occluded_1
            warped_2 = warped_2 * not_occluded_2
            warped_1_target = warped_1_target * not_occluded_1
            warped_2_target = warped_2_target * not_occluded_2

        if max_depth is not None:
            pass

        if min_depth is not None:
            pass

        # select loss type (l1 or l2)
        if self.norm == 'l1':
            criteria = F.l1_loss
        else:
            criteria = F.mse_loss

        # calculate 3d loss
        # loss between original rgb and warped rgb
        loss = criteria(warped_1[:, :-1], warped_1_target[:, :-1]) + criteria(warped_2[:, :-1], warped_2_target[:, :-1])
        # loss between projected depth and warped depth
        # hyperparameter as lambda_geometric
        loss += (criteria(warped_1[:, -1], warped_1_target[:, -1]) + criteria(warped_2[:, -1], warped_2_target[:, -1])) * self.lambda_geometric

        return loss, torch.cat([new_dp_1, new_dp_2], dim=0)


from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from django.forms.models import ModelForm
from django.utils.translation import gettext as _

from .models import Snippet

class SnippetCreateForm(ModelForm):

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

        for visible in self.visible_fields():
            visible.field.widget.attrs['class'] = 'crispy-form-item'
            visible.field.widget.attrs['spellcheck'] = 'false'

        self.fields['body'].widget.attrs['class'] += ' code-snippet'

    class Meta:
        model = Snippet
        fields = ('title', 'description', 'body', 'lang')

    helper = FormHelper()
    helper.add_input(Submit('submit', _('Create'),
                     css_class='btn-primary crispy-form-item'))


import json
import os
from pathlib import Path

import pytest

from never_worse_reduction.mdp import MDP
from never_worse_reduction.mdp_deserialise import read_mdp_from_simple_format_json

def get_test_root() -> Path:
    root_path = Path(__file__).parent

    return root_path

def get_test_input_mdp_by_name(mdp_name: str) -> MDP:
    """
        Given the name of a test input MDP, this function will return that MDP. The name of the MDP corresponds to the
        filename of the MDP json file in the "test_input_mdp" folder, without the .json extension.

    Parameters
    ----------
    mdp_name
        The name of the MDP

    Returns
    -------
    MDP
        The MDP.
    """

    return read_mdp_from_simple_format_json(get_test_root() / Path("test_files/test_input_mdp") / (mdp_name + ".json"))

def get_test_case_by_name(test_case_name: str) -> dict:
    """
        Retrieve the test case with the specified name from the "test_cases" folder.

    Parameters
    ----------
    test_case_name
        This is the filename of the JSON file without the '.json' extension.
    Returns
    -------
        A dict with the contents of the test case JSON file.

    """
    with open(get_test_root() / Path("test_files/test_cases") / (test_case_name + ".json"), 'r') as in_file:
        return json.load(fp=in_file)

def read_json_file(path: Path) -> dict:
    """
        Read the JSON file at the specified path.
    """
    with open(path, 'r') as in_file:
        return json.load(fp=in_file)

def get_labelled_states_from_mdp(mdp: MDP):
    """
        Retrieve the set of states of the specified MDP. Each state is encoded as a string label.
    """

    return mdp.get_state_labels_for_set(state_set=mdp.get_states())

def get_labelled_choices_from_mdp(mdp: MDP):
    """
        Retrieve the set of choices of the specified MDP. Each choice is encoded as a string label.
    """
    return mdp.get_choice_labels_for_set(choice_set=mdp.get_choices())

def get_labelled_forward_transitions_from_mdp(mdp: MDP) -> dict[str, set]:
    """
        Retrieve the forward transitions of the specified MDP. Each state or choice is encoded as a string label. The
        return value is a dict that maps each state or choice to its successors.
    """

    mdp_forward_transitions = dict()

    for state in mdp.get_states():
        state_label = mdp.get_state_label(state_id=state)

        labelled_choices = mdp.get_choice_labels_for_set(mdp.get_choices_for_state(state_id=state))

        mdp_forward_transitions[state_label] = labelled_choices

    for choice in mdp.get_choices():
        choice_label = mdp.get_choice_label(choice_id=choice)

        labelled_states = mdp.get_state_labels_for_set(mdp.get_successors_for_choice(choice_id=choice))

        mdp_forward_transitions[choice_label] = labelled_states

    return mdp_forward_transitions

def get_all_vertices_except_final_and_fail(mdp: MDP) -> set[int]:
    return set(mdp.get_vertices().difference({mdp.get_final_state(), mdp.get_fail_state()}))

def get_names_of_all_test_input_mdp_files() -> list[str]:
    """
        Retrieve a list of all MDPs in the "test_input_mdp" folder.
    """
    return [
        "almost_surely_reach_disconnected_graph",
        "almost_surely_reach_redundant_goals",
        "essential_set_disconnected_never_reaching",
        "essential_set_never_almost_surely_reaching",
        "essential_set_sometimes_almost_surely_reaching",
        "essential_singleton_nontrivial",
        "essential_singleton_trivial_all_nodes_are_essential",
        "extremal_and_mec_collapse_scenario_1_trivial",
        "extremal_and_mec_collapse_scenario_2_complex",
        "extremal_and_mec_collapse_scenario_3_complex",
        "extremal_five_iter_chain",
        "extremal_four_iter_chain",
        "extremal_one_iter_complex",
        "extremal_one_iter_simple_chain",
        "extremal_three_iter_chain",
        "extremal_three_iter_chain_double_connection",
        "extremal_two_iter_complex",
        "inference_almost_surely_reach",
        "inference_as_reach_2",
        "inference_fixpoint_non_trivial_1",
        "inference_fixpoint_trivial",
        "inference_old_essential",
        "inference_old_union_rule",
        "mdp_choice_prune_test_1",
        "mdp_choice_prune_test_2",
        "mdp_choice_prune_test_3",
        "mdp_choice_prune_test_4",
        "mdp_choice_prune_test_5",
        "mdp_choice_prune_test_6",
        "mdp_read_complex",
        "mec_get_scc_multiple",
        "mec_get_scc_no",
        "mec_get_scc_single",
        "mec_illegal_choices_all_illegal",
        "mec_illegal_choices_no_illegal",
        "mec_illegal_choices_some_illegal",
        "mec_multiple_iterations",
        "mec_simple_1_ashokEtAl",
        "mec_simple_2_ashokEtAl_altered",
        "mec_simple_3",
        "mec_simple_4",
        "under_approx_init_essential",
        "under_approx_init_trivial",
    ]


from decimal import Decimal

from leather.scales.base import Scale
from leather.ticks.score import ScoreTicker

class Linear(Scale):
    """
    A scale that linearly maps values from a domain to a range.

    :param domain_min:
        The minimum value of the input domain.
    :param domain_max:
        The maximum value of the input domain.
    """
    def __init__(self, domain_min, domain_max):
        if domain_min > domain_max:
            raise ValueError('Inverted domains are not currently supported.')
        elif domain_min == domain_max:
            # Default to unit scale
            self._data_min = Decimal(0)
            self._data_max = Decimal(1)
        else:
            self._data_min = Decimal(domain_min)
            self._data_max = Decimal(domain_max)

        self._ticker = ScoreTicker(self._data_min, self._data_max)

    def contains(self, v):
        """
        Return :code:`True` if a given value is contained within this scale's
        domain.
        """
        return self._data_min <= v <= self._data_max

    def project(self, value, range_min, range_max):
        """
        Project a value in this scale's domain to a target range.
        """
        value = Decimal(value)
        range_min = Decimal(range_min)
        range_max = Decimal(range_max)

        pos = (value - self._ticker.min) / (self._ticker.max - self._ticker.min)

        return ((range_max - range_min) * pos) + range_min

    def project_interval(self, value, range_min, range_max):
        """
        Project a value in this scale's domain to an interval in the target
        range. This is used for places :class:`.Bars` and :class:`.Columns`.
        """
        raise NotImplementedError

    def ticks(self):
        """
        Generate a series of ticks for this scale.
        """
        return self._ticker.ticks


import os
import sys
import re
from functools import partial
from operator import methodcaller
from collections import defaultdict

import argparse
import parsel
import parmap

from animeu.common.func_helpers import compose
from animeu.common.file_helpers import JSONListStream, open_transcoded
from animeu.spiders.xpath_helpers import get_all_text

MALE_PATTERNS = [r"\bhe\b", r"\bhis\b"]

def strip_field_name(text):
    """Strip the field name section from a piece of text.

    For example 'aka: bob' -> 'bob' or 'hair color: green' -> 'green'.
    """
    if not text:
        return None
    return re.sub(r"[^:]+:\s*", "", text)

def select_name(sel):
    """Select the element containing the characters name."""
    # pylint: disable=line-too-long
    return sel.xpath("//div[contains(@class, 'breadcrumb')]/following-sibling::div[1]")

def extract_en_jp_name(sel):
    """Extract the character's full name."""
    name_sel = select_name(sel)
    english_name = name_sel.css("::text").get().strip()
    japanese_name = get_all_text(name_sel.xpath("span")).strip("()")
    return {"en": [english_name], "jp": [japanese_name]}

def extract_info_fields_and_description(sel):
    """Extract the name-value info fields of the character."""
    name_sel = select_name(sel)
    # pylint: disable=line-too-long
    text_fragments = list(map(compose(methodcaller("strip"), methodcaller("get")),
                              name_sel.xpath("following-sibling::text() | "
                                             "following-sibling::b/text()")))
    text_fragments = list(filter(bool, text_fragments))
    info_key_to_fragments = defaultdict(list)
    current_key = None
    description_fragments = []
    # pylint: disable=invalid-name
    MAX_INFO_FIELD_FRAGMENT_LENGTH = 40
    MAX_WRITTEN_BY_LENGTH = 40
    for text_fragment in text_fragments:
        # pylint: disable=line-too-long
        if re.search(r"\b(written|from|source|author)\b", text_fragment, flags=re.I) and \
                len(text_fragment) <= MAX_WRITTEN_BY_LENGTH:
            continue
        if description_fragments and \
                len(text_fragment) > MAX_INFO_FIELD_FRAGMENT_LENGTH:
            description_fragments.append(text_fragment.strip())
            continue
        match = re.match(r"^(?P<key>[^:]{1,30}):\s*(?P<value>.*$)",
                         text_fragment)
        if not match and len(text_fragment) > MAX_INFO_FIELD_FRAGMENT_LENGTH:
            description_fragments.append(text_fragment.strip())
            continue
        if match:
            current_key = match.group("key").strip()
        if current_key:
            info_key_to_fragments[current_key].append(text_fragment.strip())
    return (
        [{"key": k, "value": "\n".join(v).strip()}
         for k, v in info_key_to_fragments.items()],
        "\n".join(description_fragments).strip() or None
    )

def extract_main_display_picture(sel):
    """Extract the main display picture URL of the character."""
    return sel.xpath("//a[contains(@href, 'pictures')]/img").attrib["src"]

def extract_anime_roles(sel):
    """Extract the animes the character appeared in."""
    anime_table = \
        sel.xpath("//div[text() = 'Animeography']/following-sibling::table[1]")
    roles = []
    for row in anime_table.xpath(".//tr"):
        image_sel, text_sel = row.xpath(".//td")
        picture = image_sel.xpath(".//img").attrib["src"]
        title = get_all_text(text_sel.xpath("./a"))
        role = get_all_text(text_sel.xpath("./div"))
        if re.search(r"main", role, flags=re.IGNORECASE):
            role = "main"
        elif re.search(r"support(ing)?|secondary", role, flags=re.IGNORECASE):
            role = "secondary"
        roles.append({"name": title, "picture": picture, "role": role})
    return roles

def extract_manga_roles(sel):
    """Extract the mangas the character appeared in."""
    anime_table = \
        sel.xpath("//div[text() = 'Mangaography']/following-sibling::table[1]")
    roles = []
    for row in anime_table.xpath(".//tr"):
        image_sel, text_sel = row.xpath(".//td")
        picture = image_sel.xpath(".//img").attrib["src"]
        title = get_all_text(text_sel.xpath("./a"))
        role = get_all_text(text_sel.xpath("./div"))
        if re.search(r"main", role, flags=re.IGNORECASE):
            role = "main"
        elif re.search(r"support(ing)?|secondary", role, flags=re.IGNORECASE):
            role = "secondary"
        roles.append({"name": title, "picture": picture, "role": role})
    return roles

def extract_gallery_pictures(sel):
    """Extract the pictures of the character from the gallery."""
    return sel.xpath("//div[@class = 'picSurround']//img/@src").getall()

def extract_metadata_from_file(filename):
    """Extract the metadata from a file."""
    # pylint: disable=broad-except
    try:
        metadata = {
            "sources": ["myanimelist"],
            "filenames": [filename],
            "names": {"en": [], "jp": []},
            "descriptions": [],
            "nicknames": {"en": [], "jp": []},
            "info_fields": [],
            "rankings": [],
            "tags": [],
            "anime_roles": [],
            "manga_roles": [],
            "pictures": {
                "display": [],
                "gallery": []
            }
        }
        profile_filename = filename
        pictures_filename = filename.replace(".html", ".pictures.html")
        if os.path.exists(profile_filename):
            with open_transcoded(filename, "r") as file_obj:
                profile_sel = parsel.Selector(text=file_obj.read().decode("utf8"))
            metadata["names"] = extract_en_jp_name(profile_sel)
            metadata["pictures"]["display"].append(
                extract_main_display_picture(profile_sel)
            )
            metadata["anime_roles"].extend(extract_anime_roles(profile_sel))
            metadata["manga_roles"].extend(extract_manga_roles(profile_sel))
            info_fields, maybe_description = \
                extract_info_fields_and_description(profile_sel)
            metadata["info_fields"].extend(info_fields)
            if maybe_description:
                metadata["descriptions"].append(maybe_description)
        if os.path.exists(pictures_filename):
            with open_transcoded(pictures_filename, "r") as file_obj:
                pictures_sel = parsel.Selector(text=file_obj.read().decode("utf8"))
            metadata["pictures"]["gallery"].extend(
                extract_gallery_pictures(pictures_sel)
            )
        return metadata
    except Exception as ex:
        print(f"Error occured processing: {filename}: {ex}", file=sys.stderr)
        return None

def test_is_male_character(metadata):
    """Test if a character is male."""
    # pylint: disable=invalid-name
    for info_field in metadata["info_fields"]:
        if re.search(r"sex", info_field["key"], flags=re.I) and \
                re.search(r"\b(male|men|man)\b", info_field["value"], flags=re.I):
            return True
    return False

def main(argv=None):
    """Entry point to the myanimelist extractor."""
    argv = argv or sys.argv[1:]
    parser = argparse.ArgumentParser("""Extract content from anime pages.""")
    parser.add_argument("--pages-directory",
                        metavar="PAGES",
                        type=str,
                        required=False)
    parser.add_argument("--output",
                        metavar="OUTPUT",
                        type=argparse.FileType("w", encoding="utf8"),
                        default=sys.stdout)
    parser.add_argument("--no-parallel",
                        action="store_true",
                        help="""Disable parallel processing.""")
    result = parser.parse_args(argv)
    basenames = \
        set(f for f in os.listdir(result.pages_directory) if
            not (f.endswith(".anime.html") or f.endswith(".pictures.html")))
    filenames = \
        list(map(partial(os.path.join, result.pages_directory), basenames))
    with JSONListStream(result.output) as extract_file:
        for metadata in parmap.map(extract_metadata_from_file,
                                   filenames,
                                   pm_pbar=True,
                                   pm_parallel=not result.no_parallel,
                                   pm_chunksize=10):
            if not metadata:
                continue
            if test_is_male_character(metadata):
                print(f"Skipping {metadata['filenames']} as it is a male "
                      f"character.",
                      file=sys.stderr)
                continue
            extract_file.write(metadata)
            result.output.flush()


from flask import Flask, render_template, request, session
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

from config import Config
from models import db

from log_req import logined

app = Flask(__name__)
app.config.from_object(Config)

db.init_app(app)
migrate = Migrate(app, db)

from api import bp as api_bp

@app.route('/')
@logined
def game():
	return render_template('index.html', name = session.get('username'))

@app.route('/login', methods = ['GET', 'POST'])
def login():
	if request.method == 'POST':

		name = request.json.get('name')
		session['log'] = True
		session['username'] = name
	return render_template('login.html')

app.register_blueprint(api_bp, url_prefix = '/api')

if __name__ == '__main__':
	app.run(debug = True, port=4000)


import json
import os
from typing import Union

__all__ = ["Settings"]

class SettingsClass:
	def __init__(self,file_location:Union[str,os.PathLike]) -> None:
		self._file_location = file_location
		self._autosave = True
		try:
			open(self._file_location,"x")
			open(self._file_location,"w").write("{}")
		except FileExistsError: pass
		# self._file_handler = open(self._file_location,"r+") # we don't want it getting fucked with while we're working with it
		try:
			with open(self._file_location,"r") as file: settings:dict = json.load(file)
		except json.JSONDecodeError:
			open(self._file_location,"w").write("{}")
			settings = {}
		self._autosave = False
		self.redirect_uri:str = settings.get("redirect_uri","http://127.0.0.1:9090")
		self.client_id:str = settings.get("client_id","")
		self.client_secret:str = settings.get("client_secret","")
		self.added_songs:int = settings.get("added_songs",90)
		self._autosave = True

	def __setattr__(self, __name: str, __value) -> None:
		super().__setattr__(__name,__value)
		if __name[0] == "_" or not self._autosave:
			return
		with open(self._file_location,"r") as file: settings:dict = json.load(file)
		settings.update({k:v for k,v in self.__dict__.items() if k[0] != "_"})
		settings[__name] = __value
		with open(self._file_location,"w") as file: json.dump(settings,file,indent=4)

	def __repr__(self) -> str:
		repr_str = f"<SettingsClass: "
		for key in self:
			repr_str += f"{key}={repr(self.__dict__[key])}, "
		repr_str += f"_file_location={repr(self._file_location)}>"
		return repr_str

	def __iter__(self):
		for i in self.__dict__.keys():
			if i[0] == "_": continue
			yield i

	def __getitem__(self,item):
		if item[0] != "_":
			return self.__dict__[item]
		raise KeyError(repr(item))

	def __setitem__(self,key,value):
		self.__setattr__(key,value)

Settings = SettingsClass("settings.json")

def assert_default_settings(settings:SettingsClass):
	assert settings.added_songs == 90
	assert settings.client_id == ""
	assert settings.client_secret == ""
	assert settings.redirect_uri == "http://127.0.0.1:9090"

def main():
	# i wrote this function because I wanted to feel productive while doing nothing productive at all
	# it did end up making the code a little less shit but not in any meaningful way
	"""
	resets your settings and performs some code tests
	"""
	f = "settings.json"

	# test __init__ from a corrupted state
	with open(f,"w") as file: file.write("{")
	Settings = SettingsClass(f)
	assert_default_settings(Settings)

	# test __init__ from a non-blank state
	Settings = SettingsClass(f)
	assert_default_settings(Settings)

	# test __init__ from a blank state
	os.remove(f)
	Settings = SettingsClass(f)
	assert_default_settings(Settings)

	# test __setattr__
	Settings.added_songs = 45
	assert Settings.added_songs == 45 # seems stupid but considering we do fuck with the __setattr__ function I believe it is a good test

	# test __iter__
	assert 'added_songs' in Settings
	assert '_file_location' not in Settings

	# test __repr__
	print(Settings) # tell me if it looks good, that's about all I can say

	# test __getitem__
	assert Settings['added_songs'] == 45
	try: # can't assert that an error will happen but we can error if it does
		Settings['_file_location']
		raise AssertionError
	except KeyError: pass

	Settings.added_songs = 90 # assuming everything else went well this will set it back to the default value

if __name__ == "__main__":
	main()


## https://leetcode.com/problems/range-sum-query-2d-mutable/

from typing import List

class NumMatrix:
    matrix = []
    R, C = 0, 0

    def __init__(self, matrix: List[List[int]]):
        self.matrix = matrix
        self.R, self.C = len(matrix), len(matrix[0])

        self.partial_sum = [[] for _ in range(self.R)]
        for row in range(self.R):
            for col in range(self.C):
                if col == 0:
                    self.partial_sum[row].append(matrix[row][0])
                else:
                    self.partial_sum[row].append(self.partial_sum[row][-1] + matrix[row][col])

        # for row in range(self.R):
        #     print(self.partial_sum[row])

    def update(self, row: int, col: int, val: int) -> None:
        pre_val = self.matrix[row][col]
        self.matrix[row][col] = val
        diff = val - pre_val
        for c in range(col, self.C):
            self.partial_sum[row][c] += diff

        # for r in range(self.R):
        #     print(self.partial_sum[r])

        return

    def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
        result = 0
        for r in range(row1, row2 + 1):
            if col1 == 0:
                result += self.partial_sum[r][col2]
            else:
                result += self.partial_sum[r][col2] - self.partial_sum[r][col1 - 1]

        # print(result)

        return result

# Your NumMatrix object will be instantiated and called as such:
# obj = NumMatrix(matrix)
# obj.update(row,col,val)
# param_2 = obj.sumRegion(row1,col1,row2,col2)

obj = NumMatrix([[3, 0, 1, 4, 2], [5, 6, 3, 2, 1], [1, 2, 0, 1, 5], [4, 1, 0, 1, 7], [1, 0, 3, 0, 5]])
obj.sumRegion(2,1,4,3)
obj.update(3,2,2)
obj.sumRegion(2,1,4,3)