from django.shortcuts import render,redirect
from CourseApp.models import studentCourse,student

# Create your views here.
def fun(request):
    return render(request,'home.html')
def addcourse(request):
    return render(request,'addcourse.html')
def addcoursedb(request):
    if request.method == "POST":
        course_name=request.POST['Course']
        course_fee=request.POST['fee']
        course=studentCourse(course_name=course_name,fee=course_fee)
        course.save()
        return redirect('/')
def student_reg(request):
    courses=studentCourse.objects.all()
    return render(request,'addstudent.html',{'course':courses})

def add_studentdb(request):
    if request.method =='POST':
        student_name=request.POST['student_name']
        student_address=request.POST['student_address']
        age=request.POST['student_age']
        jdate=request.POST['joining_date']
        sel=request.POST['course']
        coursel=studentCourse.objects.get(id=sel)
        Student=student(student_name=student_name,student_address=student_address,student_age=age,joining_date=jdate,course=coursel)
        Student.save()
        return redirect('/')

def showstudent(request):
    Student=student.objects.all()
    return render(request,'showstudent.html',{'students':Student})

def edit(request,pk):
    Student=student.objects.get(id=pk)

    course=studentCourse.objects.all()
    return render(request,'edit.html',{'stud':Student,'course':course})

def editdb(request,pk):
    if request.method=='POST':
        Student=student.objects.get(id=pk)
        Student.student_name=request.POST['student_name']
        Student.student_address=request.POST['student_address']
        Student.student_age=request.POST['student_age']
        Student.joining_date=request.POST['joining_date']
        sel=request.POST['course']
        coursel=studentCourse.objects.get(id=sel)
        Student.course=coursel
        Student.save()
        return redirect('showstudent')
    return render(request,'edit.html')

def delete(request,pk):
    s = student.objects.get(id=pk)
    s.delete()
    return redirect('showstudent')


import time
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statistics import mode

from sklearn.model_selection import KFold

# comment1

def f1_score(y_true, y_pred):
    """
    Function for calculating the F1 score

    Params
    ------
    y_true  : the true labels shaped (N, C),
              N is the number of datapoints
              C is the number of classes
    y_pred  : the predicted labels, same shape
              as y_true

    Return
    ------
    score   : the F1 score, shaped (N,)

    """
    tp = 0
    tn = 0
    fp = 0
    fn = 0

    for i in zip(y_true, y_pred):
        if i[0] == 1:
            if i[1] == 1:
                tp += 1
            else:
                fn += 1
        else:
            if i[1] == 0:
                tn += 1
            else:
                fp += 1

    precision = tp / (tp + fp)
    recall = tp / (tp + fn)
    print("precision = " + str(precision))
    print("recall = " + str(recall))
    f1 = 2 * ((precision * recall) / (precision + recall))
    return f1

def gini_index(groups, classes):
    """
    Function for calculating the gini index
        -- The goodness of the split

    Params
    ------
    groups  : A list containing two groups of samples
                resulted by the split
    classes : The classes in the classification problem
                e.g. [0,1]

    Return
    ------
    gini    : the gini index of the split
    """
    split = []
    gini = 1
    for g in groups:
        ones = sum(g)
        split.append(ones / len(g))
    for s in split:
        gini -= s ** 2
    return gini

def get_split(x_train, y_train):
    """
    Function to generate the split which results in
        the best gini_index

    Params
    ------
    x_train : the input data (n_samples, n_features)
    y_train : the input label (n_samples,)

    Return
    ------
    {gini_index, split_index, split_value}
    """
    """
    returns a Node?

    take dim1
    sort it and keep y_train attached to it
    get every index where y_train == 1, store in i
    create an array for each index j in i having all 1s beginning from j (0s for all indexes less than j)
    sum all these arrays to obtain Nl1 vector
    Nl = [1, 2, 3, 4...., S] where S is the number of samples
    we know Nl + Nr = sum(1s in Y)
    create Nr1 using sum(1s in Y) - Nl1
    create Nl0 using Nl - Nl1
    create Nr0 using Nr - Nr1

    G(split) = (Nl0 * Nl1)/ Nl + (Nr0 * Nr1)/Nr
    now find min(array) to get best split index

    """
    ginis = []
    for dim in x_train.T:
        dimsort = dim[np.argsort(dim)]
        ysort = y_train.reshape(-1)[np.argsort(dim)]
        dimy = np.array([dim, y_train.reshape(-1, )]).T

        samples = len(y_train)
        dimy = dimy[np.argsort(dimy[:, 1])]
        ones_indexes = np.argwhere(ysort == 1)[:, 0]
        ones_array = []
        for i in ones_indexes:
            # ones_array.append([0 if j < i else 1 for j in range(samples)])
            temp = [0] * i
            temp.extend([1] * (samples - i - 1))
            ones_array.append(temp)
        ones_array = np.array(ones_array)
        Nl1 = ones_array.sum(axis=0)
        Nl = np.arange(1, samples)
        Nr = np.arange(samples - 1, 0, -1)
        Nr1 = sum(y_train) - Nl1
        Nl0 = Nl - Nl1
        Nr0 = Nr - Nr1
        g_split = (2 / samples) * (((Nl0 * Nl1) / Nl) + ((Nr0 * Nr1) / Nr))
        g_min_val = min(g_split)
        g_min_index = np.where(g_split == min(g_split))[0]
        val_at_min = dimsort[g_min_index][0]

        ginis.append([g_min_val, int(g_min_index[0]), val_at_min])
    ginis = np.array(ginis)
    best_feature_index = np.argmin(ginis[:, 0])  # column number of the best index
    # traning_xy = np.array(x_train,y_train.reshape(-1,))
    sorted_x_train = x_train[np.argsort(x_train[:, best_feature_index])]
    sorted_y_train = y_train[np.argsort(x_train[:, best_feature_index])]
    sample_index = ginis[best_feature_index][1]
    left_data_x = sorted_x_train[0:int(sample_index)]
    left_data_y = sorted_y_train[:int(sample_index)]

    right_data_x = sorted_x_train[int(sample_index):]
    right_data_y = sorted_y_train[int(sample_index):]

    left_node = (left_data_x, left_data_y)
    right_node = (right_data_x, right_data_y)
    split_index = best_feature_index
    split_value = ginis[best_feature_index][2]
    data = (left_node, right_node, split_index, split_value)
    return data

##########################################################
# Alternatively combine gini_index into get_split and
# find the split point using an array instead of a for
# loop, would speed up run time
##########################################################

class DecisionTree(object):
    """
    The Decision Tree classifier
    """

    def __init__(self, max_depth, min_size=5):
        """
        Params
        ------
        max_depth   : the maximum depth of the decision tree
        min_size    : the minimum observation points on a
                        leaf/terminal node
        """
        self.max_depth = max_depth
        self.min_size = min_size
        self.root = None
        self.left = None
        self.right = None
        # self.num_datapoints = None

    def split(self, data, depth):
        """
        Function called recursively to split
            the data in order to build a decision
            tree.

        Params
        ------
        data    : {left_node, right_node, split_index, split_value}
        depth   : the current depth of the node in the decision tree

        Return
        ------
        """
        # base case
        if depth > self.max_depth:
            a = data[0][1].reshape(-1)
            np.append(a, data[1][1].reshape(-1))
            self.root = (None, None, mode(a), None)
            return

        # change state
        # check number of data points in y_train of split

        self.root = get_split(data[0], data[1])
        self.left = DecisionTree(self.max_depth, self.min_size)
        self.right = DecisionTree(self.max_depth, self.min_size)
        self.left.fit(self.root[0][0], self.root[0][1], depth + 1)
        self.right.fit(self.root[1][0], self.root[1][1], depth + 1)

    def fit(self, x_train, y_train, depth=0):
        """
        Fitting the KNN classifier

        Hint: Build the decision tree using
                splits recursively until a leaf
                node is reached

        """
        self.depth = depth
        if (len(y_train) > self.min_size) and (depth < self.max_depth):
            # self.root = get_split(x_train, y_train)
            # self.num_datapoints = len(self.root[0][1]) + len(self.root[1][1])
            self.split((x_train, y_train), depth + 1)
        else:
            try:
                m = mode(y_train.reshape(-1))
            except:
                m = 1

            self.root = (None, None, m, None)
            return

    def predict(self, x_test):
        """
        Predicting the test data

        Hint: Run the test data through the decision tree built
                during training (self.tree)
        """
        prediction = None

        if self.root[-1] is None:
            prediction = self.root[2]

        else:
            if x_test[int(self.root[2])] < self.root[-1]:
                prediction = self.left.predict(x_test)

            else:
                prediction = self.right.predict(x_test)
        if prediction is None:
            print("prediction is None :/")
            raise ValueError
        return prediction

def main():
    # Example running the class DecisionTree

    print("running...")

    # Example running the class KNN
    x_train_path = "../../Data/x_train.csv"
    y_train_path = "../../Data/y_train.csv"

    x_df = np.genfromtxt(x_train_path, delimiter=',')
    y_df = np.genfromtxt(y_train_path, delimiter=',')

    # print(x_df)
    # # input(x_df.values.tolist()[:20])
    # x_train, y_train, x_test, y_test = train_test_split(x_df, y_df, test_size=0.2, random_state=2)
    #
    # knn = KNN(n_neighbors=5)
    # knn.fit(x_train.to_numpy().reshape(-1, 1), y_train)
    # y_pred = knn.predict(x_test.to_numpy().reshape(-1, 1))
    # score = f1_score(y_test, y_pred)
    # print(score)
    # input()
    ########################################
    # Simple Guide on KFold
    ########################################
    kf = KFold(n_splits=5)
    kf.get_n_splits(x_df)

    for i, (train_index, test_index) in enumerate(kf.split(x_df)):
        x_train, x_test = x_df[train_index], x_df[test_index]
        y_train, y_test = y_df[train_index], y_df[test_index]
        dt = DecisionTree(max_depth=5)
        print("calling fit...")
        dt.fit(x_train, y_train.reshape(-1, 1))
        y_pred = [dt.predict(x_test_i) for x_test_i in x_test]
        score = f1_score(y_test, y_pred)

        print(str(i) + " f1 score = " + str(score))

if __name__ == "__main__":
    main()


# from django.shortcuts import render
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.decorators import authentication_classes, permission_classes
# from rest_framework.authentication import SessionAuthentication
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.tokens import RefreshToken
from .serializers import UserRegisterSerializer, UserLogInSerializer, UserSerializer
from database.models import Word, WordLearned, User
from django.contrib.auth import login, logout
from django.shortcuts import get_object_or_404
from django.db.models import F

# from rest_framework.authtoken.models import Token

# Create your views here.
# class UserRegisterView(APIView):
#     def post(self, request):
#         serializer = UserRegisterSerializer(data = request.data)
#         if serializer.is_valid():
#             user = serializer.save()
#             return Response(serializer.data, status=status.HTTP_201_CREATED)
#         return Response(status=status.HTTP_400_BAD_REQUEST)

class UserRegisterView(APIView):
    def post(self, request):
        serializer = UserRegisterSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()

            refresh = RefreshToken.for_user(user)

            response_data = {
                'refresh': str(refresh),
                'access': str(refresh.access_token),
                'user': serializer.data
            }

            return Response(response_data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# class UserLogInView(APIView):
#     def post(self, request):
#         serializer = UserLogInSerializer(data = request.data)
#         if serializer.is_valid():
#             user = serializer.check_user(request.data)
#             login(request, user)
#             if not user.is_login:
#                 user.score += 100
#                 user.is_login = True
#                 user.save()
#             return Response(serializer.data, status=status.HTTP_200_OK)
#         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class UserLogInView(TokenObtainPairView):
    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)
        if response.status_code == 200:
            user = User.objects.get(username=request.data['username'])
            user.update_login()
            if not user.is_login:
                user.score += 100
                user.is_login = True
                user.save()
        return response

# class UserLogOutView(APIView):
#     def post(self, request):
#         logout(request)
#         return Response(status=status.HTTP_200_OK)

class UserLogOutView(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):
        try:
            refresh_token = request.data.get("refresh_token")
            if refresh_token:
                token = RefreshToken(refresh_token)
                token.blacklist()
            return Response(status=status.HTTP_205_RESET_CONTENT)
        except Exception as e:
            return Response(status=status.HTTP_400_BAD_REQUEST)

class UserView(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = (JWTAuthentication,)
    def get(self, request):
        serializer = UserSerializer(request.user)
        user = request.user
        if user:
            user.reset_quest_status()
        if not user.is_login:
            user.score += 100
            user.is_login = True
            user.save()
        return Response({'user': serializer.data}, status=status.HTTP_200_OK)

# class SessionDataView(APIView):
#     def get(self, request):
#         session_data = {}
#         if request.session:
#             # Retrieve session data
#             session_data['session_id'] = request.session.session_key
#             session_data['user_id'] = request.session.get('user_id', None)
#             session_data['username'] = request.session.get('username', None)
#             # Add more session data as needed
#         return Response(session_data)

@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
class WordLearnedView(APIView):
    def post(self, request):
        word_ids = request.data.get('word_ids', [])
        user = request.user  # Assuming you have user authentication in place

        for word_id in word_ids:
            word = get_object_or_404(Word, id=word_id)  # Retrieve the Word instance
            word_learned_exists = WordLearned.objects.filter(user_id=user, word_id=word).exists()
            if not word_learned_exists:
                WordLearned.objects.create(user_id=user, word_id=word)

        return Response({'message': 'Word IDs stored successfully'})

def ordinalize(number):
    suffixes = {1: 'st', 2: 'nd', 3: 'rd'}
    if 10 <= number % 100 <= 20:
        suffix = 'th'
    else:
        suffix = suffixes.get(number % 10, 'th')
    return f"{number}{suffix}"

@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
class LeaderboardAPIView(APIView):
    def get(self, request):
        users = User.objects.order_by('-score')  # Retrieve users sorted by score in descending order

        # Annotate the queryset with the rank based on the score
        users = users.annotate(rank=F('score'))

        leaderboard = []
        current_user = None
        for index, user in enumerate(users, start=1):
            if user == request.user:
                current_user = {
                    'rank': ordinalize(index),
                    'username': user.username,
                    'score': user.score
                }
            leaderboard.append({
                'rank': ordinalize(index),
                'username': user.username,
                'score': user.score
            })

        return Response({'leaderboard': leaderboard, 'current_user': current_user}, status=status.HTTP_200_OK)


from django import forms
from .models import Product

class ProductForm(forms.ModelForm):
    title = forms.CharField(label="Type your title here", widget=forms.TextInput(
        attrs={'placeholder': 'Type your title here'}))

    class Meta:
        model = Product
        fields = ["title", "description", "price"]

    # def clean_<name_of_form_field>
    def clean_title(self, *args, **kwargs):
        title = self.cleaned_data.get('title')
        if "ERROR" in title:
            raise forms.ValidationError("THIS IS NOT VALID TITLE")

        return title

class RawProductForm(forms.Form):
    title = forms.CharField(label="Type your title here", widget=forms.TextInput(
        attrs={'placeholder': 'Type your title here'}))
    description = forms.CharField(required=False,
                                  widget=forms.Textarea(attrs={
                                      "class": "new-class",
                                      "placeholder": "Type your description here",
                                      "rows": "20",
                                      "cols": "20",
                                  }),
                                  )
    price = forms.DecimalField(initial=100)


import streamlit as st
from scraping import check_user_existance, scrap_user_films
from streamlit_app.utils import custom_write, endline

def handle_input_user(user_id):
    user_name = st.session_state[f'input_user_{user_id}']
    st.session_state.session.insert_user(user_name, user_id)
    st.session_state.session.reset_user_df(user_id)

def users_page():
    base = st.container()

    col_1, col_2 = base.columns(2)

    col_1.text_input('User 1', value=st.session_state.user_1, key='input_user_1', on_change=handle_input_user,
                     kwargs={'user_id': 1})
    col_2.text_input('User 2', value=st.session_state.user_2, key='input_user_2', on_change=handle_input_user,
                     kwargs={'user_id': 2})

    for user_id, col in zip((1, 2), (col_1, col_2)):
        user_name = st.session_state.session.users.get(user_id, '')
        if user_name != '':
            in_db = st.session_state.data_control.check_user_is_in_db(user_name)
            if in_db:
                col.success(f'The user {user_name} is already in our database :)')
                if st.session_state.session.users_df[user_id] is None:
                    user_df = st.session_state.data_control.get_user_films(user_name)
                    st.session_state.session.insert_user_df(user_df, user_id)

                col.table(st.session_state.session.users_df[user_id])

            else:
                exists = check_user_existance(user_name)
                if not exists:
                    col.error(f'The user {user_name} does not exist')
                    continue

                col.success(f'The user {user_name} exists')
                if st.session_state.session.users_df[user_id] is None:
                    custom_write(col, 'Getting all-time watched movies list...', align='center',
                                 color=st.session_state.text_color)

                    df = scrap_user_films(user_name, col)
                    st.session_state.session.users_df[user_id] = df

                    st.session_state.data_control.add_user_to_db(user_name)
                    st.session_state.data_control.insert_table_in_db(user_name, table=df)
                endline(col)
                col.table(st.session_state.session.users_df[user_id])

if __name__ == '__main__':
    users_page()


import sys

def shift_char(char, shift):
    # keep track of casing
    isupper = 1 if char.isupper() else 0
    # convert to lower case and make 0-indexed
    result = ord(char.lower()) - ord('a')
    shift = ord(shift.lower()) - ord('a')
    # add shift
    result = (result + shift) % 26
    # convert back to character
    result = chr(result + ord('a'))
    if isupper:
        result = result.upper()
    return result

def caesar(message, shift):
    result = ''
    # for each character,
    for char in message:
        if char.isalpha():  # if it's in [a-zA-Z], shift it
            result += shift_char(char, shift)
        else:
            result += char  # otherwise just add it
    return result

if __name__ == '__main__':
    if len(sys.argv) < 3:
        print('Usage: python3 caesar.py [message] [character]')
    else:
        print(caesar(sys.argv[1], sys.argv[2]))


import importlib
import logging
log = logging.getLogger(__name__)

class MatrixFileHandler():
    """
    This class handles the load and save of the different Hi-C contact matrix formats.
    """

    def __init__(self, pFileType='cool', pMatrixFile=None, pChrnameList=None,
                 pApplyCorrectionCoolerLoad=None, pBedFileHicPro=None, pCorrectionFactorTable=None,
                 pCorrectionOperator=None, pEnforceInteger=None, pAppend=None, pFileWasH5=None, pHiCInfo=None, pHic2CoolVersion=None,
                 pDistance=None, pMatrixFormat=None, pLoadMatrixOnly=None, pNoCutIntervals=None):

        self.class_ = getattr(importlib.import_module('.' + pFileType.lower(), package='hicmatrix.lib'), pFileType.title())

        if pFileType == 'hicpro':
            self.matrixFile = self.class_(pMatrixFile=pMatrixFile, pBedFile=pBedFileHicPro)
        else:
            self.matrixFile = self.class_(pMatrixFile=pMatrixFile)
            if pFileType == 'cool':
                self.matrixFile.chrnameList = pChrnameList
                if pCorrectionFactorTable is not None:
                    self.matrixFile.correctionFactorTable = pCorrectionFactorTable
                if pCorrectionOperator is not None:
                    self.matrixFile.correctionOperator = pCorrectionOperator
                if pEnforceInteger is not None:
                    self.matrixFile.enforceInteger = pEnforceInteger
                if pAppend is not None:
                    self.matrixFile.appendData = pAppend
                if pFileWasH5 is not None:
                    self.matrixFile.fileWasH5 = pFileWasH5
                if pApplyCorrectionCoolerLoad is not None:
                    self.matrixFile.applyCorrectionLoad = pApplyCorrectionCoolerLoad
                if pHiCInfo is not None:
                    self.matrixFile.hic_metadata = pHiCInfo
                if pHic2CoolVersion is not None:
                    self.matrixFile.hic2cool_version = pHic2CoolVersion
                if pDistance is not None:
                    self.matrixFile.distance = pDistance
                if pMatrixFormat is not None:
                    self.matrixFile.matrixFormat = pMatrixFormat
                if pLoadMatrixOnly is not None:
                    self.matrixFile.matrixOnly = pLoadMatrixOnly
                if pNoCutIntervals is not None:
                    self.matrixFile.noCutIntervals = pNoCutIntervals

    def load(self):

        return self.matrixFile.load()

    def set_matrix_variables(self, pMatrix, pCutIntervals, pNanBins, pCorrectionFactors, pDistanceCounts):
        self.matrixFile.set_matrix_variables(pMatrix, pCutIntervals, pNanBins, pCorrectionFactors, pDistanceCounts)

    def save(self, pName, pSymmetric, pApplyCorrection):
        self.matrixFile.save(pName, pSymmetric, pApplyCorrection)

    def load_init(self):
        pass


from django.urls import path
from . import views
from django.conf.urls import url

from rest_framework.authtoken import views as authviews

app_name = 'reservations'

urlpatterns = [
    url(r'^login_user/$', views.login_user, name='login_user'),
    url(r'^register/$', views.register, name='register'),
    url(r'^(?P<event_id>[0-9]+)/reservation/$', views.reservation, name='reservation'),
    url(r'^$', views.index, name='index'),
    path('<int:pk>/', views.EventDetailView.as_view(), name='event_detail'),
    url(r'^api-token-auth/', authviews.obtain_auth_token),
    url(r'^(?P<event_id>[0-9]+)/upload/$', views.model_form_upload, name='upload'),
    url(r'^user_reservations/$', views.user_reservations, name='user_reservations'),
    url(r'^(?P<event_id>[0-9]+)/delete_confirm/$', views.delete_reservation, name='delete_object'),
    url(r'^logout_user/$', views.logout_usr, name='logout_user'),
    url(r'^add_campaign/$', views.event_form, name='add_campaign'),
    url(r'^like/$', views.likes, name='like_url'),
    url(r'^blocktest/$', views.ethTest, name='blocktest'),
    url(r'^upwallet/$', views.update_wallet, name='upwallet'),
]

from django.conf import settings
from django.conf.urls.static import static

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.MEDIA_ROOT)


"""

You are given the head of a linked list, and an integer k.

Return the head of the linked list after swapping the values of the kth node from the beginning and the kth node from the end (the list is 1-indexed).
"""

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapNodes(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        first = last = head
        for i in range(1, k):
            first = first.next

        null_checker = first
        while null_checker.next:
            last = last.next
            null_checker = null_checker.next
        first.val, last.val = last.val, first.val
        return head

leetcode/Medium/1721. Swapping Nodes in a Linked List.py


# import sqlite3
from flask_restful import Resource, reqparse
from flask_jwt import jwt_required
from models.item import ItemModel

class Item(Resource):
    parser = reqparse.RequestParser()
    parser.add_argument('price',
        type=float,
        required=True,
        help="This field cant be left blank!"
    )
    parser.add_argument('store_id',
        type=int,
        required=True,
        help="Every Item needs a store id!"
    )

    @jwt_required()
    def get(self, name):
        item = ItemModel.find_by_name(name)
        if item:
            return item.json(), 200
        return {'message': 'item not found.'}, 400

    def post(self, name):
        if ItemModel.find_by_name(name):
            return {'message': "An item with name '{}' already exists.".format(name)}, 400

        data = Item.parser.parse_args()
        # item = ItemModel(name, data['price'], data['store_id'])
        item = ItemModel(name, **data)
        try:
            # 使用sqlite3連結sqlite資料庫
            # item.insert()
            item.save_to_db()
        except:
            return {'message': 'An error occurred inserting the item.'}, 500
        return item.json(), 201

    def put(self, name):
        data = Item.parser.parse_args()
        item = ItemModel.find_by_name(name)
        if item is None:
            # item = ItemModel(name, data['price'], data['store_id'])
            item = ItemModel(name, **data)
        else:
            item.price = data['price']
        item.save_to_db()
        return item.json()

        # 使用sqlite3連結sqlite資料庫
        # updated_item = ItemModel(name, data['price'])
        # if item is None:
        #     try:
        #         updated_item.insert()
        #     except:
        #         return {'message': 'An error occurred inserting the item.'}, 500
        # else:
        #     try:
        #         updated_item.update()
        #     except:
        #         return {'message': 'An error occurred updating the item.'}, 500
        # return updated_item.json()

    def delete(self, name):
        item = ItemModel.find_by_name(name)
        if item is None:
            return {"message": "item is not exist!"}
        else:
            try:
                item.delete()
            except:
                return {"message": "An error occurred deleteing the item."}
        return {'message': 'item deleted'}

class ItemList(Resource):
    def get(self):
        return {'items': [item.json() for item in ItemModel.query.all()]}

        # 使用sqlite3連結sqlite資料庫
        # connection = sqlite3.connect('data.db')
        # cursor = connection.cursor()
        # query = "SELECT * FROM items"
        # result = cursor.execute(query).fetchall()
        # connection.close()
        # return {'items': [ {"name": item[0], "price": item[1]} for item in result]}, 200


class Solution(object):
    def minimumTotal(self, triangle):
        """
        :type triangle: List[List[int]]
        :rtype: int
        """
        ht = len(triangle)
        dp = [[-1]*ht for _ in range(ht)]

        # 自底向上方法解决数字三角形问题
        # init dp
        for i in range (ht):
            dp[ht-1][i] = triangle[ht-1][i]
        # 注意一下倒序的 range 用法
        for i in range(ht-1-1,-1,-1):
            for j in range(i+1):
                l = dp[i+1][j]
                r = dp[i+1][j+1]
                dp[i][j] =  min(l,r)+triangle[i][j]
        return dp[0][0]


import datetime
import time

import cv2
from flask import Blueprint, render_template, request, send_from_directory, session, jsonify, json, Response, redirect
from werkzeug.utils import secure_filename
from app.models.my_data import Images, Cameras, Videos, Events

from ..models import db
from .. import app
import os
from os.path import join, dirname, realpath
import validators

# AI MODELS
import YoloDetector
import EmotionDetector

home = Blueprint('home', __name__)

USER_EMAIL = ""

# PATHS
UPLOADS_PATH = join(dirname(realpath(__file__)), '../static/user_data/uploads_emotion_detection/..')
app.config['UPLOAD_FOLDER'] = UPLOADS_PATH

app_root = os.path.dirname(os.path.abspath(__file__))
target = os.path.join(app_root, '../static/user_data/uploads_object_detection/')
target2 = os.path.join(app_root, '../static/user_data/uploads_emotion_detection/')
if not os.path.isdir(target):
    os.makedirs(target)

if not os.path.isdir(target2):
    os.makedirs(target2)

######################## YOLO VARIABLES ###################################
WEIGHTS = "yolov7.pt"
PRED_LOCATION = os.path.join(app_root, '../static/user_data/predicts_object_detection/')
YOLO = YoloDetector.YoloDetectorClass(project=PRED_LOCATION)
YOLO_LOADED = False
Video_Name = ""
CameraLinks = []

###################### EMOTION VARIABLES #####################################
EMOTION_PATH = "cnn.hdf5"
DETECTION_PATH = "haarcascade_frontalface_default.xml"
EMO_PRED_LOCATION = os.path.join(app_root, '../static/user_data/predicts_emotion_detection/')
EMO = EmotionDetector.EmotionDetectorClass(detection_model_path=DETECTION_PATH, emotion_model_path=EMOTION_PATH,
                                           detected_img_path=EMO_PRED_LOCATION)
EMO_LOADED = False
EMO_Video_Name = ""
EMO_CameraLinks = []

ModelSelected = ""

################################################################################

#########################################################  SHOWING LIVE VIDEOS ##############################################################
########################################################## WORKING WITH YOLO ################################################################
##### VIDEO PATH
def infer_video(video_name):
    user_mail = USER_EMAIL

    # Loading YOLO
    global YOLO_LOADED
    if not YOLO_LOADED:
        YOLO.Load_Model()
        YOLO_LOADED = True

    count = 0
    Vid_Path = os.path.join(target, video_name)
    video = cv2.VideoCapture(Vid_Path)
    w = int(video.get(3))
    h = int(video.get(4))

    FPS = 10
    Writer_Path = os.path.join(PRED_LOCATION, video_name)
    Vid_Writer = cv2.VideoWriter(Writer_Path, cv2.VideoWriter_fourcc(*'mp4v'), FPS, (w, h))

    MyVid = Videos.query.filter_by(name=video_name).first()
    Vid_ID = MyVid.id

    Frame_Count = 0
    while True:
        success, frame = video.read()
        if not success:
            break
        else:
            Frame_Location = r'{}/{}__{}.png'.format(PRED_LOCATION, video_name, count)
            cv2.imwrite(Frame_Location, frame)
            det_frame, detections = YOLO.Run_Detect(source=Frame_Location)

            Vid_Writer.write(det_frame)

            ret, buffer = cv2.imencode('.jpg', det_frame)
            frame = buffer.tobytes()
            if detections:
                detections = detections[0]
                detections_splitted = detections.split(',')
                detections = " , ".join(detections_splitted)

                # Adding the Event to the Database
                new_event = Events(email=user_mail, model="Object Detection", source="Video", source_name=video_name,
                                   message=detections, event_date=str(datetime.datetime.now()),
                                   event_link="{}__{}.png".format(video_name, count))
                db.session.add(new_event)
                db.session.commit()

            Frame_Count += 10  # i.e. at 30 fps, this advances one second
            video.set(cv2.CAP_PROP_POS_FRAMES, Frame_Count)

        count += 1

        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route("/videos_feed")
def video_feed():
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)

    else:
        global USER_EMAIL
        USER_EMAIL = session['email']
        return Response(infer_video(Video_Name),
                        mimetype='multipart/x-mixed-replace; boundary=frame')

##### CAMERAS
def Pred_One_Camera(camera_link, CameraLinkName):
    user_mail = USER_EMAIL

    # Loading YOLO
    global YOLO_LOADED
    if not YOLO_LOADED:
        YOLO.Load_Model()
        YOLO_LOADED = True

    video = cv2.VideoCapture(camera_link)
    w = int(video.get(3))
    h = int(video.get(4))
    FPS = 10
    Writer_Path = os.path.join(PRED_LOCATION, CameraLinkName + ".mp4")
    Vid_Writer = cv2.VideoWriter(Writer_Path, cv2.VideoWriter_fourcc(*'mp4v'), FPS, (w, h))
    count = 0
    CamID = Cameras.query.filter_by(link=camera_link).order_by(Cameras.id.desc()).first().id
    print(CamID)
    while True:
        success, frame = video.read()
        if not success:
            break
        else:
            Frame_Location = r'{}/{}__{}.png'.format(PRED_LOCATION, CameraLinkName, count)
            cv2.imwrite(Frame_Location, frame)
            det_frame, detections = YOLO.Run_Detect(source=Frame_Location)
            Vid_Writer.write(det_frame)

            ret, buffer = cv2.imencode('.jpg', det_frame)
            frame = buffer.tobytes()

            if detections:
                detections = detections[0]
                detections_splitted = detections.split(',')
                detections = " , ".join(detections_splitted)
                new_event = Events(email=user_mail, model="Object Detection", source="Camera", source_name=camera_link,
                                   message=detections, event_date=str(datetime.datetime.now()),
                                   event_link="{}__{}.png".format(CameraLinkName, count))

                db.session.add(new_event)
                db.session.commit()

        count += 1
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route("/cameras_feed/<int:id>/")
def camera_feed(id):
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)
    else:
        global USER_EMAIL
        USER_EMAIL = session['email']
        timestamp = int(time.time())
        CameraLinkName = "CamLink{}_{}".format(id, timestamp)

        if ModelSelected == "Object Detection":
            return Response(Pred_One_Camera(CameraLinks[id], CameraLinkName),
                            mimetype='multipart/x-mixed-replace; boundary=frame')

        elif ModelSelected == "Emotion Detection":
            return Response(Pred_One_Camera_emo(CameraLinks[id], CameraLinkName),
                            mimetype='multipart/x-mixed-replace; boundary=frame')

###################### WORKING WITH EMO ############################
#### VIDEO
def infer_video_emo(video_name):
    user_mail = USER_EMAIL

    # Loading EMO
    global EMO_LOADED
    if not EMO_LOADED:
        EMO.Load_Model()
        EMO_LOADED = True

    count = 0
    Vid_Path = os.path.join(target2, video_name)
    video = cv2.VideoCapture(Vid_Path)
    w = int(video.get(3))
    h = int(video.get(4))
    FPS = 5
    print("111111")
    Writer_Path = os.path.join(EMO_PRED_LOCATION, video_name)
    Vid_Writer = cv2.VideoWriter(Writer_Path, cv2.VideoWriter_fourcc(*'mp4v'), FPS, (w, h))

    MyVid = Videos.query.filter_by(name=video_name).first()
    Vid_ID = MyVid.id

    Frame_Count = 0
    while True:
        success, frame = video.read()
        if not success:
            break
        else:
            Frame_Location = r'{}/{}__{}.png'.format(EMO_PRED_LOCATION, video_name, count)
            cv2.imwrite(Frame_Location, frame)
            Saving_Name = r'{}__{}.png'.format(video_name, count)
            det_frame, detections = EMO.Run_Detect(source=Frame_Location, saving_name=Saving_Name)

            Vid_Writer.write(det_frame)

            ret, buffer = cv2.imencode('.jpg', det_frame)
            frame = buffer.tobytes()
            if detections:
                new_event = Events(email=user_mail, model="Emotion Detection", source="Video", source_name=video_name,
                                   message=detections, event_date=str(datetime.datetime.now()),
                                   event_link="{}__{}.png".format(video_name, count))
                db.session.add(new_event)
                db.session.commit()

            Frame_Count += 10  # i.e. at 30 fps, this advances one second
            video.set(cv2.CAP_PROP_POS_FRAMES, Frame_Count)
        count += 1

        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route("/videos_feed_emo")
def video_feed_emo():
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)
    else:
        global USER_EMAIL
        USER_EMAIL = session['email']
        return Response(infer_video_emo(Video_Name),
                        mimetype='multipart/x-mixed-replace; boundary=frame')

#### CAMERAS
def Pred_One_Camera_emo(camera_link, CameraLinkName):
    user_mail = USER_EMAIL

    # Loading YOLO
    global EMO_LOADED
    if not EMO_LOADED:
        EMO.Load_Model()
        EMO_LOADED = True

    video = cv2.VideoCapture(camera_link)
    w = int(video.get(3))
    h = int(video.get(4))
    FPS = 10

    Writer_Path = os.path.join(EMO_PRED_LOCATION, CameraLinkName + ".mp4")
    Vid_Writer = cv2.VideoWriter(Writer_Path, cv2.VideoWriter_fourcc(*'mp4v'), FPS, (w, h))
    count = 0
    CamID = Cameras.query.filter_by(link=camera_link).order_by(Cameras.id.desc()).first().id

    while True:
        success, frame = video.read()
        if not success:
            break
        else:
            Frame_Location = r'{}/{}__{}.png'.format(EMO_PRED_LOCATION, CameraLinkName, count)
            cv2.imwrite(Frame_Location, frame)
            Saving_Name = r'{}__{}.png'.format(CameraLinkName, count)
            det_frame, detections = EMO.Run_Detect(source=Frame_Location, saving_name=Saving_Name)

            Vid_Writer.write(det_frame)

            ret, buffer = cv2.imencode('.jpg', det_frame)
            frame = buffer.tobytes()

            if detections:
                detections = detections[0]
                new_event = Events(email=user_mail, model="Emotion Detection", source="Camera", source_name=camera_link,
                                   message=detections, event_date=str(datetime.datetime.now()),
                                   event_link="{}__{}.png".format(CameraLinkName, count))

                db.session.add(new_event)
                db.session.commit()

        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

######################################################### ROUTES ####################################################
# HOME PAGE
@home.route('/home')
def home_page():
    # Check if user is logged in
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)

    else:
        user_mail = session['email']
        user_fullname = session['fullname']

        # Events Table Data
        table_data = []
        # 1- Getting Events and Storing in the Table of Data
        UserEvents = Events.query.filter_by(email=user_mail)
        for event in UserEvents:
            data = {"ID": event.id, "Model": event.model, "Source": event.source, "Source_Name": event.source_name,
                    "Messages": event.message, "Date": event.event_date, "Link": event.event_link}
            table_data.append(data)

        #############################
        # Solid Line DATA
        solid_labels = []
        solid_data = []
        if len(table_data) > 0:
            min_date = min(table_data, key=lambda x: x['Date'])["Date"]
            max_date = max(table_data, key=lambda x: x['Date'])["Date"]
            current_date = min_date
            while current_date <= max_date:
                events_betn = list(filter(lambda x: min_date <= x['Date'] <= current_date, table_data))
                solid_labels.append(current_date.strftime('%m-%d %H:%M'))
                solid_data.append(len(events_betn))
                current_date = current_date + datetime.timedelta(hours=1)

        solid_dict = {
            "data": solid_data,
            "labels": solid_labels,
            "title": 'Events per Time',
            "data_unit": "Events",
            "min_unit": 0,
            "unit_label": ""
        }

        ################################
        # Score Data
        no_cameras = Cameras.query.filter_by(email=user_mail).count()
        no_videos = Videos.query.filter_by(email=user_mail).count()
        score_dict = {
            "no_events": len(table_data),
            "no_models": 2,
            "no_cameras": no_cameras,
            "no_videos": no_videos
        }
        return render_template("home/home.html",
                               solid_line=solid_dict, score=score_dict, table_data=table_data,
                               myemail=user_mail, fullname=user_fullname)

# Welcome (Login Page)
@home.route('/')
def welcome_page():
    return redirect('/home')

## Page of ANALYTICS (CHOOSING MODEL AND METHOD)
# - Once user choose model --> Model will be Loaded
@home.route('/analytics', methods=['GET', 'POST'])
def analytic_page():
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)

    else:
        user_fullname = session['fullname']
        user_mail = session['email']
        global ModelSelected

        if request.method == 'GET':
            return render_template('home/Analytics.html', myemail=user_mail, fullname=user_fullname)

        else:
            # Choosing YOLO:
            if request.form.get('model') == 'object_detection':
                global YOLO_LOADED
                if not YOLO_LOADED:
                    YOLO.Load_Model()
                    YOLO_LOADED = True
                ModelSelected = "Object Detection"

            elif request.form.get('model') == "emotion_detection":
                global EMO_LOADED
                if not EMO_LOADED:
                    EMO.Load_Model()
                    EMO_LOADED = True
                ModelSelected = "Emotion Detection"

            # Image
            if request.form['source'] == 'image':
                return render_template('home/uploadImage.html', myemail=user_mail, fullname=user_fullname,
                                       model=ModelSelected)
            # Video
            elif request.form['source'] == 'video':
                return render_template('home/uploadvedio.html', myemail=user_mail, fullname=user_fullname,
                                       model=ModelSelected)
            # Camera
            else:
                return render_template('home/uploadcam.html', myemail=user_mail, fullname=user_fullname,
                                       model=ModelSelected)

# Object Detection Page
@home.route('/object_det')
def object_page():
    if session.get('email') is None:
        return render_template('error/notfound.html')
    else:
        myname = session['username']
        myemail = session['email']
        firstname = session['firstname']
        return render_template('home/objectDet.html', myname=myname, myemail=myemail, firstname=firstname)

# Emotion Detection Page
@home.route('/emotion_det')
def emotion_page():
    if session.get('email') == None:
        return render_template('error/notfound.html')
    else:
        myname = session['username']
        myemail = session['email']
        firstname = session['firstname']

        return render_template('home/emotionalDet.html', myname=myname, myemail=myemail, firstname=firstname)

############################################### GETTING FILES SRCs FUNCTIONS #############################
# Static/Upload  --> YOLO UPLOADED FILES
@app.route('/file/<filename>')
def get_image(filename):
    return send_from_directory(target, filename)

# Static2/Upload2  --> EMO UPLOADED FILES
@app.route('/file2/<filename>')
def get_image2(filename):
    return send_from_directory(target2, filename)

# Image PREDICTED Locations
@app.route('/file3/<filename>')
def get_predict(filename):
    if ModelSelected == "Object Detection":
        return send_from_directory(PRED_LOCATION, filename)
    elif ModelSelected == "Emotion Detection":
        return send_from_directory(EMO_PRED_LOCATION, filename)

# Static2/Predicts2  --> EMO PREDICTED FILES
@app.route('/file4/<filename>')
def get_predict2(filename):
    return send_from_directory(EMO_PRED_LOCATION, filename)

######################################################### UPLOADING IMGS, VIDEOS, Picking CAMERAS ###########################################
#### UPLOADING AND DETECTING IMAGE #####
@home.route('/upload_image', methods=['GET', 'POST'])
def upload_image():
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)

    else:
        prediction = 0
        user_fullname = session['fullname']
        user_mail = session['email']

        if request.method == 'GET':
            return render_template('home/uploadImage.html', prediction=prediction, myname=user_fullname,
                                   myemail=user_mail)

        else:
            myimage = request.files['image']
            filename = secure_filename(myimage.filename)
            if ModelSelected == "Object Detection":
                destination = '/'.join([target, filename])
            else:
                destination = '/'.join([target2, filename])

            myimage.save(destination)  # Saved the uploaded image

            if not myimage:
                uploadimg = 'please upload an image'
                return render_template('home/uploadImage.html', prediction=prediction, uploadimg=uploadimg,
                                       myname=user_fullname, myemail=user_mail)

            else:
                # Adding Image to the DB
                filename = secure_filename(myimage.filename)
                mimetype = myimage.mimetype
                newimage = Images(email=user_mail, model=ModelSelected, mimetype=mimetype, name=filename,
                                  img=myimage.read())
                db.session.add(newimage)
                db.session.commit()
                id = newimage.id
                uploaded = 'your image uploaded successfully'
                myimage = Images.query.filter_by(id=id).first()
                filename = myimage.name

                if ModelSelected == "":
                    return render_template("home/Analytics.html", myemail=user_mail, fullname=user_fullname)

                else:
                    prediction = 1
                    detections = ""

                    if ModelSelected == "Object Detection":
                        # Loading YOLO
                        global YOLO_LOADED
                        if not YOLO_LOADED:
                            YOLO.Load_Model(weights=WEIGHTS)
                            YOLO_LOADED = True

                        detected_img, detections = YOLO.Run_Detect(source=destination)
                        if detections:
                            detections = detections[0]
                            detections = detections.split(',')
                        else:
                            detections = ["No Detections"]

                        EventLink = r"predicts_object_detection/{}".format(filename)

                    elif ModelSelected == "Emotion Detection":
                        global EMO_LOADED
                        if not EMO_LOADED:
                            EMO.Load_Model()
                            EMO_LOADED = True
                        detected_img, detections = EMO.Run_Detect(source=destination, saving_name=filename)
                        if detections is None:
                            detections = "No Detections"
                        EventLink = r"predicts_emotion_detection/{}".format(filename)

                    NewEvent = Events(email=user_mail, model=ModelSelected, source="Image", source_name=filename,
                                      event_date=str(datetime.datetime.now()), message=", ".join(detections),
                                      event_link=EventLink)
                    db.session.add(NewEvent)
                    db.session.commit()

                    return render_template('home/uploadImage.html', prediction=prediction, detections=detections,
                                           filename=filename, uploaded=uploaded, myname=user_fullname,
                                           myemail=user_mail)

#### UPLOADING VIDEO
@home.route('/upload_vedio', methods=['GET', 'POST'])
def upload_vedio():
    prediction = 0
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)

    else:
        myname = session['fullname']
        myemail = session['email']

        if request.method == 'GET':
            return render_template('home/uploadvedio.html', prediction=prediction, myname=myname,
                                   myemail=myemail)
        else:
            global Video_Name
            myved = request.files['video']
            filename = secure_filename(myved.filename)
            timestamp = int(time.time())
            [video, extension] = filename.split('.')
            Video_Name = "{}_{}.{}".format(video, timestamp, extension)

            if ModelSelected == "Object Detection":
                destination = '/'.join([target, Video_Name])
            else:
                destination = '/'.join([target2, Video_Name])

            myved.save(destination)
            if not myved:
                uploadvedio = 'please upload a video'
                return render_template('home/uploadvedio.html', prediction=prediction, uploadvedio=uploadvedio,
                                       myname=myname, myemail=myemail)
            else:
                if ModelSelected == "":
                    return render_template("home/Analytics.html", myemail=myemail, fullname=myname)

                else:
                    source_name = secure_filename(myved.filename)
                    NewVideo = Videos(name=Video_Name, email=myemail, model=ModelSelected)
                    db.session.add(NewVideo)
                    db.session.commit()
                    prediction = 1
                    uploaded = 'your video uploaded successfully'

                return render_template('home/uploadvedio.html', prediction=prediction, uploaded=uploaded, myname=myname,
                                       myemail=myemail, model=ModelSelected, source_name=Video_Name)

############# UPLOAD CAMERA LINKS #######################
### YOLO
@home.route('/upload_link', methods=['GET', 'POST'])
def upload_link():
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)

    else:
        myname = session['fullname']
        myemail = session['email']
        flag1 = 0

        if request.method == 'GET':
            return render_template('home/uploadcam.html', flag1=flag1, myname=myname, myemail=myemail)

        else:
            stream_url = request.form['stream_url']
            location = request.form['location']
            camera_name = request.form['camera_name']

            NewCamera = Cameras(email=myemail, link=stream_url, name=camera_name, location=location,
                                model=ModelSelected)
            db.session.add(NewCamera)
            db.session.commit()
            flag1 = 1
            uploaded = 'your link uploaded successfully , add a new one'
            return render_template('home/uploadcam.html', flag1=flag1, uploaded=uploaded, myname=myname,
                                   myemail=myemail)

### LOADING CAMERAS TO PREDICT
## YOLO
@home.route('/predict_link')
def predict_link():
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)

    else:
        myname = session['fullname']
        myemail = session['email']

        MyCameraLinks = Cameras.query.filter_by(email=myemail, model=ModelSelected)
        global CameraLinks
        CameraLinks = []
        for Camera in MyCameraLinks:
            CameraLinks.append(Camera.link)
        return render_template('home/predictcam.html', model=ModelSelected, CamLinks=MyCameraLinks, myemail=myemail,
                               myname=myname)

@home.route('/video_events/<source_name>')
def video_events(source_name):
    myname = session['fullname']
    myemail = session['email']
    return render_template('home/videoEvents.html', myname=myname, myemail=myemail, source_name=source_name)

@home.route('/get_video_events/<source_name>')
def get_video_events(source_name):
    CurrentEvents = Events.query.filter_by(source_name=source_name)

    ids = []
    models = []
    sources = []
    source_names = []
    messages = []
    dates = []
    links = []

    if CurrentEvents:
        for event in CurrentEvents:
            ids.append(event.id)
            models.append(event.model)
            sources.append(event.source)
            source_names.append(event.source_name)
            messages.append(event.message)
            dates.append(event.event_date)
            links.append(event.event_link)

        return jsonify({"IDS": ids,
                        "MODELS": models,
                        "SOURCES": sources,
                        "SOURCE_NAMES": source_names,
                        "MESSAGES": messages,
                        "DATES": dates,
                        "LINKS": links,
                        "error": "data"})
    else:
        return jsonify({"error": "no data"})

@home.route('/camera_events/<int:id>')
def camera_events(id):
    if session.get('email') is not None:
        myname = session['fullname']
        myemail = session['email']

        Camera = Cameras.query.filter_by(id=id).first()
        CamLink = Camera.link
        CamEvents = Events.query.filter_by(source_name=CamLink)
        return render_template('home/cameraEvents.html', myevnts=CamEvents, myname=myname, myemail=myemail, camera_id=id)
    else:
        return render_template('error/notfound.html')

@home.route('/get_camera_events/<int:id>')
def get_camera_events(id):
    Camera = Cameras.query.filter_by(id=id).first()
    CamLink = Camera.link
    CurrentEvents = Events.query.filter_by(source_name=CamLink)

    ids = []
    models = []
    sources = []
    source_names = []
    messages = []
    dates = []
    links = []

    if CurrentEvents:
        for event in CurrentEvents:
            ids.append(event.id)
            models.append(event.model)
            sources.append(event.source)
            source_names.append(event.source_name)
            messages.append(event.message)
            dates.append(event.event_date)
            links.append(event.event_link)

        return jsonify({"IDS": ids,
                        "MODELS": models,
                        "SOURCES": sources,
                        "SOURCE_NAMES": source_names,
                        "MESSAGES": messages,
                        "DATES": dates,
                        "LINKS": links,
                        "error": "data"})
    else:
        return jsonify({"error": "no data"})

@home.route('/deleteCam/<int:id>')
def del_cam(id):
    Camera = Cameras.query.filter_by(id=id).first()
    CamLink = Camera.link

    Events.query.filter_by(source_name=CamLink).delete()
    Cameras.query.filter_by(id=int(id)).delete()
    db.session.commit()
    return redirect("/predict_link")

# STORAGE BUTTON
@home.route('/storage')
def storage():
    print("Opening Storage.....")
    return render_template("home/storage.html")

# All Events
@home.route('/all_events/')
def all_events():
    # Check if user is logged in
    if session.get('email') is None:
        login_problem = "Sorry, you have to login first to use our service.."
        return render_template('auth/login.html', login_problem=login_problem)

    else:
        user_mail = session['email']
        user_fullname = session['fullname']

        # Events Table Data
        table_data = []
        # 1- Getting Events and Storing in the Table of Data
        UserEvents = Events.query.filter_by(email=user_mail)
        for event in UserEvents:
            data = {"ID": event.id, "Model": event.model, "Source": event.source, "Source_Name": event.source_name,
                    "Messages": event.message, "Date": event.event_date, "Link":event.event_link}
            table_data.append(data)

        return render_template("home/all_events.html", table_data=table_data, myemail=user_mail, fullname=user_fullname)


'''
This program prints numerical derivative convergance
'''
import representation_ZRN as ZRNrep
from jax.config import config
config.update("jax_enable_x64", True) #increase precision from float32 to float64
import jax_representation as jrep
import numpy as np
from numpy import linalg
import jax_derivative as jder
import database_preparation as datprep
import matplotlib.pyplot as plt
import numerical_derivative as numder

#give xyz coordinates of H2O
path = "./TEST/H2O.xyz"

#read xyz file and create compound instances
Z_orig, R_orig, N, e_orig = datprep.read_xyzfile(path)
Z_orig = np.array(Z_orig, dtype = np.float64)

M, order = jrep.CM_full_sorted(Z_orig, R_orig, N)
which_derivative = 1
#reorder your initial data. otherwise numerical differentiation will fail
#needs to be performed with preordered data, otherwise sorting can change
Z = Z_orig[order.tolist()]
R = R_orig[order]

R = np.asarray(R, dtype = np.float64)
Z = np.asarray(Z, dtype = np.float64)
functionnames = ['CM_unsrt', 'CM_EV_unsrt', 'OM', 'OM_EV']
functions = [ZRNrep.Coulomb_Matrix, ZRNrep.Eigenvalue_Coulomb_Matrix, ZRNrep.Overlap_Matrix, ZRNrep.Eigenvalue_Overlap_Matrix]

def get_first_order_errors(fun, fname, hlist, d1):

    if d1[0] == 0:
        name = "dZ%i" % (d1[1] + 1)
        dx = "Z"
        exact = jder.sort_derivative(fname, Z, R, N, 1, dx)[d1[1]]
    if d1[0] == 1:
        xyz = ['x', 'y', 'z']
        name = "d%s%i" %(xyz[d1[1]], d1[2]+1)
        dx = 'R'
        exact = jder.sort_derivative(fname, Z, R, N, 1, dx)[d1[1]][d1[2]]
    print("\n ------------------- \n Derivative %s \n ------------------ \nAnalytical derivative" %name)
    print(exact)

    ylist = []
    #calculate numerical derivatives for increasingly small h
    for h in hlist:
        derf = numder.derivative(fun, [Z,R,N], 'numerical', 1, d1, [0,0], h)
        exf = exact.flatten()
        print("derf")
        print(derf)
        print("exf")
        print(exf)
        error = linalg.norm(derf - exf)
        ylist.append(error)

    return(ylist, name)

def get_second_order_errors(fun, fname, hlist, d1, d2):
    '''
    fun: function from representation_ZRN.py
    fname: string, 'CM', 'CM_EV', 'CM_unsrt', 'OM', 'OM_EV'
    '''
    #calculate exact result
    if d1[0] == 0:
        name1 = "dZ%i" % (d1[1] + 1)
        dx1 = "Z"
        if d2[0] == 0:
            name = name1 + "dZ%i" % (d2[1] + 1)
            dx2 = "Z"
            exact = jder.sort_derivative(fname, Z, R, N, 2, dx1, dx2)[d1[1]][d2[1]]

    if d1[0] == 1:
        xyz = ['x', 'y', 'z']
        name1 = "d%s%i" %(xyz[d1[1]], d1[2])
        dx1 = 'R'
        if d2[0] == 1:
            name = name1 + "d%s%i" %(xyz[d2[1]], (d2[2] + 1))
            dx2 = 'R'
            exact = jder.sort_derivative(fname, Z, R, N, 2, dx1, dx2)[d1[1]][d1[2]][d2[1]][d2[2]]

    if (d1[0] == 0 and d2[0] == 1) or (d1[0] == 1 and d2[0] == 0):
        xyz = ['x', 'y', 'z']
        #translate dx1 and dx2 to numbers for functions and names
        dx1 = "Z"
        dx2 = "R"

        if d1[0] == 0:
            ZR_order = True
            name1 = "dZ%i" % (d1[1]+1)
            name2 = "d%s%i" %(xyz[d2[1]], d2[2]+1)

        else:
            ZR_order = False
            name1 = "dZ%i" % (d2[1]+1)
            name2 = "d%s%i" %(xyz[d1[1]], d1[2]+1)
        name = name1 + name2

        if ZR_order:
            exact = jder.sort_derivative(fname, Z, R, N, 2, dx1, dx2)[d1[1]][d2[1]][d2[2]]
        else:
            exact = jder.sort_derivative(fname, Z, R, N, 2, dx1, dx2)[d2[1]][d1[1]][d1[2]]

    print("\n ------------------- \n Derivative %s \n ------------------ \nAnalytical derivative" %name)
    print(exact)

    ylist = []
    #calculate numerical derivatives for increasingly small h
    for h in hlist:
        derf = numder.derivative(fun, [Z,R,N], 'numerical', 2, d1, d2, h)
        exf = exact.flatten()
        error = linalg.norm(derf - exf)
        print("derf")
        print(derf)
        print("exf")
        print(exf)

        #print("h", h, "error", error)
        #print(derf.reshape(3,3))
        ylist.append(error)

    return(ylist, name)

def plot_numeric_errors(fun, fname, do_first_order = True, do_second_order = True, show_legend = False):
    '''
    fun : function from representation_ZRN.py file
    fname : function name: 'CM', 'CM_unsrt', 'CM_EV', 'OM' or 'OM_EV'

    '''
    #prepare panels for plots
    fig = plt.figure(tight_layout = True, figsize=(8, 6))

    #create subfigure spacing as needed
    if do_first_order:
        if do_second_order:
            '''create 5 panel image'''
            ax1 = plt.subplot2grid((2,6),(0,0), rowspan=1, colspan=3)
            ax2 = plt.subplot2grid((2,6), (0,3), rowspan=1, colspan=3)
            ax3 = plt.subplot2grid((2,6), (1,0), rowspan=1, colspan=2)
            ax4 = plt.subplot2grid((2,6), (1,2), rowspan=1, colspan=2)
            ax5 = plt.subplot2grid((2,6), (1,4), rowspan=1, colspan=2)

        else:
            '''create 2 panel image for dZ and dR'''
            ax1 = fig.add_subplot(121)
            ax2 = fig.add_subplot(122)
    elif do_second_order:
        '''create 3 panel image for dZdZ, dRdR and dZdR'''
        ax3 = fig.add_subplot(131)
        ax4 = fig.add_subplot(132)
        ax5 = fig.add_subplot(133)

    #derivatives: standard parameters by which to derive.
    '''
    [0, ...] is dZ
    [1, ...] is dR
    [...,0,...] is dZ1 or dR1
    for dR, [...,...,0] is dx, [...,...,1] dy and [...,...,2] dz
    '''

    derivative_1 =  [[0,0], [0,1], [0,2],[1,0,0], [1,0,1],[1,0,2],[1,1,0], [1,1,1],[1,1,2],[1,2,0], [1,2,1], [1,2,2]]

    derivative_2 = [[0,0], [0,1], [0,2], [1, 1, 2], [1,0, 1], [1,0,0], [1,2,2], [1,1,2]]

    #hlist: small steps that are taken for numerical derivation
    hlist = np.logspace(-1, -5, 10)

    #plot 1st order if needed
    if do_first_order:
        for d1 in derivative_1:
            ylist, name = get_first_order_errors(fun, fname, hlist, d1)

            #plot errors in correct subplot
            if d1[0] == 0:
                ax1.loglog(hlist, ylist, 'o-', label = name)
            else:
                ax2.loglog(hlist, ylist, 'o-', label = name)

        if show_legend:
            ax1.legend()
            ax2.legend()

        ax1.title.set_text('dZ (nuclear charge)')
        ax2.title.set_text('dR (nuclear coordinate)')
        ax1.set_xlabel("dh")
        ax2.set_xlabel("dh")

    if do_second_order:

        for d1 in derivative_1:
            for d2 in derivative_2:

                ylist, name = get_second_order_errors(fun, fname, hlist, d1, d2)

                #plot errors in correct subplot
                if d1[0] == 0:
                    if d2[0] == 0:
                        ax3.loglog(hlist, ylist, 'o-', label = name)
                    else:
                        ax5.loglog(hlist, ylist, 'o-', label = name)
                if d1[0] == 1:
                    if d2[0] == 1:
                        ax4.loglog(hlist, ylist, 'o-', label = name)
                    else:
                        ax5.loglog(hlist, ylist,'o-', label = name)

        if show_legend:
            ax3.legend()
            ax4.legend()
            ax5.legend()
        ax3.title.set_text("dZdZ")
        ax4.title.set_text("dRdR")
        ax5.title.set_text("dZdR")
        ax3.set_xlabel("dh")
        ax4.set_xlabel("dh")
        ax5.set_xlabel("dh")

    fig.suptitle('Finite Central Difference Derivative on %s of H2O Molecule' %fname, fontsize = 15)
    #ad title to overall y axis

    fig.text(0.5, 0.0004, '(dh is the small change introduced in numerical differentiation)', ha='center', fontsize = 13)
    fig.text(0.0004, 0.5, 'Absolute Error w.r.t. Analytical Derivative [a.u.]', rotation = 'vertical', va='center', fontsize =13)

    filename = "./Images/numerical_errors_%s.png" % fname
    plt.savefig(filename, bbox_inches = 'tight')

    return()

fun = functions[1]
fname = functionnames[1]

print("function:", fun)
print("function name:", fname)
plot_numeric_errors(fun, fname)


import spacy

nlp = spacy.load("en_core_web_lg")

with open("/home/mich_qiu/PycharmProjects/MSc_Thesis/Bug-Report-Summarization/src/others/h_description.txt", 'r') as f:
    new_sents = []
    for line in f:
        doc = nlp(line)
        pos_noun_idx = []
        pos_noun_idx2 = []
        count = 0
        for token in doc:
            if token.pos_ == "NOUN":
                pos_noun_idx.append("someone")
                pos_noun_idx2.append("john")
                count += 1
            elif token.pos_ == "PRON":
                pos_noun_idx.append("cat")
                pos_noun_idx2.append("john")
                count += 1
            elif token.pos_ == "PROPN":
                pos_noun_idx.append("someone")
                pos_noun_idx2.append("cat")
                count += 1
            elif token.text == "verb":
                pos_noun_idx.append("run")
                pos_noun_idx2.append("run")
            elif token.text == "link":
                pos_noun_idx.append("http://www.github.com")
                pos_noun_idx2.append("http://www.github.com")
            elif token.text == "date":
                pos_noun_idx.append("21/09/2020")
                pos_noun_idx2.append("21/09/2020")
            elif token.text == "modal":
                pos_noun_idx.append("should")
                pos_noun_idx2.append("should")
            else:
                pos_noun_idx.append(token.text)
                pos_noun_idx2.append(token.text)
        if count < 1:
            continue
        sent = ' '.join(pos_noun_idx)
        sent2 = ' '.join(pos_noun_idx2)
        new_sents.extend([sent, sent2])
    f.close()
with open("/home/mich_qiu/PycharmProjects/MSc_Thesis/Bug-Report-Summarization/src/others/h_description.txt", 'a') as f:
    f.write('\n')
    for sent in new_sents:
        f.write(sent)
    f.close()


"""Hyperparameter module."""

import itertools

import numpy as np

class Hyperparameter:
    """Hyperparameter management class.

    This class describes hyperparameter names, type of parameters (*continuous* or *discrete*), and
    valid spaces. This class also retains the current value of hyperparameter, which is increased
    or decreased by ``step()`` method.
    """
    def __init__(self, name, data, is_continuous=False):
        """Initialize Hyperparameter class.

        Args:
            name (str): hyperparameter name.
            data (tuple or list): tuple must contain (``min``, ``max``, ``default_step``) for
                *continuous* mode, where ``min`` and ``max`` are the maximum and minimum value of
                the hyperparameter, and ``default_step`` indicates a interval of sampling (please
                see ``get_grid()`` method). list must contain valid parameter values for *discrete*
                mode.
            is_continuous (bool): hyperparameter is *continuous* or not.

        Examples:
            >>> # continuous hyperparameter
            >>> hp0 = Hyperparameter('hp0', (0., 1., 0.2), True)
            >>> # discrete hyperparameter
            >>> hp1 = Hyperparameter('hp1', [0., 0.2, 0.4, 0.6, 0.8. 1.0])
        """
        if not isinstance(is_continuous, bool):
            raise TypeError("is_continuous option should be bool")

        if not isinstance(data, (list, tuple)):
            raise TypeError("data option should be list or tuple")

        self._name = name
        self._data = data
        self._is_continuous = is_continuous
        self._value = data[0]

        if self._is_continuous:
            self._min = data[0]
            self._max = data[1]
            self._index = None
            self._default_step = data[2]
        else:
            self._min = 0
            self._max = len(data) - 1
            self._index = 0
            self._default_step = 1

    def __repr__(self):
        result = f'Hyperparameter(name={self._name}, '\
                                f'data={self._data}, '\
                                f'is_continuous={self._is_continuous})'
        return result

    def __len__(self):
        """Returns the number of possible hyperparameter values."""
        return len(self.get_grid())

    def __getitem__(self, item):
        """Returns the hyperparameter value by index.

        Args:
            item (int): index of ``get_grid()`` result.

        Returns:
            int or float: the hyperparameter value.
        """
        return self.get_grid()[item]

    @property
    def name(self):
        """Returns the name of hyperparameter.

        Returns:
            str: the name of hyperparameter.
        """
        return self._name

    @property
    def value(self):
        """Returns the current value of hyperparameter.

        Returns:
            int or float: the current value of hyperparameter.
        """
        return self._value

    @property
    def is_continuous(self):
        """Hyperparameter is *continuous* mode or *discrete* mode.

        Returns:
            bool: True if the hyperparameter is defined as *continuous*.
        """
        return self._is_continuous

    def step(self, step=None):
        """Increase or decrease the current hyperparameter value.

        Args:
            step (int or float): the hyperparameter value is increased or decreased according to
                sign of given ``step`` for *continuous* mode. Also the current index of
                hyperparameter is changed by ``step`` for *discrete* mode.

        Return:
            bool: if the value is changed or not.
        """
        if step is None:
            step = self._default_step

        if self._is_continuous:
            if not self._min <= (self._value + step) <= self._max:
                return False

            self._value += step
        else:
            if not isinstance(step, int):
                raise TypeError("step should be int for discrete hps")

            if not self._min <= (self._index + step) <= self._max:
                return False

            self._index += step
            self._value = self._data[self._index]

        return True

    def set_min_value(self):
        """Set the minimum value to the current value."""
        if self._is_continuous:
            self._value = self._data[0]
        else:
            self._index = 0
            self._value = self._data[0]

    def set_max_value(self):
        """Set the maximum value to the current value."""
        if self._is_continuous:
            self._value = self._data[1]
        else:
            self._index = len(self._data) - 1
            self._value = self._data[-1]

    def get_grid(self):
        """Returns available values of the hyperparameter.

        If the hyperparameter is *continuous* mode, values are sampled by
        step of ``default_step`` between ``min`` and ``max``.

        Returns:
            list: list of hyperparameter values.
        """
        if self._is_continuous:
            return np.arange(self._min, self._max, self._default_step)

        return self._data

class Hyperparameters:
    """Utility class to manage Hyperparameter classes.

    The *Hyperparameters* class provides interfances to manage *Hyperparameter* class instances.
    This *Hyperparameters* class instance should be passed to *TaskScheduler* together with
    corresponding *subtask*.

    Examples:
        >>> hps_dict = {
        >>>     'hp_layers': [5, 10, 15, 20], # discrete
        >>>     'hp_alpha': [1.0, 2.0, 3.0] # discrete
        >>> }
        >>> hps = Hyperparameters(hps_dict)
        >>> hps.set_min_hps()
        >>> hps.get_current_hps()
        >>>  -> {'hp_layers': 5, 'hp_alpha': 1.0}
        >>> hps.step('hp_layers', 2)
        >>> hps.get_current_hps()
        >>>  -> {'hp_layers': 15, 'hp_alpha': 1.0}
        >>> hps.step('hp_alpha', 1)
        >>> hps.get_current_hps()
        >>>  -> {'hp_layers': 15, 'hp_alpha': 2.0}
    """
    def __init__(self, hps=None):
        """Initialize Hyperparameters class.

        ``hps`` option provides a shortcut to register hyperparameters. This option works only for
        *discrete* hyperparameters for now.

        Args:
            hps (dict): a dictionary of hyperparameters. Please see ``add_hp_from_dict()`` method.
        """
        if hps is None:
            hps = {}

        self._hps = []
        self.add_hp_from_dict(hps)

    def __repr__(self):
        result = f'Hyperparameters(hps={self.get_hp_names()})'
        return result

    def __len__(self):
        """Returns the number of all possible combinations of hyperparameters."""
        if not self._hps:
            return 0

        result = 1
        for hp in self._hps:
            result *= len(hp)
        return result

    def __getitem__(self, item):
        """Returns registered Hyperparameter class instance by index.

        If ``item`` is str, *Hyperparameter* is searched by its ``name``, and class instance is
        returned if it exists. If ``item`` is int, a dictionary of selected hyperparameters from
        ``get_grid_hps()`` method is returned.

        Args:
            item (str or int): the name of hyperparameter, or index of all possible combination
                from ``get_grid_hps()`` method.

        Returns:
            Hyperparameter or dict: please see the above description.
        """
        if isinstance(item, int):
            grid_hps = self.get_grid_hps()
            return grid_hps[item]

        if isinstance(item, str):
            for hp in self._hps:
                if hp.name == item:
                    return hp

        raise NotImplementedError(f'item {item} is not supported')

    def __contains__(self, item):
        """Check if Hyperparameter is registered or not.

        Args:
            item (str): the name of Hyperparameter.

        Returns:
            bool: True if Hyperparameter exists.
        """
        return item in self.get_hp_names()

    def step(self, hp_name=None, step=None):
        """Update the current hyperparameter values.

        Args:
            hp_name (str): name of hyperparameter. If given ``np_name`` is None, any updatable
                ``hp_name`` is selected arbitrarily.
            step (int or float): see *Hyperparameter* class.

        Return:
            bool: if the value is changed or not.
        """
        if hp_name is not None:
            for hp in self._hps:
                if hp.name == hp_name:
                    return hp.step(step)
            return False

        for hp in self._hps:
            result = hp.step(step)
            if result is True:
                return True
        return False

    def add_hp_from_dict(self, hps):
        """Add hyperparameters from dictionary.

        Values of the dictionary should be a list of allowed hyperparameter values. *Continuous*
        mode is not supported yet.

        Args:
            hps (dict): dict of hyperparameter values.

        Examples:
            >>> hp_dict = dict(hp0=[0, 1, 2], hp1=[3, 4, 5])
            >>> hps.add_hp_from_dict(hp_dict)
        """
        for key, values in hps.items():
            if isinstance(values, list):
                self.add_hp(key, values, is_continuous=False)
            else:
                raise ValueError(
                    'Only list of discrete values is supported for converting from dict')

    def add_hp(self, name, values, is_continuous=False):
        """Add hyperparameter.

        Args:
            name (str): the name of hyperparameter.
            values (tuple or list): please see *Hyperparameter* class.
            is_continuous (bool): Hyperparameter is *continuous* or not.
        """
        self._hps.append(Hyperparameter(name, values, is_continuous))

    def set_min_hps(self):
        """Set the minimum value for each Hyperparameter."""
        for hp in self._hps:
            hp.set_min_value()

    def set_max_hps(self):
        """Set the maximum value for each Hyperparameter."""
        for hp in self._hps:
            hp.set_max_value()

    def get_current_hps(self):
        """Returns the current values of Hyperparameters.

        Returns:
            dict: dict of the current hyperparameter values.
        """
        results = {}
        for hp in self._hps:
            results[hp.name] = hp.value
        return results

    def get_grid_hps(self):
        """Returns all possible combination of hyperparameters values.

        If registered *Hyperparameter* class instance is *continuous* mode, values are sampled
        between ``min`` and ``max`` by dividing ``default step``.

        Returns:
            list: all possible combination of hyperparameters values.
        """
        hps_keys = []
        hps_values = []
        results = []

        if not self._hps:
            return results

        for hp in self._hps:
            hps_keys.append(hp.name)
            hps_values.append(hp.get_grid())

        for value in itertools.product(*hps_values):
            result = {}
            for index, key in enumerate(hps_keys):
                result[key] = value[index]
            results.append(result)
        return results

    def get_hp_names(self):
        """Returns the names of hyperparameters.

        Returns:
            list: the names of hyperparameters.
        """
        return [hp.name for hp in self._hps]