import unittest2 as unittest

from nupic.data import dict_utils
from nupic.frameworks.opf import opf_utils, previous_value_model

try:
  import capnp
except ImportError:
  capnp = None
if capnp:
  from nupic.frameworks.opf.previous_value_model_capnp import (
    PreviousValueModelProto)

SEQUENCE_LENGTH = 100

def _generateIncreasing():
  return [i for i in range(SEQUENCE_LENGTH)]

def _generateDecreasing():
  return [SEQUENCE_LENGTH - i for i in range(SEQUENCE_LENGTH)]

def _generateSaw():
  return [i % 3 for i in range(SEQUENCE_LENGTH)]

class PreviousValueModelTest(unittest.TestCase):
  """Unit test for the Previous Value Model."""

  def _runNextStep(self, data):
    model = previous_value_model.PreviousValueModel(
      opf_utils.InferenceType.TemporalNextStep, predictedField ='a')

    inputRecords = (dict_utils.DictObj({'a' : d}) for d in data)

    for i, (inputRecord, expectedInference) in enumerate(zip(inputRecords,
                                                             data)):
      results = model.run(inputRecord)
      self.assertEqual(results.predictionNumber, i)
      self.assertEqual(results.inferences[
        opf_utils.InferenceElement.prediction], expectedInference)
      self.assertEqual(results.inferences[
        opf_utils.InferenceElement.multiStepBestPredictions][1],
                       expectedInference)

  def _runMultiStep(self, data):
    model = previous_value_model.PreviousValueModel(
      opf_utils.InferenceType.TemporalMultiStep, predictedField ='a',
      predictionSteps = [1, 3, 5])

    inputRecords = (dict_utils.DictObj({'a' : d}) for d in data)

    for i, (inputRecord, expectedInference) in enumerate(zip(inputRecords,
                                                             data)):
      results = model.run(inputRecord)
      self.assertEqual(results.predictionNumber, i)
      self.assertEqual(results.inferences[
        opf_utils.InferenceElement.prediction], expectedInference)
      self.assertEqual(results.inferences[
        opf_utils.InferenceElement.multiStepBestPredictions][1],
                       expectedInference)
      self.assertEqual(results.inferences[
        opf_utils.InferenceElement.multiStepBestPredictions][3],
                       expectedInference)
      self.assertEqual(results.inferences[
        opf_utils.InferenceElement.multiStepBestPredictions][5],
                       expectedInference)

  def testNextStepIncreasing(self):
    self._runNextStep(_generateIncreasing())

  def testNextStepDecreasing(self):
    self._runNextStep(_generateDecreasing())

  def testNextStepSaw(self):
    self._runNextStep(_generateSaw())

  def testMultiStepIncreasing(self):
    self._runMultiStep(_generateIncreasing())

  def testMultiStepDecreasing(self):
    self._runMultiStep(_generateDecreasing())

  def testMultiStepSaw(self):
    self._runMultiStep(_generateSaw())

  @unittest.skipUnless(
    capnp, "pycapnp is not installed, skipping serialization test.")
  def testCapnpWriteRead(self):
    m1 = previous_value_model.PreviousValueModel(
      opf_utils.InferenceType.TemporalMultiStep, predictedField ='a',
      predictionSteps = [1, 3, 5])

    m1.run(dict_utils.DictObj({'a' : 0}))

    # Serialize
    builderProto = PreviousValueModelProto.new_message()
    m1.write(builderProto)

    # Construct reader from populated builder
    readerProto = PreviousValueModelProto.from_bytes(builderProto.to_bytes())

    # Deserialize
    m2 = previous_value_model.PreviousValueModel.read(readerProto)

    self.assertIs(m1.getSchema(), PreviousValueModelProto)
    self.assertIs(m2.getSchema(), PreviousValueModelProto)

    self.assertEqual(m2._numPredictions, m1._numPredictions)
    self.assertEqual(m2.getInferenceType(), m1.getInferenceType())
    self.assertEqual(m2.isLearningEnabled(), m1.isLearningEnabled())
    self.assertEqual(m2.isInferenceEnabled(), m1.isInferenceEnabled())
    self.assertEqual(m2.getInferenceArgs(), m1.getInferenceArgs())
    self.assertEqual(m2._predictedField, m1._predictedField)
    self.assertEqual(m2._fieldNames, m1._fieldNames)
    self.assertEqual(m2._fieldTypes, m1._fieldTypes)
    self.assertEqual(m2._predictionSteps, m1._predictionSteps)

    # Run computes on m1 & m2 and compare results
    r1 = m1.run(dict_utils.DictObj({'a' : 1}))
    r2 = m2.run(dict_utils.DictObj({'a' : 1}))

    self.assertEqual(r2.predictionNumber, r1.predictionNumber)
    self.assertEqual(r2.rawInput, r1.rawInput)

    self.assertEqual(r2.predictionNumber, r1.predictionNumber)
    self.assertEqual(r2.inferences[opf_utils.InferenceElement.prediction],
                     r1.inferences[opf_utils.InferenceElement.prediction])
    self.assertEqual(
      r2.inferences[opf_utils.InferenceElement.multiStepBestPredictions][1],
      r1.inferences[opf_utils.InferenceElement.multiStepBestPredictions][1])
    self.assertEqual(
      r2.inferences[opf_utils.InferenceElement.multiStepBestPredictions][3],
      r1.inferences[opf_utils.InferenceElement.multiStepBestPredictions][3])
    self.assertEqual(
      r2.inferences[opf_utils.InferenceElement.multiStepBestPredictions][5],
      r1.inferences[opf_utils.InferenceElement.multiStepBestPredictions][5])

if __name__ == '__main__':
  unittest.main()


import tensorflow as tf
import yaml
import gym
import ma_gym
import os
import numpy as np
from utils.init_env import init_env
from configs.config import *
import glob

def calculate_nash_conv(env, config, arg, devices):
    n_agents = env.n_agents
    checkpoint_path = args.checkpoint_path
    with tf.device(device):
        current_trainer = TRAINERs[config["trainer"]](env, n_agents, config)
        current_trainer.restore(checkpoint_path, args.agent_ids)

        # to get the current policy evaluate value
        current_values = []
        current_trainer.buf.clear()
        current_trainer.run_one_epoch(["original"] * n_agents)
        current_data = current_trainer.buf.get()
        # n_agents x shape of state
        obs = current_data[0]

        for j in range(n_agents):
            values = current_trainer.agents[j].get_value(
                current_trainer.sess, np.array(obs[:, j]), "original"
            )
            # n_agents x n_states
            current_values.append(values)

        tf.compat.v1.reset_default_graph()
        br_values = []

        br_trainer = TRAINERs[config["trainer"]](env, n_agents, config)
        br_trainer.restore(checkpoint_path, args.agent_ids)
        br_trainer.rollouts(1, ["original"] * n_agents)
        br_trainer.update_tmp_policies()

        for i in range(args.num_games_eval):
            br_trainer.buf.clear()
            br_trainer.run_one_epoch(["tmp"] * n_agents)
            br_data = br_trainer.buf.get()
            for j in range(n_agents):
                values = br_trainer.agents[j].get_value(
                    br_trainer.sess, np.array(obs[:, j]), "tmp"
                )
                br_values.append(values)
            nash_conv = 0
            for i in range(n_agents):
                nash_conv += sum(
                    np.array(br_values[i][:]) - np.array(current_values[i][:])
                )
    return nash_conv

def calculate_score(env, sess, agents):
    """
    rollout with two policies, find the score of using policy1 against policy 2
    """
    n_agents = env.n_agents
    obs_n, rew_n, done_n, ep_ret_n, ep_len = (
        env.reset(),
        [0 for i in range(n_agents)],
        False,
        [0 for i in range(n_agents)],
        0,
    )
    done = False
    while not done:
        act_n = []
        for i in range(n_agents):
            action, _, _ = agents[i].get_action(sess, obs_n[i], "original")
            act_n.append(action[0])
        obs_n, rew_n, done_n, _ = env.step(act_n)
        ep_ret_n = [n + r for n, r in zip(ep_ret_n, rew_n)]
        ep_len += 1
        if np.array(done_n).any():
            done = True

    return ep_ret_n

def calculate_population_performance(env, config, args, device):
    matrix_size = 2
    matrix = np.zeros((matrix_size, matrix_size))
    # load saved policies
    n_agents = env.n_agents
    checkpoints = []
    print(args.checkpoint_path)
    for i in range(n_agents):
        model_checkpoints =[]
        for j in range(matrix_size):
            model_checkpoints.append(args.checkpoint_path[i] + "model_{}.cpt-{}".format(i, j))
        checkpoints.append(model_checkpoints)

    # run simulations with policy pairs
    num_games = 20
    trainer = TRAINERs[config["trainer"]](env, n_agents, config)
    for i in range(matrix_size):
        for j in range(matrix_size):
            scores = []
            tf.compat.v1.reset_default_graph()
            trainer.restore([checkpoints[0][i], checkpoints[1][j]], args.agent_ids)
            # each policy pair will play 20 episodes to get the average score
            for _ in range(num_games):
                score = calculate_score(env, trainer.sess, trainer.agents)
                scores.append(score[0])
            matrix[i][j] = np.mean(scores)
    return matrix

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()

    parser.add_argument("--config_file", type=str, default="")
    parser.add_argument("--checkpoint_path", nargs='+', default="")
    parser.add_argument("--agent_ids", nargs= '+', default="")
    parser.add_argument("--evaluate_method", type=str, default="nash_conv")
    parser.add_argument("--num_games_eval", type=int, default=10)
    parser.add_argument("--output_folder", type=str, default="evaluate_logs")
    parser.add_argument("--device", type=str, default="CPU")
    args = parser.parse_args()

    a_yaml_file = open(args.config_file)
    config = yaml.load(a_yaml_file, Loader=yaml.FullLoader)

    device = args.device
    if device == "CPU" or device == "GPU":
        device = f"/{args.device}:0"
    elif device not in ["/GPU:1", "/GPU:2", "/GPU:3"]:
        raise ValueError

    env, n_agents, env_info = init_env(config)

    print("output folder is: ", config["output_dir"])
    print("env info: ", env.observation_space, env.action_space, env.n_agents)

    if args.evaluate_method == "nash_conv":
        nash_conv = calculate_nash_conv(env, config, args, device)
        print("evaluate score -- nash conv is: ", nash_conv)
    elif args.evaluate_method == "population_performance":
        matrix = calculate_population_performance( env, config, args, device)
        print(matrix)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 12 09:26:44 2017

@author: chengch
"""

import numpy as np

xyz = np.load('Stand_xyz.npy')
Pro = np.load('Pros.npy')

Vec_sts = []
Vec_vars = []
ver_COs = []
ver_NHs = []

def st_vec(mat1,mat2):
    mat_vec = mat1 - mat2
    data = np.sqrt(sum((mat_vec) ** 2))
    data = mat_vec / data
    return(data)

def var_vec(mat1,mat2):
    data = mat1 - mat2
    return(data)

for isnp in xyz:
    Vec_sts.append((st_vec(isnp[4],isnp[5]),st_vec(isnp[6],isnp[7])))

for isn in Pro:
    Vec_var = []
    for i in isn:
        Vec_var.append((var_vec(i[4],i[5]),var_vec(i[6],i[7])))
    Vec_vars.append(Vec_var)

for st, var in zip(Vec_sts,Vec_vars):
    ver_CO = []
    ver_NH = []
    for v in var:
        data_CO = np.dot(st[0],v[0])
        data_NH = np.dot(st[1],v[1])
        ver_CO.append(data_CO)
        ver_NH.append(data_NH)
    ver_COs.append(ver_CO)
    ver_NHs.append(ver_NH)

ver_COs = np.array(ver_COs)
ver_NHs = np.array(ver_NHs)

np.save('ver_CO.npy',abs(ver_COs))
np.save('ver_NH.npy',abs(ver_NHs))


import roboticstoolbox as rtb
import numpy as np

def calculate_momentum(q, qd, point, joint_num):
    """
    Calculate the instantaneous linear velocity and reflected mass of the contact point at a given time t, their product is the linear momentum of the point

    :param q: instantaneous angle of each joint at a given time t, size: 6x1
    :param qd: instantaneous velocity of each joint at a given time t, size: 6x1
    :param point: the contact point to be calculated
    :return vel_u: the unit vector of the linear velocity at contact point
    :return m_refl: reflected mass at contact point
    :return lin_vel: instantaneous linear velocity of contact point at time t
    :return rf_p: position vector of the contact point for visualisation, not used anymore
    """
    Yu = rtb.models.DH.Yu() # import Yu with all relevant geometric and mechanical data

    trafo_p = np.eye(4) # initialise homogeneous transformation matrix
    trafo_p[:, -1] = point # last column of the matrix is the contact point
    joint_jacobian = np.zeros((6, 6)) # initialise modified Jacobian
    pose_list = [] # a list of forward kinematics of each robot segment
    poses = Yu.fkine_all(q) # calculate forward kinematics of each robot segment with respect to robot basis

    for pose in (poses): # convert forward kinematics (SE3) into numpy arrays
        pose_list.append(np.array(pose))

    rf_p =  pose_list[joint_num+1] @ trafo_p @ np.array([0, 0, 0, 1]) # Position vector of contact point expressed in RF0

    for count in range(joint_num+1): # calculation of modified Jacobian, iterate through each robot segment, from robot basis to the robot segment where the contact point is located
        translation = rf_p - pose_list[count] @ np.array([0, 0, 0, 1]) # Position vector from RF of robot segment to the contact point
        translation = translation[:3] # Remove the last "1" element
        rotation = pose_list[count] @ np.array([0, 0, 1, 0]) # Rotation axis of the robot segment
        rotation = rotation[:3] # remove the last "0" element
        joint_jacobian[:3, count] = np.cross(rotation, translation) # translation part of the modified Jacobian
        joint_jacobian[3:6, count] = rotation # rotation part of the modified Jacobian

    lin_ang = joint_jacobian @ qd # linear and angular velocity of the contact point
    lin_vel = lin_ang[:3] # linear velocity of the contact point
    velocity_abs = np.linalg.norm(lin_vel, 2) # absolute value of linear velocity
    if velocity_abs <= 1e-3: # if the velocity is sufficiently small
        vel_u = np.zeros(3) # assume the contact point is stationary
    else:
        vel_u = np.divide(lin_vel, (np.linalg.norm(lin_vel, 2))) # calculate unit vector

    M_q = Yu.inertia(q) # inertia matrix of the robot
    Aq_inv = joint_jacobian @ np.linalg.inv(M_q) @ np.transpose(joint_jacobian) # inverse of the effective inertia matrix of the contact point

    if all(element == 0 for element in vel_u): # if point is stationary
        m_refl = 0 # set reflected mass to zero to avoid division over zero
    else:
        m_refl = 1/(np.transpose(vel_u) @ Aq_inv[:3, :3] @ vel_u) # calculate reflected mass of the contact point

    return vel_u, m_refl, lin_vel, rf_p


## TASK 1: DATA EXPLORATION

import numpy as np
import pandas as pd
import re
import time
import os
import sys
import glob
import copy
import sqlite3
import multiprocessing

data = pd.read_csv('SongCSV.csv')

start_time = time.time()

print(len(data))

data['SongHotness'] = data['SongHotness'].replace(0, np.nan)
data.dropna(subset=['SongHotness'], inplace=True)
data['SongID'] = data['SongID'].replace('b','',regex=True)
data['SongID'] = data['SongID'].replace('\'','',regex=True)
data['ArtistID'] = data['ArtistID'].replace('b','',regex=True)
data['ArtistID'] = data['ArtistID'].replace('\'','',regex=True)
data['ArtistName'] = data['ArtistName'].replace('b','',regex=True)
data['ArtistName'] = data['ArtistName'].replace('\'','',regex=True)
data['Title'] = data['Title'].replace('b','',regex=True)
data['Title'] = data['Title'].replace('\'','',regex=True)
data['AudioMd5'] = data['AudioMd5'].replace('b','',regex=True)
data['AudioMd5'] = data['AudioMd5'].replace('\'','',regex=True)
data.reset_index(drop=True, inplace=True)

#Data plotting
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
data['SongID']=le.fit_transform(data.SongID)
data['ArtistID']=le.fit_transform(data.ArtistID)
data['AudioMd5']=le.fit_transform(data.AudioMd5)
data['ArtistName']=le.fit_transform(data.ArtistName)
data['Title']=le.fit_transform(data.Title )

print(len(data))

import matplotlib.pyplot as plt
from matplotlib import rc
font = {'family' : 'monospace', 'weight' : 'bold', 'size'   : 10}
rc('font', **font)
plt.rcParams['figure.figsize'] = [20, 15]
plt.rcParams['lines.linewidth'] = 1.0
plt.rcParams['lines.markersize'] = 5.0

def draw_histograms(df, variables, n_rows, n_cols):
    fig=plt.figure()
    for i, var_name in enumerate(variables):
        ax=fig.add_subplot(n_rows,n_cols,i+1)
        df[var_name].hist(bins=10,ax=ax)
        ax.set_title(var_name)
    fig.tight_layout()  # Improves appearance a bit.
    plt.show()

draw_histograms(data, data.columns, 5, 4)
plt.savefig('data_plot.png', bbox_inches='tight')
plt.close(1)

#Feature exploration
data.drop(['SongID','ArtistID', 'ArtistName', 'Title','AudioMd5', 'Year','SongNumber'], axis=1, inplace=True)
data.to_csv('SongCSV_clean.csv')
print(data.head(10))

print(len(data))

X = data.loc[:,data.columns!='mode']
print(X[:10])

y = data['mode']
print(y[:10])

import seaborn as sns # data visualization library
import matplotlib.pyplot as plt
import math

ax = sns.countplot(y, label="Count", palette='seismic')
Y, N = y.value_counts()
print('Number of mode 1: ', Y)
print('Number of mode 0 : ', N)

#correlation map
f,ax = plt.subplots(figsize=(12, 10))
sns.heatmap(X.corr(), annot=True, linewidths=.5, fmt= '.1f', ax=ax)
plt.savefig('correlation_map.png', bbox_inches='tight')
plt.close(1)

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import f1_score,confusion_matrix
from sklearn.metrics import accuracy_score

# split data train 70 % and test 30 %
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

#random forest classifier with n_estimators=10 (default)
clf_rf = RandomForestClassifier(n_estimators=100, criterion='gini', max_depth=None, random_state=None)

clr_rf = clf_rf.fit(X_train,y_train)

ac = accuracy_score(y_test,clf_rf.predict(X_test))
print('Accuracy is: ',ac)
cm = confusion_matrix(y_test,clf_rf.predict(X_test))
sns.set(rc={'figure.figsize':(10,5)})
sns.heatmap(cm,annot=True,fmt="d")
plt.savefig('train_test_accuracy.png', bbox_inches='tight')
plt.close(2)

clf_rf_1 = RandomForestClassifier(n_estimators=100, criterion='gini', max_depth=None, random_state=None)
clr_rf_1 = clf_rf_1.fit(X_train,y_train)
importances = clr_rf_1.feature_importances_
std = np.std([tree.feature_importances_ for tree in clf_rf.estimators_],
             axis=0)
indices = np.argsort(importances)[::-1]

# Print the feature ranking
print("Feature ranking:")

for f in range(X_train.shape[1]):
    print("%d. feature %d (%f)" % (f + 1, indices[f], importances[indices[f]]))

# Plot the feature importances of the forest

plt.figure(1, figsize=(15, 10))
plt.title("Feature importances")
plt.bar(range(X_train.shape[1]), importances[indices],
       color="b", yerr=std[indices], align="center")
plt.xticks(range(X_train.shape[1]), X_train.columns[indices],rotation=90)
plt.xlim([-1, X_train.shape[1]])
plt.savefig('feature_importance.png', bbox_inches='tight')
plt.close(3)

print("--- %s seconds ---" % (time.time() - start_time))

## TASK 2: MODE PREDICTION

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import time

data = pd.read_csv('SongCSV.csv')
start_time = time.time()

data['SongHotness'] = data['SongHotness'].replace(0, np.nan)
data.dropna(subset=['SongHotness'], inplace=True)
data.drop(['SongID','ArtistID', 'ArtistName', 'Title','AudioMd5', 'Year' ], axis=1, inplace=True)
data.reset_index(drop=True, inplace=True)

X = data.loc[:,data.columns!='mode']
print(len(X))
y = data['mode']
print(len(y))

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

#SVC

from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
from sklearn.model_selection import GridSearchCV
print("Generating SVC...")

svm = SVC()

param_grid1 = {'C': [0.001, 0.01, 0.1],
              'gamma': [0.001, 0.01, 0.1]
             }

CV1 = GridSearchCV(svm,
                  param_grid1,
                  scoring='accuracy',
                  return_train_score=True,
                  n_jobs=-1,
		  cv=5)

CV1.fit(X_train, y_train)

print('best params: ', CV1.best_params_)
print('best score: %.3f' % CV1.best_score_)
print('accuracy score: %.3f' % CV1.score(X_test, y_test))

pred1 = CV1.predict(X_test)
ac1 = accuracy_score(y_test,pred1)
print('Accuracy is: ',ac1)

# KNN

from sklearn.neighbors import KNeighborsClassifier

print("Generating kNN...")

knn = KNeighborsClassifier()

param_grid2 = {'n_neighbors': np.arange(4,100)}

CV2 = GridSearchCV(knn,
                  param_grid2,
                  return_train_score=True,
                  n_jobs=-1,
		  cv=5)

CV2.fit(X_train, y_train)

print('best params: ', CV2.best_params_)
print('best score: %.3f' % CV2.best_score_)
print('accuracy score: %.3f' % CV2.score(X_test, y_test))

pred2 = CV2.predict(X_test)
ac2 = accuracy_score(y_test,pred2)
print('Accuracy is: ',ac2)

#Random Forest Classification

from sklearn.ensemble import RandomForestClassifier

print("Generating Random Forest Classifier...")

rfc = RandomForestClassifier()

param_grid3 = {'n_estimators': [50, 100, 200],
               'max_depth': [10, 20, 30],
              'criterion': ['gini'],
              }

CV3 = GridSearchCV(rfc,
                  param_grid3,
                  scoring='accuracy',
                  return_train_score=True,
                  n_jobs=-1,
		  cv=5)

CV3.fit(X_train, y_train)
print('best params: ', CV3.best_params_)
print('best score: %.3f' % CV3.best_score_)
print('accuracy score: %.3f' % CV3.score(X_test, y_test))

pred3 = CV3.predict(X_test)
ac3 = accuracy_score(y_test,pred3)
print('Accuracy is: ',ac3)

#SGD

from sklearn.linear_model import SGDClassifier

print("Generating SGD...")

sgdc = SGDClassifier()

param_grid4 = {'loss': [ "log"],
              'penalty': ["l1", "l2", "elasticnet"],
              'max_iter': [10000,100000,1000000],
              'alpha': [0.0001, 0.01, 0.1, 1]
              }

CV4 = GridSearchCV(sgdc,
                  param_grid4,
                  scoring='accuracy',
                  return_train_score=True,
                  n_jobs=-1,
		  cv=5)

CV4.fit(X_train, y_train)

print('best params: ', CV4.best_params_)
print('best score: %.3f' % CV4.best_score_)
print('accuracy score: %.3f' % CV4.score(X_test, y_test))

pred4 = CV4.predict(X_test)
ac4 = accuracy_score(y_test,pred4)
print('Accuracy is: ',ac4)

d = {'Model':['SVC','KNN','Random Forest','SGD'],'Accuracy':[ac1, ac2, ac3, ac4]}

agg_scores = pd.DataFrame(data = d)
agg_scores.plot(x='Model',y='Accuracy',kind='bar')
plt.savefig('model_comparison.png', bbox_inches='tight')
plt.close(1)

print("--- %s seconds ---" % (time.time() - start_time))

## TASK 3: ARTIST RECOMMENDATION

import numpy as np
import pandas as pd
import re
import sklearn
from sklearn.model_selection import train_test_split
import numpy as np

data = pd.read_csv('SongCSV.csv')

data['SongID'] = data['SongID'].replace('b','',regex=True)
data['SongID'] = data['SongID'].replace('\'','',regex=True)
data['ArtistID'] = data['ArtistID'].replace('b','',regex=True)
data['ArtistID'] = data['ArtistID'].replace('\'','',regex=True)
data['ArtistName'] = data['ArtistName'].replace('b','',regex=True)
data['ArtistName'] = data['ArtistName'].replace('\'','',regex=True)
data['Title'] = data['Title'].replace('b','',regex=True)
data['Title'] = data['Title'].replace('\'','',regex=True)

data['Song'] = data["ArtistName"] + ' - ' + data["Title"]
song_grouped = data.groupby(['Song']).agg({'SongNumber': 'count'}).reset_index()
grouped_sum = song_grouped['SongNumber'].sum()
song_grouped['percentage']  = song_grouped['SongNumber'].div(grouped_sum)*100
song_grouped.sort_values(['SongNumber', 'Song'], ascending = [0,1])

artists = data['ArtistID'].unique()
print(len(artists))

# from Recommenders import Recommenders
train_data, test_data = train_test_split(data, test_size = 0.20, random_state=0)

#Class for Popularity based Recommender System model
class popularity_recommender_py():
    def __init__(self):
        self.train_data = None
        self.ArtistID = None
        self.SongID = None
        self.popularity_recommendations = None

    #Create the popularity based recommender system model
    def create(self, train_data, ArtistID, SongID):
        self.train_data = train_data
        self.ArtistID = ArtistID
        self.SongID = SongID

        #Get a count of ArtistID for each unique song as recommendation score
        train_data_grouped = train_data.groupby([self.SongID]).agg({self.ArtistID: 'count'}).reset_index()
        train_data_grouped.rename(columns = {'ArtistID': 'score'},inplace=True)

        #Sort the songs based upon recommendation score
        train_data_sort = train_data_grouped.sort_values(['score', self.SongID], ascending = [0,1])

        #Generate a recommendation rank based upon score
        train_data_sort['Rank'] = train_data_sort['score'].rank(ascending=0, method='first')

        #Get the top 10 recommendations
        self.popularity_recommendations = train_data_sort.head(10)

    #Use the popularity based recommender system model to make recommendations
    def recommend(self, ArtistID):
        artist_recommendations = self.popularity_recommendations

        #Add user_id column for which the recommendations are being generated
        artist_recommendations['ArtistID'] = ArtistID

        #Bring user_id column to the front
        cols = artist_recommendations.columns.tolist()
        cols = cols[-1:] + cols[:-1]
        artist_recommendations = artist_recommendations[cols]

        return artist_recommendations

pm = popularity_recommender_py()
pm.create(train_data, 'ArtistID', 'Song')

#user the popularity model to make some prediction
ArtistID = artists[8]
print(pm.recommend(ArtistID))

## TASK 4: YEAR PREDICTION

import numpy as np
import pandas as pd

data = pd.read_csv('SongCSV.csv')
data['Year'] = data['Year'].replace(0, np.nan)
data['SongHotness'] = data['SongHotness'].replace(0, np.nan)
data.dropna(subset=['Year', 'SongHotness'], inplace=True)
data = data[data.Year>1990]

data.drop(['SongID','ArtistID', 'ArtistName', 'Title','AudioMd5'], axis=1, inplace=True)

nsongs = {}
for y in range(1991,2009):
    nsongs[y] = len(data[data.Year==y])
    print("Year=%d, nsongs=%d" % (y, nsongs[y]))

X = data.loc[:,data.columns!='Year']
y = data.Year

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler().fit(X)
X_scaled = scaler.transform(X)

from sklearn.model_selection import train_test_split
X_train, X_test,  y_train, y_test = train_test_split(X_scaled,y,train_size=0.8, random_state=0)

from sklearn.ensemble import RandomForestClassifier
forest = RandomForestClassifier(n_estimators=100, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', n_jobs=None, random_state=None)
forest.fit(X_train, y_train)
print("Score of training set: {:.3f}".format(forest.score(X_train, y_train)))
print("Score of test set: {:.3f}".format(forest.score(X_test, y_test)))

y_pred = forest.predict(X_test)
y_pred

from sklearn.metrics import classification_report,confusion_matrix
print("Classification Report")
print(classification_report(y_pred, y_test))
labels = np.unique(y_test)
print("Confusion Matrix")
a = confusion_matrix(y_pred, y_test, labels=labels)
pd.DataFrame(a, index=labels, columns=labels)

names = list(data.columns)
print(names)
X_names = names
def plot_feature_importances(model):
    n_features = X.shape[1]
    plt.barh(range(n_features), model.feature_importances_, align='center', color='orange', label=50)
    plt.yticks(np.arange(n_features), X_names)
    plt.title('Feature importance for dataset')
    plt.xlabel("Feature importance")
    plt.ylabel("Feature")

from matplotlib import pyplot as plt
plot_feature_importances(forest)

from sklearn.linear_model import SGDClassifier
sgdc = SGDClassifier(loss='log', penalty='elasticnet', alpha=0.0001, l1_ratio=0.15, fit_intercept=True, max_iter=2000, tol=0.001, shuffle=True, verbose=0, epsilon=0.1, n_jobs=None, random_state=None, learning_rate='optimal', eta0=0.0, power_t=0.5, early_stopping=False, validation_fraction=0.1, n_iter_no_change=5, class_weight=None, warm_start=False, average=False)
print(sgdc)

sgdc.fit(X_train, y_train)
print("Score of training set: {:.3f}".format(sgdc.score(X_train, y_train)))
print("Score of test set: {:.3f}".format(sgdc.score(X_test, y_test)))

y_pred_sgd = sgdc.predict(X_test)

cr = classification_report(y_test, y_pred_sgd)
print(cr)

cm = confusion_matrix(y_test, y_pred_sgd)
print(cm)

## TASK 5: SONG POPULARITY

import numpy as np
import pandas as pd

data = pd.read_csv('SongCSV.csv')

data['Year'] = data['Year'].replace(0, np.nan)
data['SongHotness'] = data['SongHotness'].replace(0, np.nan)

data.dropna(subset=['Year', 'SongHotness'], inplace=True)
data = data[data.Year>1990]

data['SongID'] = data['SongID'].replace('b','',regex=True)
data['SongID'] = data['SongID'].replace('\'','',regex=True)
data['ArtistID'] = data['ArtistID'].replace('b','',regex=True)
data['ArtistID'] = data['ArtistID'].replace('\'','',regex=True)
data['ArtistName'] = data['ArtistName'].replace('b','',regex=True)
data['ArtistName'] = data['ArtistName'].replace('\'','',regex=True)
data['Title'] = data['Title'].replace('b','',regex=True)
data['Title'] = data['Title'].replace('\'','',regex=True)
data['AudioMd5'] = data['AudioMd5'].replace('b','',regex=True)
data['AudioMd5'] = data['AudioMd5'].replace('\'','',regex=True)

data.groupby(data.Year).mean().reset_index()

song_hotness_mean = data.SongHotness.mean()
threshold = song_hotness_mean
data.loc[data.SongHotness>=threshold,'isPopular'] = 1
data.loc[data.SongHotness<threshold,'isPopular'] = 0

#Most Popular Songs
data.sort_values(by=['SongHotness','Year'],ascending=False)[['Title','ArtistName','SongHotness','Year']].head(10)

from sklearn.ensemble import RandomForestRegressor
X = data.drop(['SongHotness','Year','isPopular'],axis=1)
X = X.select_dtypes(exclude=[object])
Y = data['SongHotness'].values

model = RandomForestRegressor(n_estimators=100,max_depth=40)
model.fit(X,Y)

features = X.columns
feature_importances = model.feature_importances_

features_data = pd.DataFrame({'Features': features, 'Importance Score': feature_importances})
features_data.sort_values('Importance Score', inplace=True, ascending=False)

#KNN
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split

X = data.drop('SongHotness',axis=1)
X = X.select_dtypes(exclude=[object])
X_top_5_features = X[list(features_data.head().Features)]
Y = data['isPopular'].values

trainX, testX, trainY, testY = train_test_split(X_top_5_features, Y, train_size=0.70)

knn = KNeighborsClassifier()
knn.fit(trainX,trainY)

pred1 = knn.predict(testX)

print('Score of knn model: %.3f' % knn.score(testX, testY))
ac1 = accuracy_score(testY,pred1)
print('Accuracy of knn model:',ac1)

#SVC
from sklearn.svm import SVC
svm = SVC(C=1.0, kernel='rbf', degree=3, gamma='scale',random_state=None)
svm.fit(trainX,trainY)
pred2= svm.predict(testX)
print('Score of SVC model: %.3f' % svm.score(testX, testY))
ac2 = accuracy_score(testY,pred2)
print('Accuracy of SVC model:',ac2)

#Random Forest
from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(n_estimators=100,criterion='gini', max_depth=None, min_samples_split=2,min_samples_leaf=1,min_weight_fraction_leaf=0.0,max_features='auto',random_state=None)

rf.fit(trainX,trainY)
pred3= rf.predict(testX)
print('Score of random forest model: %.3f' % rf.score(testX, testY))
ac3 = accuracy_score(testY,pred3)
print('Accuracy of Random forest model: ',ac3)

#SGD

from sklearn.linear_model import SGDClassifier

sgdc = SGDClassifier()
sgdc.fit(trainX,trainY)
pred4= sgdc.predict(testX)
print('Score of SGDClassifier model: %.3f' % sgdc.score(testX, testY))
ac4 = accuracy_score(testY,pred4)
print('Accuracy of SGDClassifier model: ',ac4)

## TASK 6: SONG RECOMMENDATION

import numpy as np
import pandas as pd

data = pd.read_csv('SongCSV.csv')

data['SongID'] = data['SongID'].replace('b','',regex=True)
data['SongID'] = data['SongID'].replace('\'','',regex=True)
data['ArtistID'] = data['ArtistID'].replace('b','',regex=True)
data['ArtistID'] = data['ArtistID'].replace('\'','',regex=True)
data['ArtistName'] = data['ArtistName'].replace('b','',regex=True)
data['ArtistName'] = data['ArtistName'].replace('\'','',regex=True)
data['AudioMd5'] = data['AudioMd5'].replace('b','',regex=True)
data['AudioMd5'] = data['AudioMd5'].replace('\'','',regex=True)
data['Title'] = data['Title'].replace('b','',regex=True)
data['Title'] = data['Title'].replace('\'','',regex=True)
data['Title'] = data['Title'].replace('(, )','',regex=True)
print(len(data))

data['Song'] = data["SongID"] + ' - ' + data["Title"]
song_grouped = data.groupby(['Song']).agg({'SongID': 'count'}).reset_index()
grouped_sum = song_grouped['SongID'].sum()
song_grouped.sort_values(['SongID', 'Song'], ascending = [0,1])
song_grouped.rename(columns = {'SongID': 'Songcount'},inplace=True)

artists = data['ArtistID'].unique()
print(len(artists))

import sklearn
from sklearn.model_selection import train_test_split

train_data, test_data = train_test_split(data, test_size = 0.20, random_state=0)

import numpy as np

class popularity_recommender_py():
    def __init__(self):
        self.train_data = None
        self.ArtistID = None
        self.SongID = None
        self.popularity_recommendations = train_data

    def recommend(self, ArtistID):
        artist_recommendations = self.popularity_recommendations
        artist_recommendations = artist_recommendations[artist_recommendations['ArtistID'] == ArtistID]
        artist_recommendations = artist_recommendations.loc[:,['Title','ArtistName']]
        return artist_recommendations

pm = popularity_recommender_py()
ArtistID = artists[6]
print(pm.recommend(ArtistID))


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

from datetime import date
from odoo import models, fields, api, _
from odoo.exceptions import UserError

class ChangeManagement(models.Model):
    _name = 'change.management.request'
    _description = 'Change Management Request'
    _inherit = ['portal.mixin', 'mail.activity.mixin', 'mail.thread']
    _order = 'create_date DESC'

    state = fields.Selection([
        ('draft', 'New'),
        ('submit', 'Submitted'),
        ('change_coordinator_approved', 'Change Coordinator Approved'),
        ('grc_analyst_approved', 'GRC Analyst Approved'),
        ('service_delivery_approved', 'Service Delivery Approved'),
        ('director_operation_approved', 'Director of Operations Approved'),
        ('approved', 'SDM Implementation Approved'),
        ('reject', 'Rejected'),
        ], string='Approval Status', readonly=False, index=True, copy=False, default='draft', tracking=True)

    ref = fields.Char(string='Order Reference', readonly=True, required=True, index=True, copy=False, default='New')

    name = fields.Char(string='Summary', required=True, copy=False)
    change_type = fields.Char(string='Change Type')

    change_category = fields.Selection([
        ('onboarding', 'Onboarding'),
        ('decommissioning', 'Decommissioning'),
        ('cross_connect', 'Cross-Connect'),
        ('others', 'Others'),
        ], string='Change Category', copy=False, tracking=True)

    partner_id = fields.Many2one(comodel_name="res.partner", string='Client')
    actual_start_date = fields.Date(string='Actual Start Date')
    actual_end_date = fields.Date(string='Actual End Date')
    closure_date_time = fields.Datetime(string='Closure date and time')
    status = fields.Selection([
        ('draft', 'New'),
        ('request_for_authorization', 'Request For Authorization'),
        ('planning_in_progress', 'Planning In Progress'),
        ('cancelled', 'Cancelled'),
        ], string='Status', copy=False, default='draft', tracking=True)

    change_coordinator = fields.Many2one(comodel_name="res.users", string='Change Coordinator')
    change_manager = fields.Many2one(comodel_name="res.users", string='Change Manager')

    submit_date = fields.Date(string='Submit Date', default=date.today())

    coordinator_group = fields.Char(string='Coordinator Group')
    service = fields.Char(string='Service')
    summary = fields.Char(string='Summary')
    change_class = fields.Char(string='Class')
    change_reason = fields.Char(string='Change Reason')
    target_date = fields.Date(string='Target date')
    impact = fields.Selection([
        ('minor', 'Minor/Localized'),
        ('major', 'Major'),
        ], string='Impact', tracking=True)
    urgency = fields.Selection([
        ('low', 'Low'),
        ('mid', 'Medium'),
        ('high', 'Hign'),
        ], string='Urgency', tracking=True)
    priority = fields.Selection([
        ('0', 'Nil'),
        ('1', 'Low'),
        ('2', 'Medium'),
        ('3', 'High'),
        ('4', 'Critical'),
        ], string='Priority', default='1', tracking=True)

    change_type = fields.Selection([
        ('minor', 'Minor'),
        ('major', 'Major'),
        ], string='Change Type', default='minor', tracking=True, compute='_compute_change_type')

    risk_level = fields.Char(string='Risk Level')
    manager_group = fields.Char(string='Manager Group')

    scheduled_start_date = fields.Date(string='Scheduled Start Date & Time')
    scheduled_end_date = fields.Date(string='Scheduled End Date & time')

    scope_and_impact = fields.Text(string='Scope and Impact of Change')
    docs_impacted = fields.Char(string='Documents Impacted')

    controls_required = fields.Text(string='Controls required')
    financial_impact = fields.Text(string='Financial Impact')
    risk_assessment = fields.Text(string='Risk assessment')

    #Business Justification for the Proposed Change
    business_case_benefits = fields.Text(string='Business Case / Benefits')
    technical_case = fields.Text(string='Technical case, for and against the Change')
    estimated_cost_resources_required = fields.Text(string='Estimated Cost / Resources required for the change.')

    def _compute_change_type(self):
        for type in self:
            if type.priority == '0' or type.priority == '1' or type.priority == '2':
                type.change_type = 'minor'
            else:
                type.change_type = 'major'

    additional_info = fields.Char(string='Additional Information')

    tasks_line_ids = fields.One2many('change.management.tasks', 'change_management_id', string="Tasks", copy=True)

    #Approvals
    change_coordinator_id = fields.Many2one(comodel_name="res.users", string='Change Coordinator', readonly=True)
    change_coordinator_approval_date = fields.Date(string='Change Coordinator Approval Date', readonly=True)

    grc_analyst_id = fields.Many2one(comodel_name="res.users", string='GRC Analyst', readonly=True)
    grc_approval_date = fields.Date(string='GRC Approval Date', readonly=True)

    service_delivery_manager_id = fields.Many2one(comodel_name="res.users", string='Service Delivery Manger', readonly=True)
    service_delivery_approval_date = fields.Date(string='Service Delivery Manger Approval Date', readonly=True)

    director_operation_id = fields.Many2one(comodel_name="res.users", string='Director of Operations', readonly=True)
    director_operation_approval_date = fields.Date(string='Director of Operations Approval Date', readonly=True)

    @api.model
    def create(self, vals):
        if vals.get('ref', 'New') == 'New':
            vals['ref'] = self.env['ir.sequence'].next_by_code('change.management') or '/'
        res = super(ChangeManagement, self).create(vals)
        res.action_alert_manager()
        return res

    #alerts cc
    def action_alert_manager(self):
        group_id = self.env['ir.model.data'].xmlid_to_object('rc_service.group_ccm')
        partner_ids = []
        for user in group_id.users:
            partner_ids.append(user.partner_id.id)
        self.message_subscribe(partner_ids=partner_ids)
        subject = "A new Change Management Request '{}' with reference '{}', needs review".format(self.name, self.ref)
        self.message_post(subject=subject,body=subject,partner_ids=partner_ids)

    #submit to change coordinator
    def button_submit(self):
        self.write({'state': 'submit'})
        #self.submit_date = date.today()
        partner_ids = []
        if not self.change_coordinator:
            raise UserError(_('Please Specify the Change Coordinator.'))
        partner_ids.append(self.change_coordinator.partner_id.id)
        self.message_subscribe(partner_ids=partner_ids)
        subject = "Change Management Request '{}', needs approval".format(self.ref)
        self.message_post(subject=subject,body=subject,partner_ids=partner_ids)

    #submit to GRC Analyst
    def button_change_coordinator_approve(self):
        self.write({'state': 'change_coordinator_approved'})
        self.change_coordinator_id = self.env.uid
        self.change_coordinator_approval_date = date.today()
        group_id = self.env['ir.model.data'].xmlid_to_object('rc_service.group_grc')
        partner_ids = []
        for user in group_id.users:
            partner_ids.append(user.partner_id.id)
        self.message_subscribe(partner_ids=partner_ids)
        subject = "Change Management Request '{}', has been approved by change coordinator and needs your approval".format(self.ref)
        self.message_post(subject=subject,body=subject,partner_ids=partner_ids)

    #submit to Service Delivery Manger
    def button_grc_analyst_approve(self):
        self.write({'state': 'grc_analyst_approved'})
        self.grc_analyst_id = self.env.uid
        self.grc_approval_date = date.today()
        group_id = self.env['ir.model.data'].xmlid_to_object('rc_service.group_smd_manager')
        partner_ids = []
        for user in group_id.users:
            partner_ids.append(user.partner_id.id)
        self.message_subscribe(partner_ids=partner_ids)
        subject = "Change Management Request '{}', has been approved by GRC Analyst and needs your approval".format(self.ref)
        self.message_post(subject=subject,body=subject,partner_ids=partner_ids)

    #submit to Director of Operations
    def button_service_delivery_approve(self):
        self.write({'state': 'service_delivery_approved'})
        self.service_delivery_manager_id = self.env.uid
        self.service_delivery_approval_date = date.today()
        group_id = self.env['ir.model.data'].xmlid_to_object('rc_service.group_doo')
        partner_ids = []
        for user in group_id.users:
            partner_ids.append(user.partner_id.id)
        self.message_subscribe(partner_ids=partner_ids)
        subject = "Change Management Request '{}', has been approved by Service Delivery Manger and needs your approval".format(self.ref)
        self.message_post(subject=subject,body=subject,partner_ids=partner_ids)

    #approved by Director of Operations
    def button_director_operation_approve(self):
        self.write({'state': 'director_operation_approved'})
        self.director_operation_id = self.env.uid
        self.director_operation_approval_date = date.today()
        subject = "Change Management Request '{}', has been Approved by Director of Operations".format(self.name)
        partner_ids = []
        for partner in self.message_partner_ids:
            partner_ids.append(partner.id)
        self.message_post(subject=subject,body=subject,partner_ids=partner_ids)

    #approved by SDM
    def button_approve(self):
        self.write({'state': 'approved'})
        subject = "Change Management Request Implementation for '{}', has been Approved by SDM".format(self.name)
        partner_ids = []
        for partner in self.message_partner_ids:
            partner_ids.append(partner.id)
        self.message_post(subject=subject,body=subject,partner_ids=partner_ids)

    def button_reject(self):
        self.write({'state': 'reject'})
        subject = "Change Management Request '{}', has been rejected".format(self.name)
        partner_ids = []
        for partner in self.message_partner_ids:
            partner_ids.append(partner.id)
        self.message_post(subject=subject,body=subject,partner_ids=partner_ids)

    def button_reset(self):
        self.write({'state': 'new'})

class ChangeManagementTasks(models.Model):
    _name = 'change.management.tasks'
    _description = 'Change Management Tasks'
    _inherit = ['portal.mixin', 'mail.activity.mixin', 'mail.thread']
    _order = 'create_date DESC'

    change_management_id = fields.Many2one(comodel_name="change.management.request", string='change management')

    name = fields.Char(string='Task Name', required=True)
    summary = fields.Char(string='Task Summary')
    details = fields.Char(string='Task Details / Note')

    start_date = fields.Datetime(string='Scheduled Start Date & Time')
    end_date = fields.Datetime(string='Scheduled End Date & Time')


import os
import sqlite3 as sql
from enum import Enum
from typing import List, Optional, Dict

from model.config import Config
from model.default_database import InitSqlCommands
from view.messagebox_window_class import Messagebox, MessageBoxType

class Operation(Enum):
    SELECT = 0
    DELETE = 1
    UPDATE = 2
    INSERT = 3
    SELECT_COLUMNS = 4

class SqliteController:
    def __init__(self):
        config = Config()
        self.__db_path = config.get_db_path() + r'\RMsystem.db'
        self.__conn = None
        self.cursor = None
        self.message_box = Messagebox()
        if self.__db_path:
            self.__open(self.__db_path)
        else:
            self.message_box.window_execution('Database path is missing!', MessageBoxType.ERROR)

    def __open(self, path):
        try:
            if os.path.isfile(self.__db_path):
                self.__conn = sql.connect(self.__db_path)
                self.cursor = self.__conn.cursor()
            else:
                self.__conn = sql.connect(self.__db_path)
                self.cursor = self.__conn.cursor()
                self.__create_default_db()
        except sql.Error as e:
            self.message_box.window_execution(f'Hiba az adatbázisban\n{e}!', MessageBoxType.ERROR)

    def __create_default_db(self):
        for command in InitSqlCommands:
            self.cursor.execute(command.value)
            self.__conn.commit()
        admin_params = ('Admin', '12345')
        self.cursor.execute("INSERT INTO User (UserName, Password) VALUES (?,?)", admin_params)
        self.__conn.commit()

    def execute_command(self, operation: Operation, main_table_name: str, column_names: List[str] = None,
                        where_condition: Dict[str, str] = None, order_by: str = None,
                        insertion_value_dict: Dict[str, str] = None, update_value_dict: Dict[str, str] = None,
                        set_id: int = None) -> List[str]:
        try:
            if operation is Operation.SELECT:
                if column_names:
                    column_name_string = ", ".join([column for column in column_names])
                else:
                    column_name_string = '*'
                if where_condition:
                    where_condition_string = " WHERE "
                    flag = len(where_condition) - 1
                    for key, value in where_condition.items():
                        where_condition_string += f"{key} = '{value}'"
                        if flag:
                            where_condition_string += " AND "
                        flag -= 1
                else:
                    where_condition_string = ''
                if order_by:
                    order_by_string = f" ORDER BY {order_by}"
                else:
                    order_by_string = ''
                select_query_string = f"SELECT {column_name_string} FROM {main_table_name}{where_condition_string}{order_by_string}"
                print(select_query_string)
                c = self.cursor.execute(select_query_string)
                rows = c.fetchall()
                return rows
            elif operation is Operation.INSERT:
                insertion_columns_string = ', '.join([key for key in insertion_value_dict.keys()])
                insert_query_string = f"INSERT INTO {main_table_name} ({insertion_columns_string}) VALUES ({', '.join([' ?'] * len(insertion_value_dict.keys()))})"
                print(insert_query_string)
                self.cursor.execute(insert_query_string, tuple([value for value in insertion_value_dict.values()]))
                self.__conn.commit()
            elif operation is Operation.UPDATE:
                for key, value in update_value_dict.items():
                    update_query_string = f"UPDATE {main_table_name} SET {key} = '{value}' WHERE {main_table_name + 'ID'} = '{str(set_id)}'"
                    print(update_query_string)
                    self.cursor.execute(update_query_string)
                    self.__conn.commit()
            elif operation is Operation.DELETE:
                delete_query_string = f"DELETE FROM {main_table_name} WHERE {main_table_name + 'ID'} = {str(set_id)}"
                print(delete_query_string)
                self.cursor.execute(delete_query_string)
                self.__conn.commit()
            elif operation is Operation.SELECT_COLUMNS:
                select_columns_query = f"SELECT * FROM {main_table_name}"
                cursor = self.__conn.execute(select_columns_query)
                names = [desc[0] for desc in cursor.description]
                return names
        except sql.Error as e:
            self.message_box.window_execution(f'Operation hiba!\n{e}', MessageBoxType.ERROR)

    def execute_command_2(self, operation: Operation, table_name: str, datas: List[Dict[str, str]]) -> Optional[
        List[str]]:
        try:
            if operation is Operation.INSERT:
                columns_srting = ', '.join([key for key in datas[0].keys()])
                query = f"INSERT INTO {table_name} ({columns_srting}) VALUES ({', '.join([' ?'] * len(datas[0]))})"
                self.cursor.execute(query, tuple([value for value in datas[0].values()]))
            elif operation is Operation.SELECT:
                column_string = "*"
                condition_string = ''
                for data in datas:
                    if type(data) is list:
                        column_string = ", ".join([column for column in data])
                    if type(data) is dict:
                        condition_string = f" WHERE "
                        flag = len(data) - 1
                        for key, value in data.items():
                            condition_string += f"{key} = '{value}'"
                            if flag:
                                condition_string += " AND "
                            flag -= 1
                query = f"SELECT {column_string} FROM {table_name}{condition_string}"
                print(query)
                c = self.cursor.execute(query)
                rows = c.fetchall()
                return rows
            elif operation is Operation.UPDATE:
                query = f"UPDATE {table_name} SET {datas[0]} = {datas[1]} WHERE {table_name + 'ID'} = {datas[2]}"
                self.cursor.execute(query)
            elif operation is Operation.DELETE:
                query = f"DELETE FROM {table_name} WHERE {table_name + 'ID'} = {datas[0]}"
        except sql.Error as e:
            self.message_box.window_execution(f'Operation hiba!\n{e}', MessageBoxType.ERROR)

    def __close_db(self):
        self.__conn.commit()
        self.__conn.close()


import json
import cherrypy
import json_rpc
import subprocess

class Module (object):

    # Expose secure when we get admin-secret working
    @json_rpc.expose_anonymous
    def run(self):
        if not cherrypy.request.method in ['POST', 'PUT']:
            raise cherrypy.HTTPError(405)

        command = cherrypy.request.body.read().decode()
        try:
            code = 0
            results = subprocess.check_output(command, shell=True)
        except subprocess.CalledProcessError as e:
            cherrypy.response.status = 500
            code = e.returncode
            results = e.output

        return {'code': code, 'output': results.decode().strip()}


#!/usr/local/bin/python3
import re
import sys
import pyperclip

template_file = sys.argv[1]

file = open(template_file,mode='r')
text = file.read()
file.close()

replacements = {}
placeholders = re.findall('\{(.*?)\}', text)
for placeholder in placeholders:
    try:
        namevariable,default_value = placeholder.split('|')
        if namevariable in replacements: continue
        user_input = input(f"{namevariable}: [{default_value}]?")
        if user_input == '':
            user_input = default_value

        text = text.replace(f"{{{placeholder}}}", user_input)

    except ValueError:
        namevariable = placeholder
        if namevariable in replacements: continue
        user_input = input(f"{namevariable}?")

        text = text.replace(f"{{{placeholder}}}", user_input)

    replacements[namevariable] = user_input

print(text)
pyperclip.copy(text)


"""add publish to schedule

Revision ID: dd48947ccf75
Revises: e2cfd701b7ac
Create Date: 2017-07-24 15:26:58.144810

"""

# revision identifiers, used by Alembic.
revision = 'dd48947ccf75'
down_revision = 'e2cfd701b7ac'

from alembic import op
import sqlalchemy as sa

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('conference_schedules', schema=None) as batch_op:
        batch_op.add_column(sa.Column('publish', sa.Boolean(), nullable=True))

    ### end Alembic commands ###

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('conference_schedules', schema=None) as batch_op:
        batch_op.drop_column('publish')

    ### end Alembic commands ###


from django.urls import include, path
from django.contrib.auth import views as auth_views

from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('read/<int:id>', views.read, name='read'),
    path('delete/<int:id>', views.delete, name='delete'),
    path('update/<int:id>', views.update, name='update'),
    path('read/<int:id>', views.read, name='read'),
    path('read/', views.index, name='index'),
    path('create/', views.create, name='create'),
    path('order/<int:id>', views.order, name='order'),
    # path('who/<int:who_id>',views.who, name='who'),
    # path('what/<int:what_id>',views.what, name='what'),
    # path('login/', views.login, name='login'),
    # path('logout/', views.logout, name='logout'),
    path('accounts/', include('django.contrib.auth.urls'))
]


#!/usr/bin/env python
from setuptools import setup

with open('README.md') as f:
    long_description = f.read()

setup(
    name='django-nucleus',
    description='Theme for Django admin',
    short_description='Theme for Django admin',
    long_description=long_description,
    long_description_content_type='text/markdown',
    version='0.1.2',
    url='http://github.com/lukasvinclav/django-nucleus',
    packages=[
        'nucleus',
    ],
    include_package_data=True,
    install_requires=('django', ),
    classifiers=[
        'Programming Language :: Python',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Operating System :: OS Independent',
        'Environment :: Web Environment',
        'Intended Audience :: Developers',
        'Framework :: Django',
    ],
    keywords="django admin theme clean minimal ui sidebar"
)


import pandas as pd
import warnings

warnings.filterwarnings("ignore")

# Read the "u.data" file to extract useful information in a dataframe named 'df'.
columns_name = ["user_id", "item_id", "rating", "timestamp"]
df = pd.read_csv("u.data", sep = "\t", names = columns_name)

# Read the "u.item" file to extract useful information in a dataframe named 'movie_titles'.
movie_titles = pd.read_csv("u.item", sep = "\|", header = None)
movie_titles = movie_titles[[0, 1]]
movie_titles.columns = ["item_id", "title"]

# Merge two different dataframes named df and movie_title respectively into a df named df
df = pd.merge(df, movie_titles, on = "item_id")

# Create a new dataframe named 'ratings' and store the information "mean rating" and "number of ratings".
ratings = pd.DataFrame(df.groupby("title").mean()["rating"])
ratings["no_of_ratings"] = pd.DataFrame(df.groupby("title").count()["rating"])
ratings = ratings.sort_values(by = "rating", ascending = False)

# It stores user's data that which user gave what rating to which movie.
movie_matrix = df.pivot_table(index = "user_id", columns = "title", values = "rating")

# This function takes your watched movie name as argument and returns different movie names accordingly.
def predict_movies(movie_name):
    movie_user_rating = movie_matrix[movie_name]
    similar_to_movie =  movie_matrix.corrwith(movie_user_rating)

    similar_to_movie = pd.DataFrame(similar_to_movie, columns = ["Corelaton"])
    similar_to_movie.dropna(inplace = True)
    similar_to_movie = similar_to_movie.join(ratings["no_of_ratings"])

    prediction = similar_to_movie[similar_to_movie["no_of_ratings"] > 100].sort_values("Corelaton", ascending = False)
    return prediction

# Here you have to enter the name of your favorite movie, so that more such movies can be predicted.
predicted_movie_names = predict_movies("Titanic (1997)")
print(predicted_movie_names.head(n = 10))


import math

class GTPEstimator:

    @staticmethod
    def from_txt(filename):

        with open(filename, 'r') as f:
            raw_data = f.read()
            lines = raw_data.split('\n')

        # convert every line to an integer and
        # ignore empty lines (empty strings)
        observations = [int(line) for line in lines if line]

        return GTPEstimator(observations)

    def __init__(self, obs):
        self.obs = [o for o in obs]
        self._update_internals()

    def _update_internals(self):
        self._k = len(self.obs)
        if self._k: self._m = max(self.obs)

    def add_observations(self, o_arr):
        '''
            Add a set of new observation to our set of observations.

            Parameters
            ----------
            obs_arr :: list[float | int] :
                a list of observed values
        '''

        self.obs.extend(o_arr)
        self._update_internals()

    def add_observation(self, o):
        '''
            Add a single new observation to our set of observations.

            Parameters
            ----------
            o :: float | int :
                an observed value
        '''
        self.obs.append(o)
        self._update_internals()

    def estimate_maximum(self, method = 'freq'):
        '''
            Estimate the maximum value of our population given observed samples.

            Parameters
            ----------
            method :: str{'freq' | 'bayes_med' | 'bayes_mean'} :
                the method with which to calculate the maximum of this population
        '''

        if self._k == 0: raise RuntimeError('No observed samples!')

        if method == 'freq':
            N_hat = self._m * (1 + (1 / self._k)) - 1
        elif method == 'bayes_med':
            N_hat = self._m + ((self._m * math.log(2)) / (self._k - 1))
        elif method == 'bayes_mean':
            N_hat = (self._m - 1) * ((self._k - 1) / (self._k - 2))
        else:
            raise RuntimeError('Invalid method for estimation.')

        return N_hat

    def get_confidence_intervals(self):
        '''
            Returns the 95% confidence interval as a tuple of (lower bound, upper bound)
        '''
        if self._k == 0: raise RuntimeError('No observed samples!')

        lower_bound = self._m
        upper_bound = self._m * (20 ** (1 / self._k))

        return (lower_bound, upper_bound)


import os
import logging

from django.apps import apps
from django.conf import settings
from django.core.management import call_command
from django.core.management.base import CommandError
from django.core.management.commands.makemessages import Command as BaseCommand

CONF_NAME = 'TRANSLATED_APPS'

class Command(BaseCommand):
    help = "Make messages, including apps as configured."

    def add_arguments(self, parser):
        super(Command, self).add_arguments(parser)
        parser.add_argument('--app', '-m', default=[], action='append',
            dest='apps', help='Only scan the contents of these app folders.')
        parser.add_argument('--configured-list', dest='configured_list',
            action='store_true', help='Load a list of apps from the settings.')

    def handle(self, apps=(), configured_list=False, **options):
        self.apps = list(self.parse_apps(apps, configured_list))
        if self.apps:
            print("Selecting apps: %s" % ", ".join(self.apps))
        super(Command, self).handle(**options)

    @staticmethod
    def parse_apps(in_apps, configured_list):
        for app in list(set(settings.INSTALLED_APPS) & set(in_apps)):
            in_apps.remove(app)
            yield app

        if in_apps:
            raise CommandError("App(s) not found %s" % ", ".join(in_apps))

        if configured_list:
            if hasattr(settings, CONF_NAME):
                for item in getattr(settings, CONF_NAME):
                    yield item
            else:
                raise CommandError("Config %s is not set." % CONF_NAME)

    def find_files(self, root):
        if self.apps:
            ab_root = os.path.abspath(root)
            files = []
            for app_name in self.apps:
                app = apps.get_app_config(app_name)
                path = app.path.replace(ab_root, root)
                files += super(Command, self).find_files(path)
            return files
        return super(Command, self).find_files(root)


'''문제 설명
배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다.
이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다.
단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다.
예를 들면,
arr = [1, 1, 3, 3, 0, 1, 1] 이면 [1, 3, 0, 1] 을 return 합니다.
arr = [4, 4, 4, 3, 3] 이면 [4, 3] 을 return 합니다.
배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.
제한사항
배열 arr의 크기 : 1,000,000 이하의 자연수
배열 arr의 원소의 크기 : 0보다 크거나 같고 9보다 작거나 같은 정수

입출력 예
arr	answer
[1,1,3,3,0,1,1]	[1,3,0,1]
[4,4,4,3,3]	[4,3]
입출력 예 설명
입출력 예 #1,2
문제의 예시와 같습니다.

방법3
def solution (arr):
    answer = []
    length = len(arr)#들어온 파라미터값 세기
    for i in range(0, length):#전체 범위 값 중에서 하나씩 세기
        answer.append(arr[i])#전체 값 넣기
        # print(answer)
        for j in range(i+1, length):#더한 값 루프문
            # if arr[i] == arr[i+1]:  # 인덱스의 숫자 같은지 확인
            answer.remove(arr[i])# 같은 숫자를 arr에서 앞에서부터 제거
                # break
    print(answer)
    return answer
문제 앞에서 1을 제거하면서 for문으로 계속해서 제거해버림

def solution(arr):
    answer = []
    length = len(arr)#들어온 파라미터값 세기
    for j in range(0, length):#전체 범위 값 중에서 하나씩 세기
        answer.append(arr[j])#전체 값 넣기
        # print(answer)
        for i in range(j+1, length):#더한 값 루프문
            if arr[j] == arr[j+1]:# 인덱스의 숫자 같은지 확인
                print(arr[j])
                answer.pop()#뒤에서부터 제거(문제가 앞에서 제거하는 것이 문제이므로)
                break #break을 안하면 IndexError: pop from empty list 발생
            #range(0, length)1,1,1,4,4,1,1를 4번씩 돔
            #in answer경우, 2,2,3,2,3,4,2,3,4
            #answer.remove(arr[i])

    print(answer)
    return answer

문제 속도가 느려서 효율이 떨어짐 70점->list comprehension
'''
def solution(arr):
    a = [j for j in arr]# 1,2,3,3,0,1,1
    # c = [i for i in arr if a[i] == a[i + 1]] #0
    # b = [i for i in arr if a[i]==a[i+1] or a.remove(i)] # 1,3,1
    d = [i for i in range(len(arr[i]-1))]
    print(d)

    return d
a1 = [1, 1, 3, 3, 0, 1, 1]
solution(a1)

'''방법1 뒤에 1이 또 붙을 때 제거되지 않아야 함
from collections import OrderedDict

def solution(arr):
    answer = list(OrderedDict.fromkeys(arr))
    return answer

방법2 뒤에 1이 또 붙을 때 제거되지 않아야 함
def solution(arr):
    answer = []
    for i in arr:
        if i not in answer:
            answer.append(i)
    print(answer)
    return answer

1. 중복제거 - set을 이용하면 중복은 제거되나 순서가 뒤죽박죽
2. 순서 유지
for문 not in으로 할 경우 뒤에 똑같은 숫자가 와도 나타나지 않음'''


#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from urllib.parse import urlparse

from ironic_lib import metrics_utils
from oslo_log import log
from oslo_utils import importutils
from oslo_utils import timeutils

from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import states
from ironic.conductor import periodics
from ironic.conductor import utils as manager_utils
from ironic.conf import CONF
from ironic.drivers import base
from ironic.drivers.modules import deploy_utils
from ironic.drivers.modules.redfish import firmware_utils
from ironic.drivers.modules.redfish import utils as redfish_utils
from ironic import objects

LOG = log.getLogger(__name__)

METRICS = metrics_utils.get_metrics_logger(__name__)

sushy = importutils.try_import('sushy')

class RedfishFirmware(base.FirmwareInterface):

    _FW_SETTINGS_ARGSINFO = {
        'settings': {
            'description': (
                'A list of dicts with firmware components to be updated'
            ),
            'required': True
        }
    }

    def __init__(self):
        super(RedfishFirmware, self).__init__()
        if sushy is None:
            raise exception.DriverLoadError(
                driver='redfish',
                reason=_("Unable to import the sushy library"))

    def get_properties(self):
        """Return the properties of the interface.

        :returns: dictionary of <property name>:<property description> entries.
        """
        return redfish_utils.COMMON_PROPERTIES.copy()

    def validate(self, task):
        """Validates the driver information needed by the redfish driver.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue on malformed parameter(s)
        :raises: MissingParameterValue on missing parameter(s)
        """
        redfish_utils.parse_driver_info(task.node)

    def cache_firmware_components(self, task):
        """Store or update Firmware Components on the given node.

        This method stores Firmware Components to the firmware_information
        table during 'cleaning' operation. It will also update the timestamp
        of each Firmware Component.

        :param task: a TaskManager instance.
        :raises: UnsupportedDriverExtension, if the node's driver doesn't
            support getting Firmware Components from bare metal.
        """

        node_id = task.node.id
        settings = []
        # NOTE(iurygregory): currently we will only retrieve BIOS and BMC
        # firmware information trough the redfish system and manager.

        system = redfish_utils.get_system(task.node)

        bios_fw = {'component': 'bios',
                   'current_version': system.bios_version}
        settings.append(bios_fw)

        # NOTE(iurygregory): normally we only relay on the System to
        # perform actions, but to retrieve the BMC Firmware we need to
        # access the Manager.
        try:
            manager = redfish_utils.get_manager(task.node, system)
            bmc_fw = {'component': 'bmc',
                      'current_version': manager.firmware_version}
            settings.append(bmc_fw)
        except exception.RedfishError:
            LOG.warning('No manager available to retrieve Firmware '
                        'from the bmc of node %s', task.node.uuid)

        if not settings:
            error_msg = (_('Cannot retrieve firmware for node %s.')
                         % task.node.uuid)
            LOG.error(error_msg)
            raise exception.UnsupportedDriverExtension(error_msg)

        create_list, update_list, nochange_list = (
            objects.FirmwareComponentList.sync_firmware_components(
                task.context, node_id, settings))

        if create_list:
            for new_fw in create_list:
                new_fw_cmp = objects.FirmwareComponent(
                    task.context,
                    node_id=node_id,
                    component=new_fw['component'],
                    current_version=new_fw['current_version']
                )
                new_fw_cmp.create()
        if update_list:
            for up_fw in update_list:
                up_fw_cmp = objects.FirmwareComponent.get(
                    task.context,
                    node_id=node_id,
                    name=up_fw['component']
                )
                up_fw_cmp.last_version_flashed = up_fw.get('current_version')
                up_fw_cmp.current_version = up_fw.get('current_version')
                up_fw_cmp.save()

    @METRICS.timer('RedfishFirmware.update')
    @base.deploy_step(priority=0, argsinfo=_FW_SETTINGS_ARGSINFO)
    @base.clean_step(priority=0, abortable=False,
                     argsinfo=_FW_SETTINGS_ARGSINFO,
                     requires_ramdisk=True)
    @base.cache_firmware_components
    def update(self, task, settings):
        """Update the Firmware on the node using the settings for components.

        :param task: a TaskManager instance.
        :param settings: a list of dictionaries, each dictionary contains the
            component name and the url that will be used to update the
            firmware.
        :raises: UnsupportedDriverExtension, if the node's driver doesn't
            support update via the interface.
        :raises: InvalidParameterValue, if validation of the settings fails.
        :raises: MissingParamterValue, if some required parameters are
            missing.
        :returns: states.CLEANWAIT if Firmware update with the settings is in
            progress asynchronously of None if it is complete.
        """
        node = task.node

        update_service = redfish_utils.get_update_service(node)

        LOG.debug('Updating Firmware on node %(node_uuid)s with settings '
                  '%(settings)s',
                  {'node_uuid': node.uuid, 'settings': settings})

        self._execute_firmware_update(node, update_service, settings)

        fw_upd = settings[0]
        wait_interval = fw_upd.get('wait')

        deploy_utils.set_async_step_flags(
            node,
            reboot=True,
            skip_current_step=True,
            polling=True
        )

        return deploy_utils.reboot_to_finish_step(task, timeout=wait_interval)

    def _execute_firmware_update(self, node, update_service, settings):
        """Executes the next firmware update to the node

        Executes the first firmware update in the settings list to the node.

        :param node: the node that will have a firmware update executed.
        :param update_service: the sushy firmware update service.
        :param settings: remaining settings for firmware update that needs
            to be executed.
        """
        fw_upd = settings[0]
        component_url, cleanup = self._stage_firmware_file(node, fw_upd)

        LOG.debug('Applying new firmware %(url)s for %(component)s on node '
                  '%(node_uuid)s',
                  {'url': fw_upd['url'], 'component': fw_upd['component'],
                   'node_uuid': node.uuid})

        task_monitor = update_service.simple_update(component_url)

        fw_upd['task_monitor'] = task_monitor.task_monitor_uri
        node.set_driver_internal_info('redfish_fw_updates', settings)

        if cleanup:
            fw_clean = node.driver_internal_info.get('firmware_cleanup')
            if not fw_clean:
                fw_clean = [cleanup]
            elif cleanup not in fw_clean:
                fw_clean.append(cleanup)
            node.set_driver_internal_info('firmware_cleanup', fw_clean)

    def _continue_updates(self, task, update_service, settings):
        """Continues processing the firmware updates

        Continues to process the firmware updates on the node.

        Note that the caller must have an exclusive lock on the node.

        :param task: a TaskManager instance containing the node to act on.
        :param update_service: the sushy firmware update service
        :param settings: the remaining firmware updates to apply
        """
        node = task.node
        fw_upd = settings[0]
        wait_interval = fw_upd.get('wait')
        if wait_interval:
            time_now = str(timeutils.utcnow().isoformat())
            fw_upd['wait_start_time'] = time_now

            LOG.debug('Waiting at %(time)s for %(seconds)s seconds after '
                      '%(component)s firmware update %(url)s '
                      'on node %(node)s',
                      {'time': time_now,
                       'seconds': wait_interval,
                       'component': fw_upd['component'],
                       'url': fw_upd['url'],
                       'node': node.uuid})

            node.set_driver_internal_info('redfish_fw_updates', settings)
            node.save()
            return

        if len(settings) == 1:
            self._clear_updates(node)

            LOG.info('Firmware updates completed for node %(node)s',
                     {'node': node.uuid})

            manager_utils.notify_conductor_resume_clean(task)
        else:
            settings.pop(0)
            self._execute_firmware_update(node,
                                          update_service,
                                          settings)
            node.save()
            manager_utils.node_power_action(task, states.REBOOT)

    def _clear_updates(self, node):
        """Clears firmware updates artifacts

        Clears firmware updates from driver_internal_info and any files
        that were staged.

        Note that the caller must have an exclusive lock on the node.

        :param node: the node to clear the firmware updates from
        """
        firmware_utils.cleanup(node)
        node.del_driver_internal_info('redfish_fw_updates')
        node.del_driver_internal_info('firmware_cleanup')
        node.save()

    @METRICS.timer('RedfishFirmware._query_update_failed')
    @periodics.node_periodic(
        purpose='checking if async update of firmware component failed',
        spacing=CONF.redfish.firmware_update_fail_interval,
        filters={'reserved': False, 'provision_state': states.CLEANFAIL,
                 'maintenance': True},
        predicate_extra_fields=['driver_internal_info'],
        predicate=lambda n: n.driver_internal_info.get('redfish_fw_updates'),
    )
    def _query_update_failed(self, task, manager, context):

        """Periodic job to check for failed firmware updates."""
        # A firmware update failed. Discard any remaining firmware
        # updates so when the user takes the node out of
        # maintenance mode, pending firmware updates do not
        # automatically continue.
        LOG.error('Update firmware failed for node %(node)s. '
                  'Discarding remaining firmware updates.',
                  {'node': task.node.uuid})

        task.upgrade_lock()
        self._clear_updates(task.node)

    @METRICS.timer('RedfishFirmware._query_update_status')
    @periodics.node_periodic(
        purpose='checking async update of firmware component',
        spacing=CONF.redfish.firmware_update_fail_interval,
        filters={'reserved': False, 'provision_state': states.CLEANWAIT},
        predicate_extra_fields=['driver_internal_info'],
        predicate=lambda n: n.driver_internal_info.get('redfish_fw_updates'),
    )
    def _query_update_status(self, task, manager, context):
        """Periodic job to check firmware update tasks."""
        self._check_node_redfish_firmware_update(task)

    @METRICS.timer('RedfishFirmware._check_node_redfish_firmware_update')
    def _check_node_redfish_firmware_update(self, task):
        """Check the progress of running firmware update on a node."""

        node = task.node

        settings = node.driver_internal_info['redfish_fw_updates']
        current_update = settings[0]

        try:
            update_service = redfish_utils.get_update_service(node)
        except exception.RedfishConnectionError as e:
            # If the BMC firmware is being updated, the BMC will be
            # unavailable for some amount of time.
            LOG.warning('Unable to communicate with firmware update service '
                        'on node %(node)s. Will try again on the next poll. '
                        'Error: %(error)s',
                        {'node': node.uuid,
                         'error': e})
            return

        wait_start_time = current_update.get('wait_start_time')
        if wait_start_time:
            wait_start = timeutils.parse_isotime(wait_start_time)

            elapsed_time = timeutils.utcnow(True) - wait_start
            if elapsed_time.seconds >= current_update['wait']:
                LOG.debug('Finished waiting after firmware update '
                          '%(firmware_image)s on node %(node)s. '
                          'Elapsed time: %(seconds)s seconds',
                          {'firmware_image': current_update['url'],
                           'node': node.uuid,
                           'seconds': elapsed_time.seconds})
                current_update.pop('wait', None)
                current_update.pop('wait_start_time', None)

                self._continue_updates(task, update_service, settings)
            else:
                LOG.debug('Continuing to wait after firmware update '
                          '%(firmware_image)s on node %(node)s. '
                          'Elapsed time: %(seconds)s seconds',
                          {'firmware_image': current_update['url'],
                           'node': node.uuid,
                           'seconds': elapsed_time.seconds})

            return

        try:
            task_monitor = redfish_utils.get_task_monitor(
                node, current_update['task_monitor'])
        except exception.RedfishError:
            # The BMC deleted the Task before we could query it
            LOG.warning('Firmware update completed for node %(node)s, '
                        'firmware %(firmware_image)s, but success of the '
                        'update is unknown.  Assuming update was successful.',
                        {'node': node.uuid,
                         'firmware_image': current_update['url']})
            self._continue_updates(task, update_service, settings)
            return

        if not task_monitor.is_processing:
            # The last response does not necessarily contain a Task,
            # so get it
            sushy_task = task_monitor.get_task()

            # Only parse the messages if the BMC did not return parsed
            # messages
            messages = []
            if sushy_task.messages and not sushy_task.messages[0].message:
                sushy_task.parse_messages()

            if sushy_task.messages is not None:
                messages = [m.message for m in sushy_task.messages]

            task.upgrade_lock()
            if (sushy_task.task_state == sushy.TASK_STATE_COMPLETED
                    and sushy_task.task_status in
                    [sushy.HEALTH_OK, sushy.HEALTH_WARNING]):
                LOG.info('Firmware update succeeded for node %(node)s, '
                         'firmware %(firmware_image)s: %(messages)s',
                         {'node': node.uuid,
                          'firmware_image': current_update['url'],
                          'messages': ", ".join(messages)})

                self._continue_updates(task, update_service, settings)
            else:
                error_msg = (_('Firmware update failed for node %(node)s, '
                               'firmware %(firmware_image)s. '
                               'Error: %(errors)s') %
                             {'node': node.uuid,
                              'firmware_image': current_update['url'],
                              'errors': ",  ".join(messages)})

                self._clear_updates(node)
                if task.node.clean_step:
                    manager_utils.cleaning_error_handler(task, error_msg)
                else:
                    manager_utils.deploying_error_handler(task, error_msg)

        else:
            LOG.debug('Firmware update in progress for node %(node)s, '
                      'firmware %(firmware_image)s.',
                      {'node': node.uuid,
                       'firmware_image': current_update['url']})

    def _stage_firmware_file(self, node, component_update):

        try:
            url = component_update['url']
            name = component_update['component']
            parsed_url = urlparse(url)
            scheme = parsed_url.scheme.lower()
            source = (CONF.redfish.firmware_source).lower()

            # Keep it simple, in further processing TLS does not matter
            if scheme == 'https':
                scheme = 'http'

            # If source and scheme is HTTP, then no staging,
            # returning original location
            if scheme == 'http' and source == scheme:
                LOG.debug('For node %(node)s serving firmware for '
                          '%(component)s from original location %(url)s',
                          {'node': node.uuid, 'component': name, 'url': url})
                return url, None

            # If source and scheme is Swift, then not moving, but
            # returning Swift temp URL
            if scheme == 'swift' and source == scheme:
                temp_url = firmware_utils.get_swift_temp_url(parsed_url)
                LOG.debug('For node %(node)s serving original firmware at '
                          'for %(component)s at %(url)s via Swift temporary '
                          'url %(temp_url)s',
                          {'node': node.uuid, 'component': name, 'url': url,
                           'temp_url': temp_url})
                return temp_url, None

            # For remaining, download the image to temporary location
            temp_file = firmware_utils.download_to_temp(node, url)

            return firmware_utils.stage(node, source, temp_file)

        except exception.IronicException:
            firmware_utils.cleanup(node)


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse

import numpy as np
import tensorflow as tf

import os
import urllib
from collections import defaultdict

try:
    from urllib.parse import unquote, urlparse, parse_qs
except ImportError:
    from urlparse import unquote, urlparse, parse_qs

import json

from flask import Flask
from flask import request
from flask import url_for
from flask import jsonify
from flask_cors import CORS

from werkzeug.utils import secure_filename
import re
import base64

"""
Uploader variables
"""
UPLOAD_PATH = '/some-path'
ALLOWED_EXTENSIONS = set(['jpg', 'jpeg', 'png'])

"""
Predictor variables
"""
MODEL_FILE = "../model/output_graph.pb"
FILE_NAME = ""
LABEL_FILE = "../model/output_labels.txt"

INPUT_HEIGHT = 299
INPUT_WIDTH = 299
INPUT_MEAN = 0
INPUT_STD = 255
INPUT_LAYER = "Placeholder"
OUTPUT_LAYER = "final_result"

app = Flask(__name__)
app.config["UPLOAD_PATH"] = UPLOAD_PATH
CORS(app)

class Predictor():
    def load_graph(self):
        graph = tf.Graph()
        graph_def = tf.GraphDef()

        with open(MODEL_FILE, "rb") as f:
            graph_def.ParseFromString(f.read())
        with graph.as_default():
            tf.import_graph_def(graph_def)

        return graph

    def read_tensor_from_image_file(
            self,
            file_name,
            input_height=299,
            input_width=299,
            input_mean=0,
            input_std=255):
        input_name = "file_reader"
        output_name = "normalized"

        file_reader = tf.read_file(file_name, input_name)
        if file_name.endswith(".png"):
            image_reader = tf.image.decode_png(
                    file_reader, channels=3, name="png_reader")
        elif file_name.endswith(".gif"):
            image_reader = tf.squeeze(
                    tf.image.decode_gif(file_reader, name="gif_reader"))
        elif file_name.endswith(".bmp"):
            image_reader = tf.image.decode_bmp(file_reader, name="bmp_reader")
        else:
            image_reader = tf.image.decode_jpeg(
                    file_reader, channels=3, name="jpeg_reader")

        float_caster = tf.cast(image_reader, tf.float32)
        dims_expander = tf.expand_dims(float_caster, 0)
        resized = tf.image.resize_bilinear(dims_expander, [input_height, input_width])
        normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])
        sess = tf.Session()
        result = sess.run(normalized)

        return result

    def load_labels(self, label_file):
        label = []
        proto_as_ascii_lines = tf.gfile.GFile(label_file).readlines()
        for l in proto_as_ascii_lines:
            label.append(l.rstrip())
        return label

@app.route("/predict", methods=["GET", "POST"])
def predict():
    image_data = request.json['image']
    image_base_64 = image_data[22:]

    with open("base64data", "wb") as fh:
        fh.write(image_data)

    with open("uploaded_image.png", "wb") as fh:
        fh.write(base64.b64decode(image_base_64))

    main_predictor = Predictor()

    data = request.args

    file_name = "./uploaded_image.png"

    graph = main_predictor.load_graph()
    t = main_predictor.read_tensor_from_image_file(
            file_name = file_name,
            input_height=INPUT_HEIGHT,
            input_width=INPUT_WIDTH,
            input_mean=INPUT_MEAN,
            input_std=INPUT_STD)
    input_name = "import/" + INPUT_LAYER
    output_name = "import/" + OUTPUT_LAYER
    input_operation = graph.get_operation_by_name(input_name)
    output_operation = graph.get_operation_by_name(output_name)

    with tf.Session(graph=graph) as sess:
        results = sess.run(output_operation.outputs[0], {
            input_operation.outputs[0]: t
            })
        results = np.squeeze(results)

    top_k = results.argsort()[-5:][::-1]
    labels = main_predictor.load_labels(LABEL_FILE)
    label_results = defaultdict(str)

    for i in top_k:
        label_results[labels[i]] = str(results[i])

    return jsonify(label_results)

if __name__ == '__main__':
    port = os.environ.get('PORT', 5000)
    app.run(host='127.0.0.1', port = port)