import os
from domain.department import Department
from domain.patient import Patient
from infrastucture.hospital import HospitalRepo
import frontend.ui as UI

dep_repo = HospitalRepo([
    [1,'Dep a',5,[Patient('John','Doe',20,'891273891','cancer'),Patient('Bob','Dough',18,'12890831','covid-19')]],
    [2,'Dep b',5,[]],
    [3,'Dep c',5,[]],
    [4,'Dep d',6,[]],
    [5,'Dep e',6,[]],
    ])

def read_department():
    """
    Reads the values of a department from the console.
    """
    name_valid = False
    capacity_valid = False

    depid = int(input('Enter the department id: '))
    while dep_repo.is_valid_id(depid):
        print('Department id already exists.')
        depid = int(input('Enter the department id: '))

    while not name_valid:
        name = input("Enter the name: ")
        if name == "":
            print("The name id cannot be empty.")
        else:
            name_valid = True
            dep_name = name

    while not capacity_valid:
        cap = int(input("Enter the capacity: "))
        if cap == "" or type(cap) != int:
            print("The name id cannot be empty.")
        else:
            capacity_valid = True
            dep_cap = cap

    vec = Department(depid, dep_name, dep_cap, [])
    return vec

def read_patient():
    """
    Reads the values of a patient from the console.
    """
    first_valid = False
    last_valid = False
    age_valid = False
    cnp_valid = False
    disease_valid = False

    while not first_valid:
        name = input("Enter the first name: ")
        if name == "":
            print("The name id cannot be empty.")
        else:
            first_valid = True
            first_name = name

    while not last_valid:
        name = input("Enter the last name: ")
        if name == "":
            print("The name id cannot be empty.")
        else:
            last_valid = True
            last_name = name

    while not age_valid:
        name = int(input("Enter the age: "))
        if name == "":
            print("The age id cannot be empty.")
        else:
            age_valid = True
            age = name

    while not cnp_valid:
        name = input("Enter the CNP: ")
        if name == "":
            print("The name id cannot be empty.")
        else:
            cnp_valid = True
            cnp = name

    while not disease_valid:
        name = input("Enter the disease: ")
        if name == "":
            print("The name id cannot be empty.")
        else:
            disease_valid = True
            disease = name

    vec = Patient(first_name,last_name,age,cnp,disease)
    return vec

def input_valid_index():
    """
    Checks if the index is valid.
    """
    index_valid = False
    while not index_valid:
        index = int(input("Enter the index: "))
        if index < 0 or index >= len(dep_repo):
            print("Invalid index")
        else:
            index_valid = True
            return index
    return

while(True):
    """
    Loop the menu and wait for an input
    """
    UI.print_menu()
    option = ''
    try:
        option = int(input('Enter your choice: '))
    except:
        print('Wrong input. Please enter a number ...')
    #Check what choice was entered and act accordin gly
    os.system('cls||clear')

    if option == 0:
        print('Exiting.')
        exit()
    elif option == 1:
        aux = read_department()
        dep_repo += aux
    elif option == 2:
        print(dep_repo)
    elif option == 3:
        if dep_repo.amount != 0:

                depid = int(input('Enter the department id: '))
                while not dep_repo.is_valid_id(depid):
                    print('Invalid department id')
                    depid = int(input('Enter the department id: '))
                aux = read_patient()
                dep_repo.add_patient(depid,aux)

        else:
            print('The list is empty')

    elif option == 4:
        if dep_repo.amount != 0:
            index = int(input('Enter the index: '))
            while not dep_repo.is_index_valid(index):
                print('Invalid index')
                index = int(input('Enter the index: '))
            dep_repo.sort_patient_by_age(index)
            print(dep_repo.departments[index])
            #FIXME: Print the sorted results
        else:
            print('The list is empty')
    else:
        print('Invalid option. Please enter a valid option.')


from utils import hex_string_to_bytearray, xor
from utils import alpha_and_printable_heuristic
from single_byte_xor_cipher import xor_cipher, brute_force_xor
from operator import itemgetter

def brute_force_messages(messages, heuristic_func):
    for message in messages:
        yield from brute_force_xor(message, heuristic_func)

def detect_xor_cipher(messages, heuristic_func):
    candidates = brute_force_messages(messages, heuristic_func)
    return max(candidates, key=itemgetter(0))

def main():
    with open("4.txt", 'r') as f: lines = f.readlines()
    hex_lines = [l.replace("\n", "") for l in lines]
    ciphertexts = [hex_string_to_bytearray(i) for i in hex_lines]

    score, message, key = detect_xor_cipher(ciphertexts, alpha_and_printable_heuristic)
    print("challenge 1.4 message: %s" % message)

if __name__ == '__main__':
    main()


import logging
import os

from metrics import Metric

class MediaMetric(Metric):
  """MediaMetric class injects and calls JS responsible for recording metrics.

  Default media metrics are collected for every media element in the page,
  such as decoded_frame_count, dropped_frame_count, decoded_video_bytes, and
  decoded_audio_bytes.
  """

  def __init__(self, tab):
    super(MediaMetric, self).__init__()
    with open(os.path.join(os.path.dirname(__file__), 'media.js')) as f:
      js = f.read()
      tab.ExecuteJavaScript(js)
    self._results = None
    self._skip_basic_metrics = False

  def Start(self, page, tab):
    """Create the media metrics for all media elements in the document."""
    if hasattr(page, 'skip_basic_metrics'):
      self._skip_basic_metrics = page.skip_basic_metrics
    tab.ExecuteJavaScript('window.__createMediaMetricsForDocument()')

  def Stop(self, page, tab):
    self._results = tab.EvaluateJavaScript('window.__getAllMetrics()')

  def AddResults(self, tab, results):
    """Reports all recorded metrics as Telemetry perf results."""
    trace_names = []
    for media_metric in self._results:
      trace_names.append(self._AddResultsForMediaElement(media_metric, results))

    return '_'.join(trace_names) or tab.url

  def _AddResultsForMediaElement(self, media_metric, results):
    """Reports metrics for one media element.

    Media metrics contain an ID identifying the media element and values:
    media_metric = {
      'id': 'video_1',
      'metrics': {
          'time_to_play': 120,
          'decoded_bytes': 13233,
          ...
      }
    }
    """
    def AddOneResult(metric, unit):
      metrics = media_metric['metrics']
      for m in metrics:
        if m.startswith(metric):
          special_label = m[len(metric):]
          if isinstance(metrics[m], list):
            values = [float(v) for v in metrics[m]]
          else:
            values = float(metrics[m])
          results.Add(trace + special_label, unit, values,
                      chart_name=metric, data_type='default')

    trace = media_metric['id']
    if not trace:
      logging.error('Metrics ID is missing in results.')
      return

    if not self._skip_basic_metrics:
      AddOneResult('buffering_time', 'ms')
      AddOneResult('decoded_audio_bytes', 'bytes')
      AddOneResult('decoded_video_bytes', 'bytes')
      AddOneResult('decoded_frame_count', 'frames')
      AddOneResult('dropped_frame_count', 'frames')
      AddOneResult('time_to_play', 'ms')

    AddOneResult('avg_loop_time', 'ms')
    AddOneResult('seek', 'ms')
    return trace


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

# arguments define
import argparse

# load torch
import torchvision

# other utilities
# import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.metrics import confusion_matrix
#%% Load the training data
def MNIST_DATASET_TRAIN(downloads, train_amount):
    # Load dataset
    training_data = torchvision.datasets.MNIST(
              root = './mnist/',
              train = True,
              transform = torchvision.transforms.ToTensor(),
              download = downloads
              )

    #Convert Training data to numpy
    train_data = training_data.train_data.numpy()[:train_amount]
    train_label = training_data.train_labels.numpy()[:train_amount]

    # Print training data size
    print('Training data size: ',train_data.shape)
    print('Training data label size:',train_label.shape)
    # plt.imshow(train_data[0])
    # plt.show()

    train_data = train_data/255.0

    return train_data, train_label

#%% Load the test data
def MNIST_DATASET_TEST(downloads, test_amount):
    # Load dataset
    testing_data = torchvision.datasets.MNIST(
              root = './mnist/',
              train = False,
              transform = torchvision.transforms.ToTensor(),
              download = downloads
              )

    # Convert Testing data to numpy
    test_data = testing_data.test_data.numpy()[:test_amount]
    test_label = testing_data.test_labels.numpy()[:test_amount]

    # Print training data size
    print('test data size: ',test_data.shape)
    print('test data label size:',test_label.shape)
    # plt.imshow(test_data[0])
    # plt.show()

    test_data = test_data/255.0

    return test_data, test_label

#%% Main function for MNIST dataset
if __name__=='__main__':

    # Training Arguments Settings
    parser = argparse.ArgumentParser(description='Saak')
    parser.add_argument('--download_MNIST', default=True, metavar='DL',
                        help='Download MNIST (default: True)')
    parser.add_argument('--train_amount', type=int, default=60000,
                        help='Amount of training samples')
    parser.add_argument('--test_amount', type=int, default=2000,
                        help='Amount of testing samples')
    args = parser.parse_args()

    # Print Arguments
    print('\n----------Argument Values-----------')
    for name, value in vars(args).items():
        print('%s: %s' % (str(name), str(value)))
    print('------------------------------------\n')

    # Load Training Data & Testing Data
    train_data, train_label = MNIST_DATASET_TRAIN(args.download_MNIST, args.train_amount)
    test_data, test_label = MNIST_DATASET_TEST(args.download_MNIST, args.test_amount)

    training_features = train_data.reshape(args.train_amount,-1)
    test_features = test_data.reshape(args.test_amount,-1)

    # Training SVM
    print('------Training and testing SVM------')
    clf = svm.SVC(C=5, gamma=0.05,max_iter=10)
    clf.fit(training_features, train_label)

    #Test on test data
    test_result = clf.predict(test_features)
    precision = sum(test_result == test_label)/test_label.shape[0]
    print('Test precision: ', precision)

    #Test on Training data
    train_result = clf.predict(training_features)
    precision = sum(train_result == train_label)/train_label.shape[0]
    print('Training precision: ', precision)

    #Show the confusion matrix
    matrix = confusion_matrix(test_label, test_result)


import xml.etree.ElementTree as ET
import pandas as pd
import subprocess

def get_qualified_name(project):
    """
    Returns the qualified suffix name for the project
    :param project: the project
    :return: the qualified name
    """
    d = {'cassandra': 'org.apache.cassandra',
         'dagger': 'dagger',
         'guava': 'com.google.common',
         'ivy': 'org.apache.ivy',
         'lang': 'org.apache.commons.lang',
         'math': 'org.apache.commons.math',
         'time': 'org.joda.time'}
    return d[project]

def parse_xml(path='metrics/jdepend/dagger.xml', project='dagger'):
    """
    Parses the xml resulting from the jdepend xml output and output the result as a frame;
    deletes also the intermediate xml
    :param path: the path for the xml file
    :param project: the project under analysis
    :return: a pandas DataFrame
    """

    tree = ET.parse(path)
    root = tree.getroot()
    packages = root.find('Packages')

    # columns of the final dataframe
    project_list = []
    Ca_list = []
    Ce_list = []
    A_list = []
    I_list = []
    D_list = []
    V_list = []
    class_list = []

    for package in packages:

        if package.attrib['name'] and package.attrib['name'].startswith(get_qualified_name(project)):
            classes = [x.text.strip() for x in package.iter('Class')]
            l = len(classes)
            project_list.extend([project] * l)
            class_list.extend(classes)

            Ca_list.extend([float(next(package.iter('Ca')).text)] * l)
            Ce_list.extend([float(next(package.iter('Ce')).text)] * l)
            A_list.extend([float(next(package.iter('A')).text)] * l)
            I_list.extend([float(next(package.iter('I')).text)] * l)
            D_list.extend([float(next(package.iter('D')).text)] * l)
            V_list.extend([float(next(package.iter('V')).text)] * l)
    output = pd.DataFrame({'project': project_list,
                           'class': class_list,
                           'Ca': Ca_list,
                           'Ce': Ce_list,
                           'A': A_list,
                           'I': I_list,
                           'D': D_list,
                           'V': V_list})
    output.to_csv('metrics/jdepend/{}.csv'.format(project), index=False)
    command = 'rm -rf metrics/jdepend/{}.xml'.format(project)
    delete = subprocess.run(command.split(), stderr=subprocess.PIPE)
    if delete.returncode != 0:
        print('error')

if __name__ == '__main__':
    parse_xml()


'''
Smallish example for what appears to be a pygraphviz runtime error
'''

from pygraphviz import AGraph

# this works well:

dd = AGraph(name = "test", compound = "true", directed = "true", newrank = "true")
dd.add_node("a", shape = "point")
dd.add_node("b", shape = "point")
dd.add_subgraph(["a", "b"], name = 'cluster_a_b')

# but a similar thing on an inheriting class raises an error upon the subgraph call:

class D(AGraph):

    def __init__(self):
        super().__init__(name = "test", compound = "true", directed = "true", newrank = "true")
        # alternative, same outcome:
        # AGraph.__init__(self, name = "test", compound = "true", directed = "true", newrank = "true")
        self.add_node("a", shape = "point")
        self.add_node("b", shape = "point")
        self.add_subgraph(["a", "b"], name = 'cluster_a_b')
        self.add_node("c", shape = "point")
        self.add_edge("c",'cluster_a_b')
        self.add_node("d", shape = "point")
d = D()


from sklearn.linear_model import LogisticRegression
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import pandas as pd

# Irisデータセットをロード
iris = datasets.load_iris()
# 3,4列目の特徴量を抽出
X = iris.data[:, [2, 3]]
# クラスらラベルを取得
y = iris.target
# 一意なクラスラベルを出力
# print('Class labels:', np.unique(y))

from sklearn.model_selection import train_test_split
# 訓練データとテストデータに分割：全体の30％をテストデータにする
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 1, stratify = y)

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
# 訓練データの平均と標準偏差を計算
sc.fit(X_train)
# 平均と標準偏差を用いて標準化
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)

def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02):

    # マーカーとカラーマップの準備
    markers = ('o','s','^','v','<')
    colors = ('red','blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    # 決定領域のプロット
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))

    # 各特徴量を1次元配列に変換して予測を実行
    lab = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    # 予測結果を元のグリッドポイントのデータサイズに変換
    lab = lab.reshape(xx1.shape)
    # グリッドポイントの等高線をプロット
    plt.contourf(xx1, xx2, lab, alpha=0.3, cmap=cmap) #軸の範囲の設定
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    # クラスごとに訓練データをプロット
    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0],
                    y=X[y == cl, 1],
                    alpha=0.8,
                    c=colors[idx],
                    marker=markers[idx],
                    label=f'Class {cl}',
                    edgecolor='black')
    # テストデータ点を目立たせる（点を◯で表示）
    if test_idx:
        # すべてのデータ点プロット
        X_test, y_test = X[test_idx, :], y[test_idx]
        plt.scatter(X_test[:, 0], X_test[:, 1], c='none', edgecolor='black',
                    alpha=1.0, linewidth=1, marker='o', s=100, label='Test set')

# ロジスティック回帰のインスタンスを生成
lr = LogisticRegression(C=100.0, solver='lbfgs', multi_class='ovr')
# 訓練データをモデルに適合させる
lr.fit(X_train_std, y_train)

# 訓練データとテストデータの特徴量を行方向に結合
X_combined_std = np.vstack((X_train_std, X_test_std))
# 訓練データとテストデータのクラスラベルを結合
y_combined = np.hstack((y_train, y_test))

# # 決定領域をプロット
# plot_decision_regions(X_combined_std, y_combined, classifier=lr, test_idx=range(105,150))
# plt.xlabel('Petal length [standardized]') # 軸ラベルを設定
# plt.ylabel('Petal width [standardized]')
# plt.legend(loc='upper left') # 凡例を設定
# plt.tight_layout()
# plt.show()

# print(lr.predict_proba(X_test_std[:3,:]))
# print(lr.predict_proba(X_test_std[:3,:]).argmax(axis=1))
# print(lr.predict(X_test_std[:3,:]))
# print(lr.predict(X_test_std[0,:].reshape(1,-1)))

weights, params = [], [] # 重み係数と逆正則化パラメータのリストを生成
# 10個の逆正則化パラメータに対応するロジスティック回帰モデルを処理
for c in np.arange(-5, 5):
    lr = LogisticRegression(C=10.**c, multi_class='ovr')
    lr.fit(X_train_std, y_train)
    weights.append(lr.coef_[1]) # 重み係数を格納
    params.append(10.**c) # 逆正則化パラメータを格納

weights = np.array(weights) #重み係数をNumpy配列に変換
# 横軸に逆正則化パラメータ、縦軸に重み係数をプロット
plt.plot(params, weights[:, 0], label='Petal length')
plt.plot(params, weights[:, 1], linestyle='--', label='Petal width')
plt.ylabel('Weight coefficient')
plt.xlabel('C')
plt.legend(loc='upper left')
plt.xscale('log') #横軸を対数スケールに設定
plt.show()


class Solution:
    def numEnclaves(self, grid: List[List[int]]) -> int:
        row=len(grid)
        col=len(grid[0])
        visit=[[False]*col for i in range(row)]
        m1=[0,-1,0,1]
        m2=[1,0,-1,0]
        count=0
        def dfs(visit,r,c,grid):
            visit[r][c]=True
            for new in range(4):
                newrow=r+m1[new]
                newcol=c+m2[new]
                if newrow>=0 and newcol<col and newcol>=0 and newrow<row and not visit[newrow][newcol] and grid[newrow][newcol]==1:
                    dfs(visit,newrow,newcol,grid)
        for i in range(row):
            for j in range(col):
                if (i==0 or j==0 or j==col-1 or i==row-1) and grid[i][j]==1:
                    visit[i][j]=True
                    dfs(visit,i,j,grid)
        for i in range(row):
            for j in range(col):
                if not visit[i][j] and grid[i][j]==1:
                    count+=1
        return count


#!/user/bin/python

'''Longest Common Subsequence of Two Sequences

Compute the length of a longest common subsequence of two sequences. A
subsequence is a sequence that appears in the same relative order, but not
necessarily contiguous order in both strings.

i.e.
x: ABCBDAB
y: BDCABA

LC subsequences:
1. BDAB
2. BCAB
3. BCBA

Bottom Up Dynamic Programming - Iterative LCS:

    int lcs_length(char * A, char * B)
    {
	allocate storage for array L;
	for (i = m; i >= 0; i--)
	    for (j = n; j >= 0; j--)
	    {
		if (A[i] == '\0' || B[j] == '\0') L[i,j] = 0;
		else if (A[i] == B[j]) L[i,j] = 1 + L[i+1, j+1];
		else L[i,j] = max(L[i+1, j], L[i, j+1]);
	    }
	return L[0,0];
    }

'''

import sys

def lcs2(a, b):
    # generate matrix of longest common substrings
    len_array = [[0 for i in range(len(b)+1)] for j in range(len(a)+1)]
    for i, x in enumerate(a):
        for j, y in enumerate(b):
            if x == y:
                len_array[i+1][j+1] = len_array[i][j] + 1
            else:
                len_array[i+1][j+1] = max(len_array[i+1][j], len_array[i][j+1])

    result = ''
    j = len(b)
    for i in range(1, len(a)+1):
        if len_array[i][j] != len_array[i-1][j]:
            result += a[i-1]

    return result
    #write your code here
    #return min(len(a), len(b))

if __name__ == '__main__':
    input = sys.stdin.read()
    data = list(map(int, input.split()))

    n = data[0]
    data = data[1:]
    a = data[:n]

    data = data[n:]
    m = data[0]
    data = data[1:]
    b = data[:m]

    print(lcs2(a, b))


# Explore Coriolis Argo oxygen data
# Plot temporal and spatial distributions of this data

import xarray as xr
import glob

argo_dir = '/home/hourstonh/Documents/climatology/oxy_clim/Coriolis_Argo/'
argo_files = glob.glob(argo_dir + '*.nc')

argo = argo_files[0]

argodat = xr.open_dataset(argo)

# Some key variable names:
# LATITUDE, LONGITUDE, DOXY_ADJUSTED, N_PROF (number of profiles), JULD (Julian day in UTC)
# JULD same as JULD_LOCATION ??

# JULD in numpy.datetime64 format

# Plot spatial distribution

argodat.close()


from django.conf.urls import url

from portelaGerenciador.core.views import home, cadastro_usuario, sucesso_usuario,cadastro_produtos,sucesso_produto

urlpatterns = [
    url(r'^$', home, name='home'),
    url(r'^cadastro-usuario/$', cadastro_usuario, name='cadastrousuario'),
    url(r'^sucesso-usuario/$', sucesso_usuario, name='usuariosucesso'),
    url(r'^cadastro-produto/$',cadastro_produtos, name='cadastroproduto'),
    url(r'^sucesso-produto/$',sucesso_produto, name='sucessoproduto'),
]


# --- IMPORTS ---
from datetime import datetime, timedelta
import joblib
import numpy as np
import pandas as pd
import yfinance as yf
from flask import Flask, render_template
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, PolynomialFeatures
from tensorflow.keras.models import load_model

# --- MODEL LOADING ---
def load_models():
    return {
        'lin_reg': joblib.load('models/lin_reg.joblib'),
        'poly_reg': joblib.load('models/poly_reg.joblib'),
        'default_lasso': joblib.load('models/default_lasso.joblib'),
        'tuned_lasso': joblib.load('models/tuned_lasso.joblib'),
        'default_ridge': joblib.load('models/default_ridge.joblib'),
        'tuned_ridge': joblib.load('models/tuned_ridge.joblib'),
        'cnn_model': load_model('models/cnn'),
        'lstm_model': load_model('models/lstm')
    }

# --- DATA PREPARATION ---
def fetch_data():
    return yf.Ticker("TSLA").history(period="max")

def prepare_data(stock_data):
    x = stock_data.index.values
    y = stock_data['Close'].values
    return train_test_split(x, y, test_size=1/5)

# --- PREDICTION FUNCTIONS ---
def predict_regressor(model, y_train, train_features, next_date_features):

    model.fit(train_features, y_train)
    regressor_pred = model.predict(next_date_features)[0]

    return round(regressor_pred, 2)

def predict_cnn(model, y):

    X_recent = y[-1:].reshape(1, 1, 1)  # Reshape to (samples, timesteps, features) for LSTM
    cnn_pred = model.predict(X_recent)[0][0]

    return round(cnn_pred, 2)

def predict_lstm(model, y):

    N = 30  # This is the offset, or the number of days of data the LSTM model expects as input
    scaler = MinMaxScaler(feature_range=(0, 1))
    last_N_days = y[-N:]
    last_N_days_scaled = scaler.fit_transform(last_N_days.reshape(-1, 1))
    X_recent_lstm = last_N_days_scaled.reshape(1, N, 1)
    predicted_scaled_price = model.predict(X_recent_lstm)

    # Inverse transform the prediction to get the actual stock price
    lstm_pred = scaler.inverse_transform(predicted_scaled_price)[0][0]

    return round(lstm_pred, 2)

models = load_models()

def get_predictions():

    stock_data = fetch_data()
    x = stock_data.index.values
    y = stock_data['Close'].values
    x_train, _, y_train, _ = prepare_data(stock_data)

    # For regression classifiers
    last_date = x[-1].astype('int64') // 1e9
    last_date_datetime = datetime.utcfromtimestamp(last_date)
    next_date_datetime = last_date_datetime + timedelta(days=1)
    next_date_timestamp = np.array([[pd.Timestamp(next_date_datetime).value]])
    print(f"Date of the next stock price we'll be predicting: {next_date_datetime}")

    lin = PolynomialFeatures(degree=1, include_bias=False)
    train_linear_features = lin.fit_transform(x_train.reshape(-1, 1))
    next_date_linear_features = lin.transform(next_date_timestamp)

    poly = PolynomialFeatures(degree=16, include_bias=False)
    train_poly_features = poly.fit_transform(x_train.reshape(-1, 1))
    next_date_poly_features = poly.transform(next_date_timestamp)

    # Fit and predict for Default Ridge
    ridge = PolynomialFeatures(degree=5, include_bias=False)
    train_ridge_features = ridge.fit_transform(x_train.reshape(-1, 1))
    next_date_ridge_features = ridge.transform(next_date_timestamp)

    return {
        'predictions': {
            'Linear Regression': predict_regressor(models['lin_reg'], y_train, train_linear_features, next_date_linear_features),
            'Polynomial Regression': predict_regressor(models['poly_reg'], y_train, train_poly_features, next_date_poly_features),
            'Default LASSO': predict_regressor(models['default_lasso'], y_train, train_poly_features, next_date_poly_features),
            'Tuned LASSO': predict_regressor(models['tuned_lasso'], y_train, train_poly_features, next_date_poly_features),
            'Default Ridge': predict_regressor(models['default_ridge'], y_train, train_ridge_features, next_date_ridge_features),
            'Tuned Ridge': predict_regressor(models['tuned_ridge'], y_train, train_ridge_features, next_date_ridge_features),
            'Convolutional Neural Network': predict_cnn(models['cnn_model'], y),
            'LSTM': predict_lstm(models['lstm_model'], y)
            # ... call the functions for other models
        },
        'next_date': next_date_datetime.strftime("%m/%d/%Y")
    }

# --- FLASK SETUP ---
app = Flask(__name__)

@app.route('/')
def index():
    result = get_predictions()
    return render_template('index.html', predictions=result['predictions'], next_date=result['next_date'])

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


from utils import *
from torch.distributions import Normal
import torch
import torch.nn as nn
import torch.nn.functional as F

class PPOModel(nn.Module):
    def __init__(self, state_dim, action_dim, hidden_dim1=128, hidden_dim2=128):
        super(PPOModel, self).__init__()
        self.actor_mean = nn.Sequential(
            nn.Linear(state_dim, hidden_dim1),
            nn.ReLU(),
            nn.Linear(hidden_dim1, hidden_dim2),
            nn.ReLU(),
            nn.Linear(hidden_dim2, action_dim),
            nn.Tanh()
        )
        self.actor_var = nn.Sequential(
            nn.Linear(state_dim, hidden_dim1),
            nn.ReLU(),
            nn.Linear(hidden_dim1, hidden_dim2),
            nn.ReLU(),
            nn.Linear(hidden_dim2, action_dim),
            nn.Sigmoid()
        )
        self.critic = nn.Sequential(
            nn.Linear(state_dim, hidden_dim1),
            nn.ReLU(),
            nn.Linear(hidden_dim1, hidden_dim2),
            nn.ReLU(),
            nn.Linear(hidden_dim2, 1)
        )

    def forward(self, x):
        raise NotImplementedError

    def act(self, x):
        return self.actor_mean(x), self.actor_var(x)

    def evaluate(self, x):
        return self.critic(x)

class PPOAgent(object):
    def __init__(self, state_dim, action_dim, memory, args):
        self.device = torch.device('cuda:' + str(args.device) if torch.cuda.is_available() else 'cpu')
        print(self.device)
        self.gamma = args.gamma
        self.eps_clip = args.eps_clip
        self.n_updates = args.n_updates
        self.policy = PPOModel(state_dim, action_dim).to(self.device)
        self.optimizer = torch.optim.Adam(self.policy.parameters(), lr=args.lr)
        self.policy_old = PPOModel(state_dim, action_dim).to(self.device)
        self.policy_old.load_state_dict(self.policy.state_dict())
        self.criterion = nn.MSELoss()
        self.memory = memory

    def select_action(self, state):
        state_ = torch.from_numpy(state).to(self.device)
        # calculate the action based on the old policy wrt \theta_old
        action_mean, action_var = self.policy_old.act(state_)
        dist = Normal(action_mean, action_var)
        action = torch.clamp(dist.sample(), -1, 1 - state[0])
        action_logprob = dist.log_prob(action)
        # restore the state, actions, log_prob into the memory
        self.memory.states.append(state_)
        self.memory.actions.append(action)
        self.memory.logprobs.append(action_logprob)
        return action.detach().cpu().data.numpy().flatten()

    def evaluate_action(self, state, action):
        # calculate the action based on the policy wrt \theta
        action_mean, action_var = self.policy.act(state)
        dist = Normal(action_mean, action_var)
        action_logprob = dist.log_prob(action)
        dist_entropy = dist.entropy()
        state_value = self.policy.evaluate(state)
        return action_logprob, torch.squeeze(state_value), dist_entropy

    def update(self):
        rewards = []
        discounted_reward = 0
        for reward, done in zip(reversed(self.memory.rewards), reversed(self.memory.done)):
            if done:
                discounted_reward = 0
            discounted_reward = reward + (self.gamma * discounted_reward)
            rewards.insert(0, discounted_reward)

        rewards = torch.tensor(rewards, dtype=torch.float32).to(self.device)
        rewards = ((rewards - rewards.mean()) / (rewards.std() + 1e-5))

        old_states = torch.squeeze(torch.stack(self.memory.states).to(self.device), 1).detach()
        old_actions = torch.squeeze(torch.stack(self.memory.actions).to(self.device), 1).detach()
        old_logprobs = torch.squeeze(torch.stack(self.memory.logprobs).to(self.device), 1).detach()

        for i in range(self.n_updates):
            logprobs, state_values, dist_entropy = self.evaluate_action(old_states, old_actions)
            ratios = torch.exp(logprobs - old_logprobs.detach())

            advantages = rewards - state_values.detach()
            surr1 = ratios * advantages
            surr2 = torch.clamp(ratios, 1 - self.eps_clip, 1 + self.eps_clip) * advantages
            loss = -torch.min(surr1, surr2) + 0.5 * self.criterion(state_values, rewards) - 0.01 * dist_entropy

            self.optimizer.zero_grad()
            loss.mean().backward()
            self.optimizer.step()

        self.policy_old.load_state_dict(self.policy.state_dict())


import cmath
import numpy.ma
import sys
import matplotlib.pyplot as plt
from objs import *
import math
import copy
"""
This is the utility file for the calculator, nearly all features are kept and maintained here. it includes:
tokenizer(expression)
findNeg(token list)
fixmult(token list)
check(token list)
toReversePolish(token list)
getPrecedence(token data)
calculate(token list, value)
get_function(token)
graph(token_list, xmin,xmax)
isnum(number)
treeify(token list)
infix_traversal(postfix tree)
expression(token list)
collapse(token list)
list_to_string(token list)
derivative(postfix tree)
"""
def tokenizer(expression, lst = [],flag = True):
    """
    Recursive algorithm that takes a input string and converts it into a list of tokens, thus making processing easier.
    :param expression: Input string
    :param lst: keeps track of current list of tokens produced
    :param flag: Solution to scope issues do to default arguments being global, there may be a more elegant solution to
    be found later.
    :return: List of tokens
    """
    if lst !=[] and flag:
        lst = [SOF()]
    elif lst == []:
        lst = [SOF()]
    if expression[:1].isdigit() or expression[:1] == ".":
        i = 0
        while len(expression) !=i and (expression[i].isdigit() or expression[i] == "."):
            i += 1
        if i == 0:
            i = 1
        if len(expression) !=i:
            try:
                tok = num(float(expression[:i]))
            except ValueError:
                print(expression[:1] + " is not a number, quitting now...")
                sys.exit()
        else:
            try:
                tok = num(float(expression))
            except ValueError:
                print(expression + " is not a number, quitting now...")
                sys.exit()
        lst.append(tok)
        return tokenizer(expression[i:],lst,False)

    elif expression[:1] in ["+","-","*","/","^"]:
        tok = oper(expression[0])
        lst.append(tok)
        return tokenizer(expression[1:],lst,False)

    elif expression[:1] == "(":
        lst.append(leftparen())
        return tokenizer(expression[1:],lst,False)

    elif expression[:1] == ")":
        lst.append(rightparen())
        return tokenizer(expression[1:], lst,False)

    elif expression[:1] == 'x':
        lst.append(var())
        return tokenizer(expression[1:],lst,False)

    elif expression[:1].isalpha():
        i = 1
        while expression[i].isalpha():
            i += 1
        tok = expr(expression[:i])
        lst.append(tok)
        return tokenizer(expression[i:],lst,False)
    elif expression[:1] == "":
        lst.append(EOF())
        return lst
def findNeg(toks):
    """
    Due to my processing, a negative symbol looks the same as a minus sign. This converts any oper("-") into
    [leftparen(),num(-l),oper("*"),num(NUMBER TO BE MADE NEGATIVE),rightparen()] so long as another oper preceeds in and
    a number or var follows it.
    :param toks: Token list
    :return: Adjusted token list
    """
    lst = []
    for i in range(len(toks)):

        if type(toks[i]) is oper:
            if toks[i].data == "-" and ((type(toks[i-1]) is SOF or type(toks[i-1]) is oper or type(toks[i-1]) is leftparen) and (type(toks[i+1]) is num or type(toks[i+1]) is var)):
                lst.append(i)
    lst.sort(reverse=True)
    for j in lst:
        toks.insert(j+1,leftparen())
        toks.insert(j+2,num(-1))
        toks.insert(j+3,oper("*"))
        toks.insert(j+5,rightparen())
        toks.pop(j)

    return toks[1:]
def fixmult(toks):
    """
    Adjusts the token list so that all instance of "Nx" where N is a number, is replaced with N*x
    :param toks: token list
    :return: adjusted token list
    """
    lst =[]
    for i in range(len(toks)):
        if type(toks[i]) is num and (type(toks[i+1]) is var or type(toks[i+1]) is expr or type(toks[i+1]) is leftparen):
            lst.append(i)
    lst.sort(reverse=True)
    for i in lst:
        toks.insert(i+1,oper("*"))
    return toks
def check(toks):
    """
    Validates input to make sure it is mathematically valid, will throw an error if the input is invalid
    :param toks: token list
    :return: None
    """
    if not type(toks[-1]) is EOF:
        raise TypeError("EOF not at end.")
    for i in range(len(toks)):
        if type(toks[i]) is num:
            tempbool = type(toks[i+1]) is EOF or type(toks[i+1]) is rightparen or type(toks[i+1]) is oper
            if not tempbool:
                raise NameError("Invalid Syntax, num must be followed by EOF, right parenthesis, or an operation")
            if i!=0:
                tempbool = type(toks[i-1]) is oper or type(toks[i-1]) is leftparen
            if not tempbool:
                raise NameError("Invalid Syntax, num must be preceeded by operation or left parenthesis or Start of File")
        elif type(toks[i]) is oper:

            tempbool = type(toks[i+1]) is num or type(toks[1+i]) or type(toks[i+1]) is leftparen or type(toks[i+1]) is var
            if not tempbool:
                raise NameError("Invalid Syntax, operation must be followed by number, expression, or a variable")
            if i == 0:
                raise NameError("Synatax Error, cannot start expression with operation")
            else:
                tempbool = type(toks[i-1]) is num or type(toks[i-1]) is rightparen or type(toks[i-1]) is var
            if not tempbool:
                raise NameError("Invalid Syntax, operation must be preceeded by number, expression, or variable")
        elif type(toks[i]) is var:
            tempbool = type(toks[i + 1]) is EOF or type(toks[i + 1]) is rightparen or type(toks[i + 1]) is oper
            if not tempbool:
                raise NameError("Invalid Syntax, variable must be followed by EOF, right parenthesis, or an operation")
            if i != 0:
                tempbool = type(toks[i - 1]) is oper or type(toks[i-1]) is leftparen
            if not tempbool:
                raise NameError("Invalid Syntax, variable must be preceeded by operation or left parenthesis Or Start of File")
        elif type(toks[i]) is expr:
            tempbool = type(toks[i + 1]) is leftparen
            if not tempbool:
                raise NameError("Invalid Syntax, expression must be followed by left parenthesis")
            if i!=0:
                tempbool = type(toks[i-1]) is oper or type(toks[i-1]) is leftparen
            if not tempbool:
                raise NameError("Invalid syntax, expression preceeded by operation or left parenthesis or Start of File")
        elif type(toks[i]) is leftparen:
            k = -1
            j = i+1
            while k !=0:
                if type(toks[j]) is EOF:
                    raise RuntimeError("Reached end of expression while parsing")
                if type(toks[j]) is leftparen:
                    k -=1
                if type(toks[j]) is rightparen:
                    k +=1
                j+=1
            tempbool = type(toks[i+1]) is num or type(toks[i+1]) is expr or type(toks[i+1]) is var or type(toks[i+1]) is leftparen
            if not tempbool:
                raise NameError(" Invalid syntax, Left Parenthesis cannot be followed by an operation or End Of File")
            if i !=0:
                tempbool = type(toks[i-1]) is oper or type(toks[i-1]) is expr or type(toks[i-1]) is leftparen
            if not tempbool:
                raise NameError("Invalid syntax, Left Parenthesis can only be preceeded by an operation, expression, or Start of File")
        elif type(toks[i]) is rightparen:
            k = -1
            j = i -1
            while k != 0:
                if j ==len(toks):
                    raise RuntimeError("No left parenthesis to pair")
                if type(toks[j]) is leftparen:
                    k += 1
                if type(toks[j]) is rightparen:
                    k -= 1
                j-=1
            tempbool = type(toks[i + 1]) is EOF or type(toks[i + 1]) is rightparen or type(toks[i + 1]) is oper
            if not tempbool:
                raise NameError("Invalid Syntax, right parenthesis must be followed by EOF, right parenthesis, or an operation")
            if i != 0:
                tempbool = type(toks[i - 1]) is num or type(toks[i-1]) is var or type(toks[i-1]) is rightparen
            if not tempbool:
                raise NameError("Invalid syntax, Right Parenthesis can only be preceeded by an operation, expression, or Start of File")
    return toks
def toReversePolish(toks):
    """
    Uses the Shunting Yard algorithm to covert a infix list of tokens into a postfix string of tokens.
    :param toks: infix token list
    :return: postfix token list
    """
    Queue = queue()
    Stack = stack()
    lst = []
    for tok in toks:
        if type(tok) is num or type(tok) is var:
            Queue.enqueue(tok)
        elif type(tok) is expr:
            Stack.push(tok)
        elif type(tok) is oper:
            if not Stack.top is None:
                while type(Stack.top.data) is oper:
                    if (tok.data in ["-","+","*","/"] and getPrecedence(tok.data) <= getPrecedence(Stack.top.data.data)) or (tok.data == "^" and getPrecedence(tok.data) < getPrecedence(Stack.top.data.data)):
                        Queue.enqueue(Stack.top.data)
                        Stack.pop()
                        if Stack.is_empty():
                            break
                    else:
                        break
            Stack.push(tok)
        elif type(tok) is leftparen:
            Stack.push(tok)
        elif type(tok) is rightparen:
            if not Stack.is_empty():
                while not type(Stack.top.data) is leftparen:
                    Queue.enqueue(Stack.top.data)
                    Stack.pop()
                    if Stack.is_empty():
                        break
            Stack.pop()
            if not Stack.is_empty():
                if type(Stack.top.data) is expr:
                    Queue.enqueue(Stack.top.data)
                    Stack.pop()

        elif type(tok) is EOF:
            if not Stack.top is None:
                while type(Stack.top.data) is oper:
                    Queue.enqueue(Stack.top.data)
                    Stack.pop()
                    if Stack.top is None:
                        break
    while not Queue.is_empty():
        lst.append(Queue.front.data)
        Queue.dequeue()
    return lst
def getPrecedence(operator):
    """
    Returns the precedence for operators for use in toReversePolish(), where high numbers represent greater precedence
    :param operator: operator token data
    :return: number representing the precedence of the given operator
    """
    if operator == "^":
        return 3
    elif operator in ["*","/"]:
        return 2
    elif operator in ["+","-"]:
        return 1
def calculate(toks,val=0):
    """
    Calculates an inputted value of a postfix formatted list of tokens.
    :param toks: Postfix token list
    :param val: Input for token list
    :return: Result
    """
    for tok in toks:
        if type(tok) is var:
            tok.data = val
    my_stack = stack()
    for tok in toks:
        if type(tok) is num or type(tok) is var:
            my_stack.push(tok)
        elif type(tok) is oper:
            if tok.data == '+':
                num1 = my_stack.top.data.data
                my_stack.pop()
                num2 = my_stack.top.data.data
                my_stack.pop()
                my_stack.push(num(num1+num2))
            if tok.data == '-':
                num1 = my_stack.top.data.data
                my_stack.pop()
                num2 = my_stack.top.data.data
                my_stack.pop()
                my_stack.push(num(num2-num1))
            if tok.data == '*':
                num1 = my_stack.top.data.data
                my_stack.pop()
                num2 = my_stack.top.data.data
                my_stack.pop()
                my_stack.push(num(num1*num2))
            if tok.data == '/':
                num1 = my_stack.top.data.data
                my_stack.pop()
                num2 = my_stack.top.data.data
                my_stack.pop()
                try:
                    my_stack.push(num(num2/num1))
                except ZeroDivisionError:
                    return numpy.ma.masked
            if tok.data == '^':
                num1 = my_stack.top.data.data
                my_stack.pop()
                num2 = my_stack.top.data.data
                my_stack.pop()
                my_stack.push(num(num2**num1))
        elif type(tok) is expr:
            num1 = my_stack.top.data.data
            my_stack.pop()
            my_stack.push(num(get_function(tok,num1)))
    return my_stack.top.data.data
def get_function(tok,val):
    """
    Lookup and calculation function for different possible functions.
    :param tok: expr token
    :param val: input value to tok
    :return: result
    """
    if tok.data == "sin":
        if type(val) is float or type(val) is int:
            return round(math.sin(float(val)),4)
        elif type(val) is complex:
            return cmath.sin(val)
    if tok.data == "cos":
        if type(val) is float or type(val) is int:
            return round(math.cos(float(val)),4)
        elif type(val) is complex:
            return cmath.cos(val)
    if tok.data == "tan":
        if type(val) is float or type(val) is int:
            return round(math.tan(float(val)),4)
        elif type(val) is complex:
            return cmath.tan(val)
    if tok.data == "sec":
        if type(val) is float or type(val) is int:
            return round(1/(math.cos(float(val))),4)
        elif type(val) is complex:
            return 1/(cmath.cos(val))
    if tok.data == "csc":
        if type(val) is float or type(val) is int:
            return round(1/(math.sin(float(val))),4)
        elif type(val) is complex:
            return 1/(cmath.sin(val))
    if tok.data == "cot":
        if type(val) is float or type(val) is int:
            return round(1/(math.tan(float(val))),4)
        elif type(val) is complex:
            return 1/(cmath.tan(val))
    if tok.data == "arccos":
        if type(val) is float or type(val) is int:
            return round(math.acos(float(val)),4)
        elif type(val) is complex:
            return cmath.acos(val)
    if tok.data == "arcsin":
        if type(val) is float or type(val) is int:
            return round(math.asin(float(val)),4)
        elif type(val) is complex:
            return cmath.asin(val)
    if tok.data == "arctan":
        if type(val) is float or type(val) is int:
            return round(math.atan(float(val)),4)
        elif type(val) is complex:
            return cmath.atan(val)
    if tok.data == "ln":
        if (type(val) is float or type(val) is int) and val > 0:
            return round(math.log(float(val)),4)
        elif type(val) is complex or val <=0:
            return cmath.log(val)
    if tok.data == "sqrt":
        if (type(val) is float or type(val) is int) and val > 0:
            return round(math.sqrt(float(val)),4)
        elif type(val) is complex or val<=0:
            return cmath.sqrt(val)
    else:
        raise NameError("Function does not exist in lookup table, please add for functionality")

def graph(func,minimum,maximum):
    """
    Graphs a function represented by a postfix list of tokens
    :param func: Function to graph
    :param minimum: x minimum
    :param maximum: y maximum
    :return: None
    """
    count = minimum
    y = []
    while count <= maximum:
        y.append(count)
        count+=.001
    count = minimum
    x = []
    while count <= maximum:
        try:
            x.append(calculate(func,count))
        except ValueError or TypeError:
            x.append(numpy.ma.masked)
        count+=.001
    y = numpy.ma.array(y)
    x = numpy.ma.array(x)
    plt.plot(y,x)
    plt.axhline(0, color='black')
    plt.axvline(0, color='black')
    plt.show()
def isnum(num):
    """
    Returns true if the inputted argument can be converted into a float or int
    :param num:
    :return: Boolean value
    """
    try:
        float(num)
    except ValueError:
        return False
    return True

def treeify(toks,count = 0):
    """
    Turns a postfix list of tokens into a tree, POSTFIX LIST MUST BE REVERSED FOR PROCESSING
    :param toks: Token list to be turned into a tree
    :param count: Keeps track of where to make the next branch of the tree.
    :return: Postfix Tree
    """
    if type(toks[0]) is num or type(toks[0]) is var:
        return tree(toks[0]),count
    if type(toks[0]) is expr:
        temp = expr_tree(toks[0])
        child,count =treeify(toks[1:],count)
        temp.add(child)
        count+=1
        return temp,count
    temp = tree(toks[0])
    right,count = treeify(toks[1+count:])
    left,count = treeify(toks[2+count:])
    count+=2
    temp.add(right)
    temp.add(left)
    return temp,count
def infix_traversal(my_tree):
    """
    Performs an infix traversal of an postfix tree.
    :param my_tree: Postfix tree
    :return: Infix list of tokens
    """
    if type(my_tree) is tree:
        if my_tree.left is None:
            return expression([my_tree.node])
        temp = expression([infix_traversal(my_tree.left),my_tree.node,infix_traversal(my_tree.right)])
        temp1 = []
        for i in temp:
            if type(i) is list:
                temp1 += i
            else:
                temp1 +=[i]
        return temp1
    else:
        if my_tree.child is None:
            return
        temp = expression([my_tree.node,infix_traversal(my_tree.child)])
        return temp
def expression(lst):
    """
    Adds wrapping left and right parenthesis to a token list.
    :param lst: Input list
    :return: Wrapped list
    """
    temp = [leftparen()]
    temp1 = [rightparen()]
    return temp + lst + temp1
def collapse(lst):
    """
    Removes all sublists from a list while keeping their values
    :param lst: List to be collapsed.
    :return: List
    """
    temp = []
    for i in lst:
        if type(i) is list:
            temp +=collapse(i)
        else:
            temp +=[i]
    return temp
def list_to_string(lst):
    """
    Converts an infix token list into an infix string
    :param lst: token list
    :return: Infix string
    """
    temp = ""
    for i in lst:
        if type(i) is var:
            temp += "x"
        elif type(i) is num or type(i) is oper or type(i) is expr:
            temp += str(i.data)
        elif type(i) is leftparen:
            temp += "("
        elif type(i) is rightparen:
            temp += ")"
    return temp
def derivative(my_tree):
    """
    Recursive algorithm to calculate the analytical derivative of a function from a postfix tree. A simplifying algorithm
    still needs to be written to make the output more fit for human use, but is effective for the computational uses
    within this program. This feature is still in development, but it's mostly bug free.
    :param my_tree: Postfix tree
    :return: Infix list of tokens representing the derivative of the function.
    """
    if type(my_tree.node) is num:
        temp = num(0)
        return expression([temp])
    elif type(my_tree.node) is var:
        temp = num(1)
        return expression([temp])
    elif type(my_tree.node) is oper:
        if my_tree.node.data == "+":
            temp = [oper("+")]
            return expression([derivative(my_tree.left)] + temp +[derivative(my_tree.right)])
        elif my_tree.node.data == "-":
            temp = [oper("-")]
            return expression([derivative(my_tree.left)] + temp + [derivative(my_tree.right)])
        elif my_tree.node.data == "*":
            temp = [oper("*")]
            temp1 = [oper("+")]
            return expression(expression(expression([derivative(my_tree.left)]) + temp + expression([infix_traversal(my_tree.right)]))) + temp1 + expression(expression(expression([derivative(my_tree.right)]) + temp + expression([infix_traversal(my_tree.left)])))
        elif my_tree.node.data == "/":
            temp = [oper("*")]
            temp1 = [oper("-")]
            temp2 = [oper("/")]
            temp3 = [oper("^")] + [num(2)]
            return expression(expression(expression(expression([derivative(my_tree.left)]) + temp + expression([infix_traversal(my_tree.right)])) + temp1 + expression(expression([derivative(my_tree.right)]) + temp + expression([infix_traversal(my_tree.left)]))) + temp2 + expression([infix_traversal(my_tree.right)]) + temp3)
        elif my_tree.node.data == "^":
            temp = [oper("*")]
            temp1 = [oper("+")]
            temp2 = [oper("/")]
            return infix_traversal(my_tree) + temp + expression(expression(expression(expression([derivative(my_tree.left)])+ temp2 + expression(infix_traversal(my_tree.left))) + temp + infix_traversal(my_tree.right)) + temp1 + expression([expr("ln")] + infix_traversal(my_tree.left) + temp + [derivative(my_tree.right)]))
    elif type(my_tree.node) is expr:
        if my_tree.node.data == "sin":
            temp = [oper("*")]
            temp1 = [expr("cos")]
            return expression(expression([derivative(my_tree.child)]) + temp + expression(temp1 + expression([infix_traversal(my_tree.child)])) )
    if my_tree.node.data == "cos":
        temp = [oper("*")]
        temp1 = [num(-1),oper("*")]
        temp2 = [expr("sin")]
        return expression(temp1 + [derivative(my_tree.child)]) + temp + temp2 + expression(infix_traversal(my_tree.child))
    if my_tree.node.data == "tan":
        temp = [oper("*")]
        temp1 = [expr("sec")]
        temp2 = [oper("^")] + [num(2)]
        return expression([derivative(my_tree.child)]) + temp + expression(expression([temp1 + expression([infix_traversal(my_tree.child)])])+temp2)
    if my_tree.node.data == "sec":
        temp = [oper("*")]
        temp1 = [expr("sec")]
        temp2 = [expr("tan")]
        return expression([derivative(my_tree.child)]) + temp + expression(expression([temp1 + expression([infix_traversal(my_tree.child)])])+ temp +expression(temp2 + expression([infix_traversal(my_tree.child)])))
    if my_tree.node.data == "csc":
        temp = [oper("*")]
        temp1 = [expr("cot")]
        temp2 = [expr("csc")]
        temp3 = [num(-1),oper("*")]
        return expression([derivative(my_tree.child)]) + temp + expression(temp3 +expression([temp1 + expression([infix_traversal(my_tree.child)])])+ temp +expression(temp2 + expression([infix_traversal(my_tree.child)])))
    if my_tree.node.data == "cot":
        temp = [oper("*")]
        temp1 = [expr("csc")]
        temp2 = [oper("^")] + [num(2)]
        temp3 = [num(-1),oper("*")]
        return expression([derivative(my_tree.child)]) + temp + expression(temp3 +expression(expression([temp1 + expression([infix_traversal(my_tree.child)])])+temp2))
    if my_tree.node.data == "arcsin":
        temp = [oper("/")]
        temp1 = [expr("sqrt")]
        temp2 = [num(1),oper("-")]
        temp3 = [oper("^"),num(2)]
        return [derivative(my_tree.child)] + temp + expression(temp1 + expression(temp2 + expression([infix_traversal(my_tree.child)] + temp3)))
    if my_tree.node.data == "arccos":
        temp = [oper("/")]
        temp1 = [expr("sqrt")]
        temp2 = [num(1),oper("-")]
        temp3 = [oper("^"),num(2)]
        temp4 = [num(-1),oper("*")]
        return temp4 + expression([derivative(my_tree.child)] + temp + expression(temp1 + expression(temp2 + expression([infix_traversal(my_tree.child)] + temp3))))
    if my_tree.node.data == "arctan":
        temp = [oper("/")]
        temp1 = [num(1),oper("+")]
        temp2 = [oper("^"),num(2)]
        return [derivative(my_tree.child)] + temp + expression(temp1 + expression([infix_traversal(my_tree.child)] + temp2))
    if my_tree.node.data == "ln":
        temp = [oper("/")]
        return derivative(my_tree.child) + temp + infix_traversal(my_tree.child)
    if my_tree.node.data == "sqrt":
        temp = [num(.5),oper("*")]
        temp1 = [oper("*")]
        temp2 = [oper("^"),num("-.5")]
        return temp + expression(derivative(my_tree.child)) + temp1 + expression(infix_traversal(my_tree.child)+temp2)
def format_list(toks):
    """
    Coverts a list of tokens from derivative into a useable list for calculations
    :param toks: token list
    :return: Postfix formatted derivative
    """
    toks = collapse(toks)
    toks = list_to_string(toks)
    print(toks)
    toks = findNeg(tokenizer(toks))
    toks = toReversePolish(toks)
    return toks


from django.shortcuts import render
from django.views import View
from SysProj.settings import DATABASES
from Products.models import Product
# Create your views here.

class ViewAllDB(View):
    def get(self, request, slug):
        db = request.user.databases
        return render(request, 'alldb.html', context ={"data": [ key for key in db ] })

class CreateProduct(View):
    def get(self, request, slug):
        return render(request, 'create_product.html' , context = {"db":slug})

    def post(self, request, slug):
        data = request.POST
        user_id = request.user.id
        print('user_id',user_id)
        Product.objects.using(slug).create( name = data['name'], price = data['price'], unit = data['unit'])
        return render(request, 'create_product.html' , context = {"db":slug})

class AllProduct(View):
    def get(self, request):
        db1 = Product.objects.using('database1').all()
        db2 = Product.objects.using('database2').all()
        db3 = Product.objects.using('database3').all()
        db4 = Product.objects.using('database4').all()
        db5 = Product.objects.using('database5').all()

        data = {
            "database1":db1,
            "database2":db2,
            "database3":db3,
            "database4":db4,
            "database5":db5,
        }

        return render(request, 'all_product.html', context = data)


from tkinter import *

def bt_click():

    if(str(ed1.get()).isnumeric() and (str(ed2.get())).isnumeric()):
        n1 = float(ed1.get())
        n2 = float(ed2.get())
        lb["text"] = n1*n2
    else:
        lb['text'] = 'Valores informados são invalidos'

janela = Tk()
janela.title('Janela Principal')
janela["bg"] = "red"
janela["background"] = "blue"
#LxA+E+T
#300x300+100+100
janela.geometry("800x300+100+100")

ed1 = Entry(janela)
ed1.place(x=100, y=100)
ed2 = Entry(janela)
ed2.place(x=100, y=130)

bt = Button(janela, width=20, text='Ok', command=bt_click)
bt.place(x=100, y=150)
lb = Label(janela, text='')
lb.place(x=100, y=200)

janela.mainloop()


"""
Created on Wed 24 Mar 15:37:43 GMT 2021.

@author: sejmodha
"""

import joblib
import argparse
import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
from sklearn import metrics
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import confusion_matrix
from sklearn.calibration import CalibratedClassifierCV
from sklearn.metrics import brier_score_loss
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import KFold

np.random.seed(235487)

"""Functions for prokaryotic sequence prediction models."""

def set_vars():
    """Set var_list required for the module."""
    parser = argparse.ArgumentParser(description='This script can be used to train new random forest models')
    parser.add_argument('-i', '--infile', help='Input a comma separated data file (.csv)', required=True)
    parser.add_argument('-n', '--indexColumn', help='Specify index column name (default = "id")', required=False, default='id')
    parser.add_argument('-y', '--targetColumn', help='Specify target/label column name (default = "class")', required=False, default='class')
    parser.add_argument('-t', '--threads', help='Specify number of threads (default = 2)', required=False, default=2, type=int)
    parser.add_argument('-o', '--outputPrefix', help='Specify an output prefix', required=False)
    parser.add_argument('-path', '--modelpath', help='Provide locations to model files (default = models/)', required=False, default='models')
    parser.add_argument('-cv', '--crossvalidation', help='Cross-validation generator (default = 5)', required=False, default=5, type=int)

    args = parser.parse_args()

    datafile = args.infile
    index_column = args.indexColumn
    target_column = args.targetColumn
    cpu = args.threads
    path = args.modelpath
    out = args.outputPrefix
    cv = args.crossvalidation

    df = pd.read_csv(datafile, index_col=index_column)

    return (df, target_column, cpu, out, path, cv)

def get_train_test(input_df, label_col, test_size, k, n_features):
    """Generate train/test set for each class."""
    train_test_dict = {}
    for i in sorted(input_df[label_col].unique()):
        # print(i)
        try:
            pos_df = input_df[input_df[label_col] == i].drop(columns=[label_col])
            pos_df[i] = 1
            # print(pos_df.shape)
            # print(pos_df.head())
            neg_df = input_df[input_df[label_col] != i].sample(n=pos_df.shape[0]).drop(columns=[label_col])
            neg_df[i] = 0
            # print(neg_df.shape)
            # print(neg_df.head())
            data_df = pd.concat([pos_df, neg_df]).sample(frac=1)
            # print(data_df.shape)
            # get X and Y
            X = data_df.iloc[:, 0:n_features]
            y = data_df.iloc[:, n_features]
            X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=0)
            train_test_dict[i] = [X_train, X_test, y_train, y_test, X, y]
            # print(X_train.shape)
            # print(X_test.shape)
            # print(y_train.shape)
            # print(y_test.shape)
        except(ValueError):
            print('Please make sure that data contains positive and negative datapoints for each class.\n')

    return train_test_dict

def get_best_model(X, y, cpu):
    """Run GriSearchCV to identity the best model parameters."""
    for i in y.columns:
        rfc = RandomForestClassifier(random_state=123, n_estimators=100, class_weight='balanced', bootstrap=False)
        steps = [('scaler', StandardScaler()), ('rf', rfc)]
        pipe = Pipeline(steps)
        params = [{'rf__bootstrap': [True, False],
                   'rf__n_estimators': [50, 100, 150, 200, 300, 400, 500],
                   'rf__criterion': ['gini', 'entropy']}]
        gs = GridSearchCV(pipe, params, scoring='f1', n_jobs=cpu)
        gs_clf = gs.fit(X, y[i])
        best_params = gs_clf.best_params_
        best_pipe = gs_clf.best_estimator_
        rf_clf = best_pipe.named_steps.rf
        model = best_pipe

        print(model, rf_clf)

def train_models_rfc(data_dict, out, path, cpu, cv):
    """Run the Random forest classifier and saves models."""
    for k, v in data_dict.items():
        print(f'Building ML models for {k}')
        X_train, X_test, y_train, y_test, X, y = v

        rfc = RandomForestClassifier(n_estimators=1000, class_weight='balanced', bootstrap=True, n_jobs=cpu)

        rfc.fit(X_train, y_train)
        y_pred_rfc = rfc.predict(X_test)
        y_pred_proba_rfc = rfc.predict_proba(X_test)
        print('====================================================')
        print('Raw random forest classifier results below:')
        print('====================================================')
        print(f'Model accuracy is: {metrics.accuracy_score(y_test, y_pred_rfc)}')
        print(metrics.classification_report(y_test, y_pred_rfc))
        titles_options = [("Confusion matrix, without normalization: "+k, None),
                          ("Normalized confusion matrix: "+k, 'true')]
        for title, normalise in titles_options:
            print(title)
            print(confusion_matrix(y_test, y_pred_rfc, normalize=normalise))

        # Try calibrating the classifiers

        clf_sigmoid = CalibratedClassifierCV(rfc, method='sigmoid', n_jobs=cpu, cv=cv)
        clf_sigmoid.fit(X_train, y_train)

        y_pred_proba_sigmoid = clf_sigmoid.predict_proba(X_test)

        print("Brier scores: (smaller is better)")

        clf_score = brier_score_loss(y_test, y_pred_proba_rfc[:, 1])
        print("No calibration: %1.3f" % clf_score)

        clf_sigmoid_score = brier_score_loss(y_test, y_pred_proba_sigmoid[:, 1])
        print("With sigmoid calibration: %1.3f" % clf_sigmoid_score)
        print('====================================================')
        print('Sigmoid calibrated pipeline results below:')
        print('====================================================')
        y_pred_sigmoid = clf_sigmoid.predict(X_test)

        print(f'Model accuracy is: {metrics.accuracy_score(y_test, y_pred_sigmoid)}')
        print(metrics.classification_report(y_test, y_pred_sigmoid))
        for title, normalise in titles_options:
            print(title)
            print(confusion_matrix(y_test, y_pred_sigmoid, normalize=normalise))
        print('====================================================')
        print(f'{cv}-fold Cross validations performed below')
        print('====================================================')
        kfold = KFold(n_splits=cv)
        results_kfold = cross_val_score(rfc, X, y, cv=kfold)
        print(results_kfold)
        print("Accuracy: %.2f%%" % (results_kfold.mean()*100.0))

        # save the model to disk
        if out is None:
            filename = f'{path}/rfc_{k}.model'
        else:
            filename = f'{path}/{out}_{k}.model'
        print(f'\nSaving calibrated model. \nModel is saved in: {filename}\n')
        joblib.dump(clf_sigmoid, filename, compress=3)
        # save non-calibrated model below
        # joblib.dump(rfc, filename, compress=3)
        plt.close('all')
    return

def main():
    """Run the module as a script."""
    df, target_column, cpu, out, path, cv = set_vars()
    data_dict = get_train_test(df, target_column, 0.3, 4, 256)

    train_models_rfc(data_dict, out, path, cpu, cv)

if __name__ == "__main__":
    main()


import numpy as np
from matplotlib import pyplot as plt
from src.synthetic_functions import y_exp2
from src.kernels import get_non_linear_input_dependent_kernel
from src.regression.gpar_regression import GPARRegression
from src.regression.igp_regression import IGPRegression
from exp.noise_structure.utils import plot_noise, \
    get_split_outputs, get_prediction_noise

NUM_RESTARTS = 0
KERNEL_FUNCTION = get_non_linear_input_dependent_kernel

START = 0
END = 1

# Construct synthetic outputs
n_true = 100000
X = np.linspace(START, END, n_true).reshape((n_true, 1))
Y_true_noisy = y_exp2(X, is_noisy=True)
Y_true = y_exp2(X, is_noisy=False)
split_output_true = get_split_outputs(Y_true)

# Construct observations
n_obs = 100
X_obs = np.linspace(START, END, n_obs).reshape((n_obs, 1))
Y_obs = y_exp2(X_obs, is_noisy=True)
split_output_obs = get_split_outputs(Y_obs)

# Get outputs at desired locations
Y_new_noisy = y_exp2(X, is_noisy=True)

# Get predictions
def true_predictor(Y_true):
    return Y_true, np.zeros(Y_true.shape)

def gpar_predictor(Y):
    m = GPARRegression(X_obs, Y, KERNEL_FUNCTION, num_restarts=NUM_RESTARTS)
    return m.predict_f(X)

def igp_predictor(Y):
    igp_model = IGPRegression(X_obs, Y, KERNEL_FUNCTION, num_restarts=NUM_RESTARTS)
    return igp_model.predict_f(X)

noise_true = get_prediction_noise(Y_true_noisy, true_predictor, split_output_true)
noise_gpar = get_prediction_noise(Y_new_noisy, gpar_predictor, split_output_obs)
noise_igp = get_prediction_noise(Y_new_noisy, igp_predictor, split_output_obs)

# Display results
plot_noise(0, X, noise_true, 'Truth')
plot_noise(1, X, noise_gpar, 'GPAR')
plot_noise(2, X, noise_igp, 'IGP')
plt.show()


# Restaurent Rating System

# Supressing the warning messages
import warnings
warnings.filterwarnings('ignore')

#Importing the dataset
import pandas as pd
import numpy as np
ZomatoData = pd.read_csv('ZomatoData.csv')
print('Shape of the data',ZomatoData.shape)

ZomatoData = ZomatoData.drop_duplicates()
print('Shape of data after removing duplicate value',ZomatoData.shape)

#printing first few rows from dataset
ZomatoData.head(10)

#Study of target variable

# import matplotlib.pyplot as plt
# plt.hist(ZomatoData['Rating'])
# plt.show()

#Data Exploration
ZomatoData.info()
#checking unique values for each column
ZomatoData.nunique()

# =============================================================================
# '''By looking at the data we can reject Restaurant ID, Restaurant Name , City ,Cuisines,Locality Verbose , locality , Cuisines '''
# =============================================================================

#we can however use the number of cuisines offered so
#funtion to count number of cuisines
def cuisine_counter(inp):
    NumCuisines  = len(str(inp).split(','))
    return NumCuisines
ZomatoData['CuisineCount'] = ZomatoData['Cuisines'].apply(cuisine_counter)

#Removing Useless Columns from th data
UselessColumns = ['Restaurant ID', 'Restaurant Name','City','Address','Locality', 'Locality Verbose','Cuisines']
ZomatoData = ZomatoData.drop(UselessColumns,axis=1)

# =============================================================================
# by looking at the bar charts in this data, "Country Code", "Currency", "is delivering now" and "Switch to order menu" are too skewed. There is just one bar which is dominating and other categories have very less rows or there is just one value only. Such columns are not correlated with the target variable because there is no information to learn. The algorithms cannot find any rule like when the value is this then the target variable is that.
#only these columns are selected 'Has Table booking', 'Has Online delivery', 'Price range'
# =============================================================================

#Outlier Treatement

# =============================================================================
# on checking the votes column we can see that there are otliers so we treat them by replacing any value above 4000 by a different value
# =============================================================================
ZomatoData['Votes'][ZomatoData['Votes']<4000].sort_values(ascending=False)
#we see the nearest value is 3986
ZomatoData['Votes'][ZomatoData['Votes']>4000] = 3986

# Finding nearest values to 50000 mark
ZomatoData['Average Cost for two'][ZomatoData['Average Cost for two']<50000].sort_values(ascending=False)

#replacing the oulier with 8000
ZomatoData['Average Cost for two'][ZomatoData['Average Cost for two']>50000] =8000

# =============================================================================
# feature selection
# =============================================================================

#calculating the correlation coefficient for continuous data
# Calculating correlation matrix
ContinuousCols=['Rating','Longitude', 'Latitude', 'Votes', 'Average Cost for two']

# Creating the correlation matrix
CorrelationData=ZomatoData[ContinuousCols].corr()
CorrelationData

# Filtering only those columns where absolute correlation > 0.2 with Target Variable
CorrelationData['Rating'][abs(CorrelationData['Rating']) > 0.2]
#so final selected continuous columns are Votes and Average Cost for two

# =============================================================================
# performing ANOVA test for categorical data
# =============================================================================
# Defining a function to find the statistical relationship with all the categorical variables
def FunctionAnova(inpData, TargetVariable, CategoricalPredictorList):
    from scipy.stats import f_oneway

    # Creating an empty list of final selected predictors
    SelectedPredictors=[]

    print('##### ANOVA Results ##### \n')
    for predictor in CategoricalPredictorList:
        CategoryGroupLists=inpData.groupby(predictor)[TargetVariable].apply(list)
        AnovaResults = f_oneway(*CategoryGroupLists)

        # If the ANOVA P-Value is <0.05, that means we reject H0
        if (AnovaResults[1] < 0.05):
            print(predictor, 'is correlated with', TargetVariable, '| P-Value:', AnovaResults[1])
            SelectedPredictors.append(predictor)
        else:
            print(predictor, 'is NOT correlated with', TargetVariable, '| P-Value:', AnovaResults[1])

    return(SelectedPredictors)
# Calling the function to check which categorical variables are correlated with target
# Calling the function to check which categorical variables are correlated with target
CategoricalPredictorList=['Has Table booking', 'Has Online delivery', 'Price range']
FunctionAnova(inpData=ZomatoData,
              TargetVariable='Rating',
              CategoricalPredictorList=CategoricalPredictorList)
#final we select 'Has Table booking', 'Has Online delivery', 'Price range' for categorical data columns

# =============================================================================
# selecting final predictors for our model
# =============================================================================
SelectedColumns = ['Votes','Average Cost for two','Has Table booking','Has Online delivery','Price range']

#selecting the final columns
DataForML = ZomatoData[SelectedColumns]

#saving this data for refrence
DataForML.to_pickle('DataForML.pkl')

# =============================================================================
# Converting the binary nominal variable to numeric 1/0 mapping
# =============================================================================
DataForML['Has Table booking'].replace({'Yes':1, 'No':0}, inplace=True)
DataForML['Has Online delivery'].replace({'Yes':1, 'No':0}, inplace=True)

# =============================================================================
# Converting the nominal variable to numeric using get_dummies()
# =============================================================================
DataForML_Numeric = pd.get_dummies(DataForML)
DataForML_Numeric['Rating'] = ZomatoData['Rating']

# =============================================================================
# Splitting the data into test and train set
# =============================================================================
TargetVariable='Rating'
Predictors=['Votes', 'Average Cost for two', 'Has Table booking',
           'Has Online delivery', 'Price range']

X=DataForML_Numeric[Predictors].values
y=DataForML_Numeric[TargetVariable].values

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,train_size=0.3,random_state=428)

# =============================================================================
# ### Sandardization of data ###
# =============================================================================
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# Choose either standardization or Normalization
# On this data Min Max Normalization produced better results

# Choose between standardization and MinMAx normalization
#PredictorScaler=StandardScaler()
PredictorScaler=MinMaxScaler()

# Storing the fit object for later reference
PredictorScalerFit=PredictorScaler.fit(X)

# Generating the standardized values of X
X=PredictorScalerFit.transform(X)

# Split the data into training and testing set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# =============================================================================
# Fitting  Decision Trees
# =============================================================================
from sklearn.tree import DecisionTreeRegressor
RegModel = DecisionTreeRegressor(max_depth=10,criterion='mse')

DT = RegModel.fit(X_train,y_train)
prediction = DT.predict(X_test)

from sklearn import metrics
# Measuring Goodness of fit in Training data
print('R2 Value:',metrics.r2_score(y_train, DT.predict(X_train)))

###########################################################################
print('\n##### Model Validation and Accuracy Calculations ##########')

# Printing some sample values of prediction
TestingDataResults=pd.DataFrame(data=X_test, columns=Predictors)
TestingDataResults[TargetVariable]=y_test
TestingDataResults[('Predicted'+TargetVariable)]=np.round(prediction)

# Printing sample prediction values
print(TestingDataResults[[TargetVariable,'Predicted'+TargetVariable]].head())

# Calculating the error for each row
TestingDataResults['APE']=100 * ((abs(
  TestingDataResults['Rating']-TestingDataResults['PredictedRating']))/TestingDataResults['Rating'])

MAPE=np.mean(TestingDataResults['APE'])
MedianMAPE=np.median(TestingDataResults['APE'])

Accuracy =100 - MAPE
MedianAccuracy=100- MedianMAPE
print('Mean Accuracy on test data:', Accuracy) # Can be negative sometimes due to outlier
print('Median Accuracy on test data:', MedianAccuracy)

# Defining a custom function to calculate accuracy
# Make sure there are no zeros in the Target variable if you are using MAPE
def Accuracy_Score(orig,pred):
    MAPE = np.mean(100 * (np.abs(orig-pred)/orig))
    #print('#'*70,'Accuracy:', 100-MAPE)
    return(100-MAPE)

# Custom Scoring MAPE calculation
from sklearn.metrics import make_scorer
custom_Scoring=make_scorer(Accuracy_Score, greater_is_better=True)

# Importing cross validation function from sklearn
from sklearn.model_selection import cross_val_score

# Running 10-Fold Cross validation on a given algorithm
# Passing full data X and y because the K-fold will split the data and automatically choose train/test
Accuracy_Values=cross_val_score(RegModel, X , y, cv=10, scoring=custom_Scoring)
print('\nAccuracy values for 10-fold Cross Validation:\n',Accuracy_Values)
print('\nFinal Average Accuracy of the model:', round(Accuracy_Values.mean(),2))

# =============================================================================
# choosing only the most important variable
# =============================================================================
#we select only 'Votes', 'Average Cost for two', 'Price range' for final model

TargetVariable = 'Rating'
Predictors = ['Votes','Average Cost for two','Price range']

X = DataForML_Numeric[Predictors].values
y = DataForML_Numeric[TargetVariable].values
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# Choose either standardization or Normalization
# On this data Min Max Normalization produced better results

# Choose between standardization and MinMAx normalization
#PredictorScaler=StandardScaler()
PredictorScaler=MinMaxScaler()

# Storing the fit object for later reference
PredictorScalerFit=PredictorScaler.fit(X)

# Generating the standardized values of X
X=PredictorScalerFit.transform(X)

# =============================================================================
# retraining the model with 100% data
# =============================================================================
from sklearn.tree import DecisionTreeRegressor
RegModel = DecisionTreeRegressor(max_depth=6,criterion='mse')
FinalDecisionTreeModel = RegModel.fit(X, y)

import pickle
import os

# Saving the Python objects as serialized files can be done using pickle library
# Here let us save the Final ZomatoRatingModel
with open('FinalDecisionTreeModel.pkl', 'wb') as fileWriteStream:
    pickle.dump(FinalDecisionTreeModel, fileWriteStream)
    # Don't forget to close the filestream!
    fileWriteStream.close()

print('pickle file of Predictive Model is saved at Location:',os.getcwd())
# This Function can be called from any from any front end tool/website
def FunctionPredictResult(InputData):
    import pandas as pd
    Num_Inputs=InputData.shape[0]

    # Making sure the input data has same columns as it was used for training the model
    # Also, if standardization/normalization was done, then same must be done for new input

    # Appending the new data with the Training data
    DataForML=pd.read_pickle('DataForML.pkl')
    InputData=InputData.append(DataForML)

    # Generating dummy variables for rest of the nominal variables
    InputData=pd.get_dummies(InputData)

    # Maintaining the same order of columns as it was during the model training
    Predictors=['Votes', 'Average Cost for two', 'Price range']

    # Generating the input values to the model
    X=InputData[Predictors].values[0:Num_Inputs]

    # Generating the standardized values of X since it was done while model training also
    X=PredictorScalerFit.transform(X)

    # Loading the Function from pickle file
    import pickle
    with open('FinalDecisionTreeModel.pkl', 'rb') as fileReadStream:
        PredictionModel=pickle.load(fileReadStream)
        # Don't forget to close the filestream!
        fileReadStream.close()

    # Genrating Predictions
    Prediction=PredictionModel.predict(X)
    PredictionResult=pd.DataFrame(Prediction, columns=['Prediction'])
    return(PredictionResult)
# Calling the function for new sample data
NewSampleData=pd.DataFrame(
data=[[314,1100,3],
     [591,1200,4]],
columns=['Votes', 'Average Cost for two', 'Price range'])

print(NewSampleData)

# Calling the Function for prediction
FunctionPredictResult(InputData= NewSampleData)

# Creating the function which can take inputs and return predictions
def FunctionGeneratePrediction(inp_Votes, inp_Average_Cost, inp_Price_range):

    # Creating a data frame for the model input
    SampleInputData=pd.DataFrame(
     data=[[inp_Votes , inp_Average_Cost, inp_Price_range]],
     columns=['Votes', 'Average Cost for two', 'Price range'])

    # Calling the function defined above using the input parameters
    Predictions=FunctionPredictResult(InputData= SampleInputData)

    # Returning the prediction
    return(Predictions.to_json())

# Function call
FunctionGeneratePrediction(314,1100,3)

filename = 'PredictorScaler.pkl'
pickle.dump(PredictorScaler,open(filename,'wb'))


import heapq as hq

def solution(op):
        q = []
        for i in op:
            ins, num = i.strip().split()
            if ins == 'I':
                hq.heappush(q, int(num))
            elif ins == 'D' and q:
                if num == '-1':
                    hq.heappop(q)
                elif num == '1':
                    q.pop()
        return [max(q), min(q)] if q else [0,0]

프로그래머스/lv3/42628. 이중우선순위큐/이중우선순위큐.py


import numpy as np
import matplotlib.pyplot as plt

def get_points(mean, std=.15, npoints=10):
  x = np.random.normal(mean[0], std, npoints)
  y = np.random.normal(mean[1], std, npoints)
  return np.stack([x,y]).T

def att_mean(points, ref, sigma=.15):
  ref = np.array(ref)[None]
  dists = points - ref
  dists = np.sum(dists**2, axis=1)
  w = np.exp(-dists/sigma/2)
  w = w/np.sum(w)
  att_mean = points * w[:, None]
  return att_mean.sum(axis=0)

p0 = [-1, .5]
p1 = [.5, 0]
p2 = [0, .5]

a = [0, 1]
b = [1, 0]
c = [-1, 0]
points_cluster = [get_points(x) for x in [a,b,c]]
points = np.concatenate(points_cluster, axis=0)

mean = np.mean(points, axis=0)
att0 = att_mean(points, p0)
att1 = att_mean(points, p1)
att2 = att_mean(points, p2)

plt.plot(points_cluster[0][:, 0], points_cluster[0][:, 1], '.', markersize=20, color='purple')
plt.plot(points_cluster[1][:, 0], points_cluster[1][:, 1], '.', markersize=20, color='green')
plt.plot(points_cluster[2][:, 0], points_cluster[2][:, 1], '.', markersize=20, color='pink')

markers = ['h', 's', 's', 's', 'o', 'o', 'o']
colors = ['black', 'red', 'blue', 'green', 'red', 'blue', 'green']
for i, p in enumerate([mean, att0, att1, att2, p0, p1, p2]):
  plt.plot(p[0], p[1], markers[i], color=colors[i], markersize=20)

plt.gca().axes.get_yaxis().set_visible(False)
plt.gca().axes.get_xaxis().set_visible(False)
plt.show()
#plt.xlim(0, 1.8)


from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from .forms import DocumentForm
from .models import Document, ConstructionMaterial

import pandas as pd
from sqlalchemy import create_engine

def upload_csv(request):
    """
    Загрузка файла в модель Document.
    """
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect("/success/")
    else:
        form = DocumentForm()
    return render(request, 'main_app/upload.html', {'form': form})

def parsing_request(request):
    """
    Вывод шаблона с полями для ввода запроса на парсинг.
    """
    last_file = Document.objects.last()
    fields = [f.verbose_name for f in ConstructionMaterial._meta.get_fields()]
    return render(request, 'main_app/parser.html', {'document': last_file, 'fields': fields[1:]})

def parsing_result(request):
    """
    Получение запрашиваемой в парсинге информации, чтение последнего загруженного .csv файла через pandas.
    """
    searching_field = request.POST.getlist("searching_field")
    fields = [f.verbose_name for f in ConstructionMaterial._meta.get_fields()]
    fields = fields[1:]
    current_search = {fields[i]: searching_field[i] for i in range(len(fields)) if searching_field[i] != ''}

    def search_df(length, **kwargs):
        """
        Поиск побитового соответствия запрашиваемого поля в dataframe pandas.
        """
        latest_csv = Document.objects.latest('file')
        df = pd.read_csv(latest_csv.file.path, sep=';', engine='python', quoting=3, error_bad_lines=False)
        if length == 0:
            res = "Необходимо выбрать хотя бы одно поле для поиска"
        else:
            for key, value in kwargs.items():
                res = df[df[key].astype(str).str.contains(value, na=False)]  # Доработать множественный поиск
        return res

    global result
    result = search_df(len(current_search), **current_search)
    result_html = result.to_html()

    return render(request, 'main_app/parser_result.html', {'result_html': result_html, 'result': result})

def save_to_db(request):
    """
    Сохранение информации которую удалось спарсить в модель ConstructionMaterial.
    """
    if request.method == 'GET':
        # result = request.GET["result"]
        print(type(result))
        engine = create_engine('sqlite:///db.sqlite3')
        result.to_sql(ConstructionMaterial._meta.db_table, if_exists='append', con=engine, index=False)
        context = {"success": "Данная выборка успешно сохранена"}
    # return HttpResponse("Данная выборка успешно сохранена")
    return render(request, 'main_app/parser_result.html', context)


#!/usr/bin/env python3

"""
Program which asks the user whether they want to convert from decimal to binary,
or binary to decimal. The program then prompts the user to enter either a decimal
integer or a binary string depending on their previous selection. The program then
converts the input to either binary or decimal, depending on the selection.
"""

def decimal_to_binary():
    decimal = int(input('Please enter a positive integer: '))
    arr = []
    while decimal > 0:
        arr.append(decimal % 2)
        decimal = int(decimal/2)
    binary_string = [str(x) for x in arr[::-1]]
    print(''.join(binary_string))

def binary_to_decimal():
    binary_list = list(input('Please enter a binary number (no spaces or commas): '))
    total = 0
    for x in binary_list:
        total = total * 2 + int(x)
    print(total)

print('''Please select an operation:
1) Decimal to binary
2) Binary to decimal\n''')

while True:
    operation_selection = input('[1/2]:')
    if operation_selection == '1':
        decimal_to_binary()
        break
    elif operation_selection == '2':
        binary_to_decimal()
        break
    else:
        print("Invalid selection. You must select either '1' or '2'. Try again...\n")


count = 0
cont = 0
while cont == 0:
    num = int(input('Digite o primeiro número da progressão aritimetica: '))
    r = int(input('Digite a razão: '))
    while count <= 9:
        num += r
        print(num)
        count += 1
    opc = input('Gstaria de continuar com outro termo? [S/N]: ')
    if opc == 's':
        count = 0
    else:
        break


# Customer Segmentation with RFM Analysis

# TASK 1. Data Understanding

# Import necessarily libraries
import pandas as pd
import datetime as dt

# Set pandas options to display all columns and rows, float format, and comment out display width
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
pd.set_option('display.float_format', lambda x: '%.2f' % x)

# 1. Read the flo_data_20K.csv file and create a copy of the dataframe
df_ = pd.read_csv(r"CRM_Analytics\flo_data_20k.csv")
df = df_.copy()
df.head()

# 2. Analyze the data set including the first 10 observations, variable names, dimensions, descriptive statistics,
# missing values, and variable types
df.head(10)
df.columns
df.shape
df.describe().T
df.isnull().sum()
df.info()

# 3. Create new variables to show the total number of orders and the total customer value for each customer
# who shops from both online and offline platforms
df["order_num_total"] = df["order_num_total_ever_online"] + df["order_num_total_ever_offline"]
df["customer_value_total"] = df["customer_value_total_ever_offline"] + df["customer_value_total_ever_online"]

# 4. Analyze variable types and convert date columns to datetime
date_columns = df.columns[df.columns.str.contains("date")]
df[date_columns] = df[date_columns].apply(pd.to_datetime)
df.info()

# 5. Analyze the distribution of the number of customers, total number of items purchased, and total customer
# value in each order channel
df.groupby("order_channel").agg({"master_id":"count",
                                 "order_num_total":"sum",
                                 "customer_value_total":"sum"})

# 6. Sort and display the top 10 customers who bring the highest customer value
df.sort_values("customer_value_total", ascending=False)[:10]

# 7. Sort and display the top 10 customers who have the highest number of orders
df.sort_values("order_num_total", ascending=False)[:10]

# 8. Function to prepare the data
def data_prep(dataframe):
    # Create new variables to show the total number of orders and the total customer value for each customer
    # who shops from both online and offline platforms
    dataframe["order_num_total"] = dataframe["order_num_total_ever_online"] + dataframe["order_num_total_ever_offline"]
    dataframe["customer_value_total"] = dataframe["customer_value_total_ever_offline"] + dataframe["customer_value_total_ever_online"]
    # Convert date columns to datetime
    date_columns = dataframe.columns[dataframe.columns.str.contains("date")]
    dataframe[date_columns] = dataframe[date_columns].apply(pd.to_datetime)
    return df

# TASK 2: Calculate RFM Metrics

# Define the analysis date as 2 days after the date of the latest order in the dataset
latest_order_date = df["last_order_date"].max()
analysis_date = latest_order_date + dt.timedelta(days=2) # add 2 days to the latest order date

# Create a new dataframe to store customer_id, recency, frequency, and monetary values for RFM analysis
rfm = pd.DataFrame()
rfm["customer_id"] = df["master_id"] # Add customer IDs from original dataframe
rfm["recency"] = (analysis_date - df["last_order_date"]).astype('timedelta64[D]') # Calculate recency as the number of days between the analysis date and the date of the customer's last order
rfm["frequency"] = df["order_num_total"] # Add total number of orders for each customer from the original dataframe
rfm["monetary"] = df["customer_value_total"] # Add total monetary value of orders for each customer from the original dataframe

# Print the first five rows of the RFM dataframe to check that it has been created correctly
print(rfm.head())

# TASK 3: Calculate RF and RFM Scores

# Convert the recency, frequency, and monetary metrics into scores from 1 to 5 using qcut, and save them as separate columns in the rfm dataframe
rfm["recency_score"] = pd.qcut(rfm['recency'], 5, labels=[5, 4, 3, 2, 1]) # Divide recency values into 5 equal-sized bins and assign labels of 5 (highest) to 1 (lowest) to each bin
rfm["frequency_score"] = pd.qcut(rfm['frequency'].rank(method="first"), 5, labels=[1, 2, 3, 4, 5]) # Divide frequency values into 5 equal-sized bins based on their rank, and assign labels of 1 (lowest) to 5 (highest) to each bin
rfm["monetary_score"] = pd.qcut(rfm['monetary'], 5, labels=[1, 2, 3, 4, 5]) # Divide monetary values into 5 equal-sized bins and assign labels of 1 (lowest) to 5 (highest) to each bin

# Combine the recency_score and frequency_score columns into a single column called RF_SCORE
rfm["RF_SCORE"] = (rfm['recency_score'].astype(str) + rfm['frequency_score'].astype(str)) # Concatenate the recency_score and frequency_score columns into a single column

# Combine the recency_score, frequency_score, and monetary_score columns into a single column called RFM_SCORE
rfm["RFM_SCORE"] = (rfm['recency_score'].astype(str) + rfm['frequency_score'].astype(str) + rfm['monetary_score'].astype(str)) # Concatenate all three score columns into a single column

# TASK 4: Define RF Scores as Segments
# Define segments for more meaningful interpretation of RFM scores and convert RF_SCORE to segments using seg_map
seg_map = {
    r'[1-2][1-2]': 'hibernating', # Customers who have low recency, frequency, and monetary value
    r'[1-2][3-4]': 'at_Risk', # Customers who have low recency but higher frequency and monetary value
    r'[1-2]5': 'cant_loose', # Customers who have high monetary value but low recency and frequency
    r'3[1-2]': 'about_to_sleep', # Customers who have low recency and frequency but higher monetary value
    r'33': 'need_attention', # Customers who have low recency, frequency, and monetary value
    r'[3-4][4-5]': 'loyal_customers', # Customers who have high recency and frequency but lower monetary value
    r'41': 'promising', # Customers who have high recency, low frequency, and monetary value
    r'51': 'new_customers', # Customers who have high frequency but low recency and monetary value
    r'[4-5][2-3]': 'potential_loyalists', # Customers who have high recency and monetary value but lower frequency
    r'5[4-5]': 'champions' # Customers who have high recency, frequency, and monetary value
}

# Replace RF_SCORE with corresponding segment using seg_map and add a new 'segment' column to the rfm DataFrame
rfm['segment'] = rfm['RF_SCORE'].replace(seg_map, regex=True)

# TASK 5. Action Time!
# 1. Analyze the recency, frequency, and monetary averages of the segments.
# Group by the "segment", and aggregate the means and counts of the "recency", "frequency", and "monetary" columns.
rfm[["segment", "recency", "frequency", "monetary"]].groupby("segment").agg(["mean", "count"])

# 2. Using RFM analysis, find the customers in the relevant profile for 2 cases and save their customer IDs to CSV files.

# a. FLO is introducing a new women's shoe brand. The prices of the brand's products are above the general customer preferences. Therefore, it is desired to communicate
# with the customers in the relevant profile who will be interested in the promotion and sales of the brand. These customers are planned to be loyal and
# those who shop from the women's category. Save the customer IDs to a CSV file named "new_brand_target_customer_ids.csv".
target_segments_customer_ids = rfm[rfm["segment"].isin(["champions","loyal_customers"])]["customer_id"]
cust_ids = df[(df["master_id"].isin(target_segments_customer_ids)) &(df["interested_in_categories_12"].str.contains("KADIN"))]["master_id"]
cust_ids.to_csv("new_brand_target_customer_ids.csv", index=False)
print(cust_ids.shape)

# b. A discount of nearly 40% is planned for men's and children's products. Previously good customers who are interested in the discounted categories but have not shopped for a long time, and new customers are wanted to be targeted specifically. Save the customer IDs to a CSV file named "discount_target_customer_ids.csv".
target_segments_customer_ids = rfm[rfm["segment"].isin(["cant_loose","hibernating","new_customers"])]["customer_id"]
cust_ids = df[(df["master_id"].isin(target_segments_customer_ids)) & ((df["interested_in_categories_12"].str.contains("ERKEK"))|(df["interested_in_categories_12"].str.contains("COCUK")))]["master_id"]
cust_ids.to_csv("discount_target_customer_ids.csv", index=False)
print(cust_ids.shape)

# BONUS. Functionalize all steps

def create_rfm(dataframe):
    # Data Preparation
    # Create a new column for the total number of orders
    dataframe["order_num_total"] = dataframe["order_num_total_ever_online"] + dataframe["order_num_total_ever_offline"]
    # Create a new column for the total customer value
    dataframe["customer_value_total"] = dataframe["customer_value_total_ever_offline"] + dataframe["customer_value_total_ever_online"]
    # Get the columns that contain dates and convert them to datetime format
    date_columns = dataframe.columns[dataframe.columns.str.contains("date")]
    dataframe[date_columns] = dataframe[date_columns].apply(pd.to_datetime)

    # Calculate RFM Metrics
    # Determine the latest order date and set the analysis date to the next day
    latest_order_date = dataframe["last_order_date"].max()
    analysis_date = latest_order_date + dt.timedelta(days=1)
    # Create a new empty dataframe to store RFM values
    rfm = pd.DataFrame()
    # Add customer ID, recency, frequency, and monetary columns to the RFM dataframe
    rfm["customer_id"] = dataframe["master_id"]
    rfm["recency"] = (analysis_date - dataframe["last_order_date"]).astype('timedelta64[D]')
    rfm["frequency"] = dataframe["order_num_total"]
    rfm["monetary"] = dataframe["customer_value_total"]

    # Calculate RF and RFM Scores
    # Divide recency, frequency, and monetary into 5 equal-sized groups and assign scores
    rfm["recency_score"] = pd.qcut(rfm['recency'], 5, labels=[5, 4, 3, 2, 1])
    rfm["frequency_score"] = pd.qcut(rfm['frequency'].rank(method="first"), 5, labels=[1, 2, 3, 4, 5])
    rfm["monetary_score"] = pd.qcut(rfm['monetary'], 5, labels=[1, 2, 3, 4, 5])
    # Combine recency and frequency scores to create RF Score
    rfm["RF_SCORE"] = (rfm['recency_score'].astype(str) + rfm['frequency_score'].astype(str))
    # Combine RF Score and monetary score to create RFM Score
    rfm["RFM_SCORE"] = (rfm['recency_score'].astype(str) + rfm['frequency_score'].astype(str) + rfm['monetary_score'].astype(str))

    # Map RF Scores to segment names
    seg_map = {
        r'[1-2][1-2]': 'hibernating',
        r'[1-2][3-4]': 'at_Risk',
        r'[1-2]5': 'cant_loose',
        r'3[1-2]': 'about_to_sleep',
        r'33': 'need_attention',
        r'[3-4][4-5]': 'loyal_customers',
        r'41': 'promising',
        r'51': 'new_customers',
        r'[4-5][2-3]': 'potential_loyalists',
        r'5[4-5]': 'champions'
    }
    # Map RF Scores to segment names and add the segment column to the RFM dataframe
    rfm['segment'] = rfm['RF_SCORE'].replace(seg_map, regex=True)

    # Return the RFM dataframe
    return rfm[["customer_id", "recency","frequency","monetary","RF_SCORE","RFM_SCORE","segment"]]

rfm_df = create_rfm(df)