from flask import (
    Blueprint, flash, g, redirect, render_template, request, url_for
)

from werkzeug.exceptions import abort

from eventosABC.auth import login_required
from eventosABC.db import get_db

bp = Blueprint('evento', __name__)

@bp.route('/')
@login_required
def index():
    db = get_db()
    eventos = db.execute(
        'SELECT e.id, creado, titulo, fecha, hora_inicio, author_id FROM '
        'evento e JOIN user u on e.author_id=u.id WHERE u.id =?'
        ' ORDER BY creado ASC', (g.user['id'],)
    ).fetchall()
    return render_template('eventos/index.html', eventos=eventos)

@bp.route('/create', methods=('GET', 'POST'))
@login_required
def create():
    if request.method == 'POST':
        titulo = request.form['titulo']
        fecha = request.form['fecha']
        hora_inicio = request.form['hora_inicio']
        hora_fin = request.form['hora_fin']
        descripcion = request.form['descripcion']

        error = None

        if not titulo:
            error = "Es necesario llenar todos los campos"
        if not fecha:
            error = "Es necesario llenar todos los campos"
        if not descripcion:
            error = "Es necesario llenar todos los campos"
        if not hora_inicio:
            error = "Es necesario llenar todos los campos"
        if not hora_fin:
            error = "Es necesario llenar todos los campos"

        if error is not None:
            flash(error)
        else:
            db = get_db()
            db.execute(
                'INSERT INTO evento (titulo, descripcion, author_id, '
                'fecha, hora_inicio, hora_fin) values(?, ?, ?, ?, ?, ?)',
                (titulo, fecha, g.user['id'], descripcion, hora_inicio, hora_fin, )
            )
            db.commit()
            return redirect(url_for('evento.index'))

    return render_template('eventos/create.html')

def get_evento(id, check_author=True):
    evento = get_db().execute(
        'SELECT e.id, titulo, descripcion, creado, fecha, hora_inicio, hora_fin, author_id'
        ' FROM evento e JOIN user u ON e.author_id=u.id WHERE e.id=?', (id,)
    ).fetchone()

    if evento is None:
        abort(404, "El evento que esta buscando no existe.")
    elif check_author and evento['author_id'] != g.user['id']:
        abort(403, "No tienes perimso para ver este evento.")

    return evento

@bp.route('/<int:id>/detail', methods=('GET', 'POST'))
@login_required
def detail_evento(id):
    evento = get_evento(id)
    return render_template('eventos/detail.html', evento=evento)

@bp.route('/<int:id>/update', methods=('GET', 'POST'))
@login_required
def update_evento(id):
    evento = get_evento(id)

    if request.method == 'POST':
        titulo = request.form['titulo']
        fecha = request.form['fecha']
        descripcion = request.form['descripcion']
        hora_inicio = request.form['hora_inicio']
        hora_fin = request.form['hora_fin']

        error = None

        if not titulo:
            error = "Es necesario llenar todos los campos"
        if not fecha:
            error = "Es necesario llenar todos los campos"
        if not descripcion:
            error = "Es necesario llenar todos los campos"
        if not hora_inicio:
            error = "Es necesario llenar todos los campos"
        if not hora_fin:
            error = "Es necesario llenar todos los campos"

        if error is not None:
            flash(error)
        else:
            db = get_db()
            db.execute(
                'UPDATE evento SET titulo=?, descripcion=?,'
                'fecha=?, hora_inicio=?, hora_fin=? WHERE id=?',
                (titulo, fecha, descripcion, hora_inicio, hora_fin, evento['id'])
            )
            db.commit()
            return redirect(url_for('evento.index'))

    return render_template('eventos/update.html', evento=evento)

@bp.route('/<int:id>/delete', methods=('POST',))
@login_required
def delete_evento(id):
    db = get_db()
    get_evento(id)
    db.execute('DELETE FROM evento WHERE id = ?', (id,))
    db.commit()
    return redirect(url_for('evento.index'))


import os
import time
import argparse
import numpy as np
import tensorflow as tf

from progress.bar import Bar
from ipywidgets import IntProgress
from IPython.display import display
import skimage.transform
import imageio

from model import VGG16
from utils import read_images, read_masks, read_list, label2rgb

TRAIN_DIR = "hw3-train-validation/train/"
VAL_DIR = "hw3-train-validation/validation/"

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--init_from', type=str, default='keras-vgg16.npy', help='pre-trained weights')
    parser.add_argument('--save_dir', type=str, default='save', help='directory to store checkpointed models')
    parser.add_argument('--mode', type=str, default='FCN32s', help='FCN mode: FCN32s, FCN16s, FCN8s')
    parser.add_argument('--lr', type=float, default=1e-4, help='starting learning rate')
    parser.add_argument('--decay', type=float, default=0.0, help='multiplier for weight decay')
    parser.add_argument('--keep_prob', type=float, default=1.0, help='dropout keep probability for fc layer')
    parser.add_argument('--note', type=str, default='', help='argument for taking notes')

    FLAG = parser.parse_args()

    print("===== create directory =====")
    if not os.path.exists(FLAG.save_dir):
        os.makedirs(FLAG.save_dir)

    train(FLAG)

def train(FLAG):
    print("Reading dataset...")
    # load data
    Xtrain, Ytrain = read_images(TRAIN_DIR), read_masks(TRAIN_DIR, onehot=True)
    Xtest, Ytest = read_images(VAL_DIR), read_masks(VAL_DIR, onehot=True)
    track = ["hw3-train-validation/validation/0008","hw3-train-validation/validation/0097","hw3-train-validation/validation/0107"]
    Xtrack, Ytrack = read_list(track)

    vgg16 = VGG16(classes=7, shape=(256,256,3))
    vgg16.build(vgg16_npy_path=FLAG.init_from, mode=FLAG.mode, keep_prob=FLAG.keep_prob)

    saver = tf.train.Saver(tf.global_variables(), max_to_keep=1)
    checkpoint_path = os.path.join(FLAG.save_dir, 'model.ckpt')

    def initialize_uninitialized(sess):
        global_vars = tf.global_variables()
        is_not_initialized = sess.run([tf.is_variable_initialized(var) for var in global_vars])
        not_initialized_vars = [v for (v,f) in zip(global_vars, is_not_initialized) if not f]
        if len(not_initialized_vars):
                sess.run(tf.variables_initializer(not_initialized_vars))

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())

        # hyper parameters
        batch_size = 32
        epoch = 500
        early_stop_patience = 50
        min_delta = 0.0001
        opt_type = 'adam'

        # recorder
        epoch_counter = 0

        # optimizer
        global_step = tf.Variable(0, trainable=False)

        # Passing global_step to minimize() will increment it at each step.
        if opt_type is 'sgd':
            start_learning_rate = FLAG.lr
            half_cycle = 2000
            learning_rate = tf.train.exponential_decay(start_learning_rate, global_step, half_cycle, 0.5, staircase=True)
            opt = tf.train.MomentumOptimizer(learning_rate=learning_rate, momentum=0.9, use_nesterov=True)
        else:
            start_learning_rate = FLAG.lr
            half_cycle = 2000
            learning_rate = tf.train.exponential_decay(start_learning_rate, global_step, half_cycle, 0.5, staircase=True)
            opt = tf.train.AdamOptimizer(learning_rate=learning_rate)

        obj = vgg16.loss
        train_op = opt.minimize(obj, global_step=global_step)

        # progress bar
        ptrain = IntProgress()
        pval = IntProgress()
        display(ptrain)
        display(pval)
        ptrain.max = int(Xtrain.shape[0]/batch_size)
        pval.max = int(Xtest.shape[0]/batch_size)

        # re-initialize
        initialize_uninitialized(sess)

        # reset due to adding a new task
        patience_counter = 0
        current_best_val_loss = np.float('Inf')

        # optimize when the aggregated obj
        while(patience_counter < early_stop_patience and epoch_counter < epoch):

            # start training
            stime = time.time()
            bar_train = Bar('Training', max=int(Xtrain.shape[0]/batch_size), suffix='%(index)d/%(max)d - %(percent).1f%% - %(eta)ds')
            bar_val =  Bar('Validation', max=int(Xtest.shape[0]/batch_size), suffix='%(index)d/%(max)d - %(percent).1f%% - %(eta)ds')

            train_loss, train_accu = 0.0, 0.0
            for i in range(int(Xtrain.shape[0]/batch_size)):
                st = i*batch_size
                ed = (i+1)*batch_size
                loss, accu,_ = sess.run([obj, vgg16.accuracy, train_op],
                                    feed_dict={vgg16.x: Xtrain[st:ed,:],
                                                vgg16.y: Ytrain[st:ed,:],
                                                vgg16.is_train: True})
                train_loss += loss
                train_accu += accu
                ptrain.value +=1
                ptrain.description = "Training %s/%s" % (ptrain.value, ptrain.max)
            train_loss = train_loss/ptrain.value
            train_accu = train_accu/ptrain.value

            # validation
            val_loss = 0
            val_accu = 0
            for i in range(int(Xtest.shape[0]/batch_size)):
                st = i*batch_size
                ed = (i+1)*batch_size
                loss, accu = sess.run([obj, vgg16.accuracy],
                                    feed_dict={vgg16.x: Xtest[st:ed,:],
                                                vgg16.y: Ytest[st:ed,:],
                                                vgg16.is_train: False})
                val_loss += loss
                val_accu += accu
                pval.value += 1
                pval.description = "Testing %s/%s" % (pval.value, pval.value)
            val_loss = val_loss/pval.value
            val_accu = val_accu/pval.value

            # plot
            if epoch_counter%10 == 0:
                Xplot = sess.run(vgg16.pred,
                        feed_dict={vgg16.x: Xtrack[:,:],
                                    vgg16.y: Ytrack[:,:],
                                    vgg16.is_train: False})

                for i, fname in enumerate(track):
                    saveimg = skimage.transform.resize(Xplot[i],output_shape=(512,512),order=0,preserve_range=True,clip=False)
                    saveimg = label2rgb(saveimg)
                    imageio.imwrite(os.path.join(FLAG.save_dir,os.path.basename(fname)+"_pred_"+str(epoch_counter)+".png"), saveimg)
                    print(os.path.join(FLAG.save_dir,os.path.basename(fname)+"_pred_"+str(epoch_counter)+".png"))

            # early stopping check
            if (current_best_val_loss - val_loss) > min_delta:
                current_best_val_loss = val_loss
                patience_counter = 0
                saver.save(sess, checkpoint_path, global_step=epoch_counter)
                print("save in %s" % checkpoint_path)
            else:
                patience_counter += 1

            # shuffle Xtrain and Ytrain in the next epoch
            idx = np.random.permutation(Xtrain.shape[0])
            Xtrain, Ytrain = Xtrain[idx,:,:,:], Ytrain[idx,:]

            # epoch end
            epoch_counter += 1

            ptrain.value = 0
            pval.value = 0
            bar_train.finish()
            bar_val.finish()

            print("Epoch %s (%s), %s sec >> train loss: %.4f, train accu: %.4f, val loss: %.4f, val accu: %.4f" % (epoch_counter, patience_counter, round(time.time()-stime,2), train_loss, train_accu, val_loss, val_accu))

        # para_dict = sess.run(vgg16.para_dict)
        # np.save(os.path.join(FLAG.save_dir, "para_dict.npy"), para_dict)
        # print("save in %s" % os.path.join(FLAG.save_dir, "para_dict.npy"))

        # FLAG.optimizer = opt_type
        # FLAG.lr = start_learning_rate
        # FLAG.batch_size = batch_size
        # FLAG.epoch_end = epoch_counter
        # FLAG.val_loss = current_best_val_loss

        # header = ''
        # row = ''
        # for key in sorted(vars(FLAG)):
        #     if header is '':
        #         header = key
        #         row = str(getattr(FLAG, key))
        #     else:
        #         header += ","+key
        #         row += ","+str(getattr(FLAG,key))
        # row += "\n"
        # if os.path.exists("/home/cmchang/DLCV2018SPRING/hw3/model.csv"):
        #     with open("/home/cmchang/DLCV2018SPRING/hw3/model.csv", "a") as myfile:
        #         myfile.write(row)
        # else:
        #     with open("/home/cmchang/DLCV2018SPRING/hw3/model.csv", "w") as myfile:
        #         myfile.write(header)
        #         myfile.write(row)

if __name__ == '__main__':
    main()


from django.contrib.auth import get_user_model

from rest_framework import serializers
from rest_framework.relations import SlugRelatedField

from posts.models import Comment, Follow, Group, Post

User = get_user_model()

class PostSerializer(serializers.ModelSerializer):
    author = SlugRelatedField(slug_field='username', read_only=True)

    class Meta:
        fields = '__all__'
        model = Post

class GroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = Group
        fields = '__all__'

class CommentSerializer(serializers.ModelSerializer):
    author = serializers.SlugRelatedField(
        read_only=True, slug_field='username'
    )

    class Meta:
        fields = '__all__'
        model = Comment

class FollowSerializer(serializers.ModelSerializer):
    user = serializers.SlugRelatedField(
        read_only=True, slug_field='username'
    )
    following = serializers.SlugRelatedField(
        queryset=User.objects.all(), slug_field='username'
    )

    class Meta:
        fields = '__all__'
        model = Follow

    def validate(self, data):
        follower = self.context.get('request').user
        following = data.get('following')

        if Follow.objects.filter(user=follower, following=following).exists():
            raise serializers.ValidationError(
                'Вы уже подписаны на данного пользователя.'
            )

        if follower == following:
            raise serializers.ValidationError(
                'Нельзя подписаться на самого себя.'
            )
        return data


from functools import reduce
from collections import Counter
from utils import read_file, parse_multiline

def find_group_count(entry):
    entry_set = set(''.join(entry.split()))
    return len(entry_set)

def common_letters(group):
    counts = Counter(''.join(group.split()))
    letters = [letter for letter, cnt in counts.most_common() if cnt == len(group.split())]
    return letters

if __name__ == '__main__':
    data = read_file("day6/data.txt")
    parsed = parse_multiline(data)
    ans = sum([find_group_count(entry) for entry in parsed])
    print(f"Sum of each group count {ans}")

    group_letters = [common_letters(group) for group in parsed]
    ans = sum(map(len, group_letters))
    print(f"Sum where groups all answered yes count {ans}")


from __future__ import absolute_import, print_function

import shutil
import tempfile

import pytest
from flask import Flask
from flask_menu import Menu
from invenio_accounts import InvenioAccounts
from invenio_assets import InvenioAssets
from invenio_jsonschemas import InvenioJSONSchemas

from invenio_records_editor.ext import InvenioRecordsEditor
from invenio_records_editor.views import create_editor_blueprint

@pytest.fixture()
def editor_config():
    """Editor example config."""
    config = {
        "items": {
            "recordConfig": {
                "apiUrl": "api/items/",
                "schema": "items/item-v1.0.0.json",
            },
            "editorConfig": {
                "schemaOptions": {
                    "alwaysShow": [
                        "legacy_id",
                        "shelf",
                        "description",
                        "circulation_restriction",
                        "medium",
                        "legacy_library_id",
                    ],
                    "properties": {
                        "$schema": {"hidden": True},
                        "document": {"hidden": True},
                        "internal_location": {"hidden": True},
                        "circulation_status": {"hidden": True},
                    },
                }
            },
        }
    }
    return config

@pytest.fixture()
def instance_path():
    """Temporary instance path."""
    path = tempfile.mkdtemp()
    yield path
    shutil.rmtree(path)

@pytest.fixture()
def base_app(instance_path, editor_config):
    """Flask application fixture."""
    app = Flask("testapp", instance_path=instance_path)

    app.config.update(
        SECRET_KEY="SECRET_KEY", TESTING=True, SERVER_NAME="localhost"
    )
    app.config.update(RECORDS_EDITOR_UI_CONFIG=editor_config)

    InvenioAccounts(app)
    InvenioAssets(app)
    InvenioJSONSchemas(app)
    InvenioRecordsEditor(app)
    Menu(app)

    from invenio_accounts.views.settings import blueprint
    app.register_blueprint(blueprint)

    app.register_blueprint(create_editor_blueprint(app))
    return app

@pytest.fixture()
def app(base_app):
    """Flask application fixture."""
    with base_app.app_context():
        yield base_app


from __future__ import annotations
from abc import ABC, abstractmethod

import datetime
from chrome import ChromeDriver
from html_parser import HTMLParser, Element
from typing import List

PCF_TEMPLATE = 'https://investor.vanguard.com/etf/profile/portfolio/%s/pcf'
OVERVIEW_TEMPLATE = 'https://investor.vanguard.com/etf/profile/overview/%s'

class ETFFetcher(ABC):
    @abstractmethod
    def holdings(self) -> Holdings:
        pass

    @abstractmethod
    def nav(self) -> float:
        pass

    @abstractmethod
    def quit(self) -> None:
        pass

class VanguardETFFetcher(ETFFetcher):
    def __init__(self, driver: ChromeDriver, html_parser: HTMLParser):
        self._driver = driver
        self._html_parser = html_parser

    def holdings(self, ticker: str) -> Holdings:
        url = PCF_TEMPLATE % ticker
        self._driver.load(url)
        self._expand_page()
        self._parse_source()

        raw_date = self._html_parser.find_first(
            'span', {'class': 'displayBlock ng-binding'}).content()
        date = datetime.datetime.strptime(raw_date, 'as of %m/%d/%Y')

        raw_elements = self._retrieve_holding_elements()
        holding_elements = self._parse_holding_elements(raw_elements)

        return Holdings(date, holding_elements)

    def _expand_page(self) -> None:
        selector = "a[data-ng-click='goToNextPage()'"
        next_page = self._driver.clickable_element(selector)
        next_page.click_until_stale()

    def _parse_source(self) -> None:
        html = self._driver.source()
        self._html_parser.parse(html)

    def _retrieve_holding_elements(self) -> List[Element]:
        elements = self._html_parser.find_all('tr', {
            'data-ng-repeat': 'curRow in dynamicData.pcfData.items ' +
            '| startFrom : pagination.startLoopFrom | limitTo : pagination.showUpto ' +
            '| orderBy : shareQuantity'}
        )
        elements = elements[:len(elements) // 2]
        return elements

    @staticmethod
    def _parse_holding_elements(holding_elements: List[Element]) -> List[Holdings.Entry]:
        holdings = []
        for holding_element in holding_elements:
            elements = holding_element.find_all('td', {'class': 'ng-binding'})
            ticker = elements[0].content().replace('.', '-')
            sharesText = elements[2].content().replace(',', '')
            shares = int(sharesText)
            holdings.append(Holdings.Entry(ticker, shares))
        return holdings

    def nav(self, ticker: str) -> float:
        url = OVERVIEW_TEMPLATE % ticker
        self._driver.load(url)
        selector = 'span[class="ng-scope ng-binding sceIsLayer arrange arrangeSec"'
        self._driver.wait(selector, count=5)
        self._parse_source()

        return self._parse_nav()

    def _parse_nav(self) -> float:
        elements = self._html_parser.find_all(
            'span', {'class': 'ng-scope ng-binding sceIsLayer arrange arrangeSec'})
        nav = elements[4].content()[1:]
        return float(nav)

    def quit(self) -> None:
        self._driver.quit()

class Holdings(object):
    class Entry(object):
        def __init__(self, ticker: str, shares: int):
            self.ticker = ticker
            self.shares = shares

        def __repr__(self):
            return f'(Ticker: {self.ticker}, Shares: {self.shares})'

    def __init__(self, date: datetime.datetime, entries: List[Entry]):
        self.date = date
        self.entries = entries

    def __repr__(self):
        repr = f'As of {self.date}:\n'
        repr += '\n'.join(f'{idx+1} - {h}' for idx,
                          h in enumerate(self.entries))
        return repr


from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from rest_framework.views import APIView

from main.models import TenantFAQ, PartnerFAQ, News, TopBanner
from main.serializers import TenantFAQSerializer, PartnerFAQSerializer, NewsSerializer

class TenantFAQView(ListAPIView):
    """"""
    queryset = TenantFAQ.objects.all()
    serializer_class = TenantFAQSerializer

class PartnerFAQView(ListAPIView):
    """"""
    queryset = PartnerFAQ.objects.all()
    serializer_class = PartnerFAQSerializer

class NewsView(ListAPIView):
    """"""
    queryset = News.objects.all()
    serializer_class = NewsSerializer

class TopBannerView(APIView):
    """"""
    @staticmethod
    def get(request, format=None):
        results = TopBanner.objects.filter(is_active=True)
        if results:
            return Response({"text": results[0].text})
        else:
            return Response({"text": None})


# -*- coding: utf-8 -*-
"""
Created on Thu Jun 24 10:36:17 2021

@author: Research_Lab
"""

import numpy as np
from scipy import fftpack
from matplotlib import pyplot as plt
#%%
import pandas
import os
datadir = os.path.join('C:\\Users\\Research Lab\\Desktop\\SI_Resources\\Synthetic_topography\\') # directory for some sample data files
#filename = 'Elevation_profile2.csv'
filename = "site1.csv"
filepath = os.path.join(datadir, filename)
df = pandas.read_csv(filepath)

sig = df.ix[:,1]
sig_non_zero = sig[sig!=0]
#%%
#%%
# The FFT of the signal
sig_fft = fftpack.fft(sig_non_zero)

# And the power (sig_fft is of complex dtype)
power = np.abs(sig_fft)**2

# The corresponding frequencies
sample_freq = fftpack.fftfreq(sig_non_zero.size)

# Plot the FFT power
plt.figure(figsize=(6, 5))
plt.plot(sample_freq, power)
plt.xlabel('Frequency [Hz]')
plt.ylabel('plower')

# Find the peak frequency: we can focus on only the positive frequencies
pos_mask = np.where(sample_freq > 0)
freqs = sample_freq[pos_mask]
peak_freq = freqs[power[pos_mask].argmax()]

# Check that it does indeed correspond to the frequency that we generate
# the signal with
#np.allclose(peak_freq, 1./period)

# An inner plot to show the peak frequency
axes = plt.axes([0.55, 0.3, 0.3, 0.5])
plt.title('Peak frequency')
plt.plot(freqs[:15], power[:15])
plt.setp(axes, yticks=[])

plt.figure(figsize=(9, 7))
plt.plot(freqs[2:50], power[2:50])

# scipy.signal.find_peaks_cwt can also be used for more advanced
# peak detection
#%%
time_vec = np.arange(0, sig_non_zero.size, 1)
time_vec = df.ix[:,0]
#%%
#Setting a cutoff threshold at the first

high_freq_fft_coarse = sig_fft.copy()
high_freq_fft_coarse[np.abs(sample_freq) > peak_freq] = 0
filtered_sig_coarse = fftpack.ifft(high_freq_fft_coarse)

high_freq_fft_fine = sig_fft.copy()
high_freq_fft_fine [np.abs(sample_freq) > freqs[2]] = 0
filtered_sig_fine = fftpack.ifft(high_freq_fft_fine)

high_freq_fft_finest = sig_fft.copy()
high_freq_fft_finest [np.abs(sample_freq) > 0.002] = 0
filtered_sig_finest = fftpack.ifft(high_freq_fft_finest)

#%%
# Estimating the standard deviation for the noise

SD_sample_coarse = np.std(sig_non_zero-filtered_sig_coarse )
noise_random_coarse = np.random.normal(0, .25, sig_non_zero.size)
synthetic_topo_coarse = filtered_sig_coarse + noise_random_coarse

SD_sample_fine = np.std(sig_non_zero-filtered_sig_fine )
noise_random_fine = np.random.normal(0, .25, sig_non_zero.size)
synthetic_topo_fine = filtered_sig_fine + noise_random_fine

SD_sample_finest = np.std(sig_non_zero-filtered_sig_finest )
noise_random_finest = np.random.normal(0, .25, sig_non_zero.size)
synthetic_topo_finest = filtered_sig_finest + noise_random_finest

#%%
# Generating Plots

plt.figure(figsize=(10, 10))
plt.subplot(2, 2, 1)
plt.plot(time_vec, sig_non_zero, linewidth=2, label='Elev Prof Site 1')
plt.xlabel('Distance (degrees)')
plt.ylabel('Elevation (m)')
plt.legend(loc='best')

plt.subplot(2, 2, 2)
plt.plot(time_vec, sig_non_zero, linewidth=2, label='Elev Prof Site 1')
plt.plot(time_vec, synthetic_topo_coarse, linewidth=1, label='Syn topo coarse')
plt.xlabel('Distance (degrees)')
plt.ylabel('Elevation (m)')
plt.legend(loc='best')

plt.subplot(2, 2, 3)
plt.plot(time_vec, sig_non_zero, linewidth=2, label='Elev Prof Site 1')
plt.plot(time_vec, synthetic_topo_fine, linewidth=1, label='Syn topo fine')
plt.xlabel('Distance (degrees)')
plt.ylabel('Elevation (m)')
plt.legend(loc='best')

plt.subplot(2, 2, 4)
plt.plot(time_vec, sig_non_zero, linewidth=2, label='Elev Prof Site 1')
plt.plot(time_vec, synthetic_topo_finest, linewidth=1, label='Syn topo finest')
plt.xlabel('Distance (degrees)')
plt.ylabel('Elevation (m)')
plt.legend(loc='best')

#%%


import pyautogui
import keyboard as key
from PIL import ImageGrab
from PIL import Image
import pygame

pygame.init()

swidth, sheigth = pyautogui.size()

win = pygame.display.set_mode((swidth,sheigth))

pygame.display.set_caption("RAT")

def PrtScn():
    width, heigth = pyautogui.size()
    run = True
    while run:
        if key.is_pressed("p"):
            bbox = 0, 0, width, heigth
            screenshot = ImageGrab.grab(bbox)
            screenshot.save(r"C:\Users\siaaa013\Documents\Programering\python\backdoor\image.png")

sc = pygame.image.load(r"C:\Users\siaaa013\Documents\Programering\python\backdoor\image.png")

def redraw(win):
    win.blit(sc,(0,0))
    pygame.display.update()

#main loop

run = True
while run:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()

    sc = pygame.image.load(r"C:\Users\sigur\OneDrive\Bilder\Kamerabilder\image.png")

    redraw(win)

pygame.quit()


from django.urls import path, include
from .views import *

app_name = 'app'

urlpatterns = [
    # User Auth
    path('user/sign_up/', CreateUser.as_view(), name="create_user"),
    path('user/log_out/blacklist/', BlacklistTokenView.as_view(), name='blacklist'),

    # Reset User Password
    path('auth/', include('djoser.urls')),

    # Books
    path('books/<str:ISBN>', Books.as_view(), name="retrieve_book"),

    # Friends
    path('friends/', FriendsView.as_view(), name='friends'),
    path('friends/user/<int:other_user_id>', OtherUserFriendsView.as_view(), name='other_user_friends'),
    path('friends/<int:other_user_id>', FriendView.as_view(), name='single_friend'),
    path('friend_requests/', FriendRequestsView.as_view(), name='friend_requests'),

    # Chat
    path('chat/', ChatListView.as_view()),
    path('chat/leave/<pk>/', ChatLeaveView.as_view()),

    # Recommender system
    path('recommender/', RecommenderAPI.as_view(), name='recommender'),
    path('recommender/<str:action>/', RecommenderAPI.as_view(), name='recommender_action'),
    path('recommender/<int:m>/<int:n>/<int:id>/<str:action>/', RecommenderAPI.as_view(), name='recommender_top_n'),
    path('recommender/<int:m>/<int:n>/<int:id>/<str:action>/<str:genre>/', RecommenderAPI.as_view(),
         name='recommender_top_n_for_genre'),
    path('recommender/<int:m>/<int:n>/<str:action>/', RecommenderAPI.as_view(), name='recommender_top_n_global'),
    path('recommender/<int:m>/<int:n>/<str:action>/<str:genre>/', RecommenderAPI.as_view(),
         name='recommender_top_n_global_for_genre'),

    # Feed
    path('feed/', FeedView.as_view(), name='feed'),
    path('posts/', AllPostsView.as_view(), name='all_posts'),
    path('posts/<int:post_id>', PostView.as_view(), name='post'),
    path('posts/<int:post_id>/comments/', AllCommentsView.as_view(), name='all_comments'),
    path('posts/<int:post_id>/comments/<int:comment_id>', CommentView.as_view(), name='comment'),
    path('posts/<int:post_id>/comments/<int:comment_id>/replies/', AllRepliesView.as_view(), name='all_replies'),
    path('posts/<int:post_id>/comments/<int:comment_id>/replies/<int:reply_id>', ReplyView.as_view(), name='reply'),
    path('feed/clubs/<int:club_id>', ClubFeedView.as_view(), name='club_feed'),

    # Club API
    path('user/get_update/<int:id>/', UserDetails.as_view(), name="get_update"),
    path('clubs/', Clubs.as_view(), name='clubs'),
    path('clubs/user/<int:user_id>', UserClubView.as_view(), name='user_clubs'),
    path('singleclub/<int:id>/', SingleClub.as_view(), name='retrieve_single_club'),
    path('singleclub/<int:id>/<str:action>/<int:user_id>', SingleClub.as_view(), name='manage_club'),
    path('singleclub/<int:id>/<str:action>/', SingleClub.as_view(), name='update_club'),

    # Search API
    path('search/', SearchView.as_view(), name='search'),

    # Ratings
    path('ratings/', AllRatingsView.as_view(), name='user_ratings'),
    path('ratings/<int:rating_id>/', RatingView.as_view(), name='rating'),
    path('books/<str:isbn>/ratings/', BookRatingsView.as_view(), name='book_ratings'),
    path('ratings/other_user/<int:other_user_id>', OtherUserRatingsView.as_view(), name='other_user_ratings'),

    # Others
    path('get_current_user/', GetCurrentUserView.as_view(), name='current_user'),

    # Genre API
    path('genres/', GenresView.as_view(), name='genres'),

    # Feed
    path('feed/', FeedView.as_view(), name='feed'),
    path('posts/', AllPostsView.as_view(), name='all_posts'),
    path('posts/<int:post_id>', PostView.as_view(), name='post'),
    path('posts/user/<int:other_user_id>', OtherUserPostsView.as_view(), name='other_user_posts'),
    path('posts/<int:post_id>/comments/', AllCommentsView.as_view(), name='all_comments'),
    path('posts/<int:post_id>/comments/<int:comment_id>', CommentView.as_view(), name='comment'),
    path('posts/<int:post_id>/comments/<int:comment_id>/replies/', AllRepliesView.as_view(), name='all_replies'),
    path('posts/<int:post_id>/comments/<int:comment_id>/replies/<int:reply_id>', ReplyView.as_view(), name='reply'),

    # Scheduling API
    path('scheduling/', SchedulingView.as_view(), name='scheduling'),
    path('scheduling/<int:id>/', SchedulingView.as_view(), name='scheduling_with_id'),
    path('scheduling/<int:id>/<str:action>/', SchedulingView.as_view(), name='scheduling_update'),
    path('calendar/', CalendarView.as_view(), name='calendar'),
    path('calendar/<int:id>', CalendarView.as_view(), name='calendar_with_id'),
    path('meetings/', MeetingsView.as_view(), name='meetings'),
    path('meetings/<int:id>', MeetingsView.as_view(), name='meetings_with_id'),
    path('club_meetings/', ClubMeetingsView.as_view(), name='club_meetings'),
    path('club_meetings/<int:id>', ClubMeetingsView.as_view(), name='club_meetings_with_id'),
]


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome(executable_path="D:\webdrivers\chromedriver\chromedriver_win32\chromedriver.exe")

driver.maximize_window()

driver.get("http://www.flipkart.com")
time.sleep(2)
print(driver.title)

#login by entering user id and password
driver.find_element_by_xpath("/html/body/div[2]/div/div/div/div/div[2]/div/form/div[1]/input").send_keys(9439749279)
driver.find_element_by_xpath("/html/body/div[2]/div/div/div/div/div[2]/div/form/div[2]/input").send_keys("manojyavam")
driver.find_element_by_xpath("(//*[@type='submit'])[2]").click()

time.sleep(10)
driver.find_element_by_name("q").send_keys("mobile",Keys.ENTER)
time.sleep(2)
#driver.find_element_by_xpath("//*[@id='container']/div/div[1]/div[1]/div[2]/div[2]/form/div/button").click()

time.sleep(10)
driver.close()     # Closing the web browser


import pandas as pd
import json
import streamlit as st
import time
from snowflake.snowpark import Session

import pandas as pd
import json
import streamlit as st
from snowflake.snowpark import Session
import time

if 'snowflake_connection' not in st.session_state:
    # connect to Snowflake
    with open('creds.json') as f:
        connection_parameters = json.load(f)
    st.session_state.snowflake_connection = Session.builder.configs(connection_parameters).create()
    session = st.session_state.snowflake_connection
else:
    session = st.session_state.snowflake_connection

st.set_page_config(layout="centered", page_title="Data Editor", page_icon="ðŸ§®")
st.title("Demo APP")
st.caption("This is a demo powered by Thirdeyedata.")

def get_dataset():
    # load messages df
    df = session.table("TEDEMO")

    return df

dataset = get_dataset()

with st.form("data_editor_form"):
     st.caption("Edit the dataframe below")
     edited = st.experimental_data_editor(dataset, use_container_width=True, num_rows="dynamic")
     submit_button = st.form_submit_button("Submit")

if submit_button:
    try:
        session.write_pandas(edited, "TEDEMO", overwrite=True)
        st.success("Table updated")
        time.sleep(5)
    except:
        st.warning("Error updating table")
    #display success message for 5 seconds and update the table to reflect what is in Snowflake
    st.experimental_rerun()


import spacy
import itertools
import en_core_web_sm
nlp = en_core_web_sm.load()

def isSentence(changedSentence, originalSentence):
    '''
    Takes a changed sentence and the original sentence and returns True if
    they are close enough in meaning. If not, function return False.
    '''
    # Initializes the variables needed.
    originalSubject = None
    originalSentenceVerb = None
    changedSubject = None
    changedSentenceVerb = None

    # Makes both sentences Doc objects.
    nlpChangedSentence = nlp(changedSentence)
    nlpOriginalSentence = nlp(originalSentence)

    # Initializes dictionaries that will hold parts of speech data.
    sentenceElementsChangedSentence = dict()
    sentenceElementsOriginalSentence = dict()

    # Loops over both lists using itertools and populate dictionaries with part of speech data.
    for changedWord, originalWord in itertools.zip_longest(nlpChangedSentence, nlpOriginalSentence):

        # Once one of the lists ends, itertools makes the other list populate with None.
        # This makes sure None doesn't get added to dictionaries.
        if changedWord == None:
            continue
        sentenceElementsChangedSentence[changedWord] = (changedWord.dep_, changedWord.pos_)

        if originalWord == None:
            continue
        sentenceElementsOriginalSentence[originalWord] = (originalWord.dep_, originalWord.pos_)

    # Loops over both dictionaries and checks for conditions
    for key1, key2 in itertools.zip_longest(sentenceElementsChangedSentence, sentenceElementsOriginalSentence):
        similarity = nlpOriginalSentence.similarity(nlpChangedSentence)
        if key1 == None:
            continue
        if key2 == None:
            continue

        # Gets the subject and verb from the changed sentence and the original sentence.
        if sentenceElementsChangedSentence[key1][0] == 'ROOT' and sentenceElementsChangedSentence[key1][1] == 'VERB':
            changedSentenceVerb = key1
        if sentenceElementsOriginalSentence[key2][0] == 'ROOT' and sentenceElementsOriginalSentence[key2][1] == 'VERB':
            originalSentenceVerb = key2

        if (sentenceElementsChangedSentence[key1][0] == 'nsubj' or sentenceElementsChangedSentence[key1][0] == 'nsubjpass') and ((sentenceElementsChangedSentence[key1][1] == 'NOUN') or (sentenceElementsChangedSentence[key1][1] == 'PRON')):
            changedSubject = key1

        if (sentenceElementsOriginalSentence[key2][0] == 'nsubj' or sentenceElementsOriginalSentence[key2][0] == 'nsubjpass') and ((sentenceElementsOriginalSentence[key2][1] == 'NOUN') or (sentenceElementsOriginalSentence[key2][1] == 'PRON')):
            originalSubject = key2

    # Replaces elements in dictinary with None when they are empty.
    if changedSentenceVerb == None:
        changedSentenceVerb = nlp("None")
    if changedSubject == None:
        changedSubject = nlp("None")

    # Test to see if the two sentences are similar enough. If so, returns True.
    try:
        if (changedSentenceVerb.text == originalSentenceVerb.text) and \
                (originalSubject.text == changedSubject.text) \
                and (similarity > .91):
            return True
    except:
        return False


import contextlib
import datetime as dt
import io
import json
import traceback
import urllib.parse

import flask.json
import wand.image
from flask import Blueprint, jsonify, current_app, request, stream_with_context
from werkzeug.exceptions import HTTPException

import acnh.dodo as dodo
import acnh.designs.api as designs_api
import acnh.designs.render as designs_render
import acnh.designs.db as designs_db
import utils
import tarfile_stream
from acnh.errors import (
	ACNHError,
	InvalidDesignCodeError,
	MissingLayerError,
	InvalidScaleFactorError,
	CannotScaleThumbnailError,
	InvalidImageError,
	InvalidImageIdError,
	InvalidImageArgument,
	InvalidProArgument,
	InvalidAuthorIdError,
	TiledImageTooBigError,
	InvalidPaginationError,
	InvalidPaginationLimitError,
)
from acnh.designs.db import PageSpecifier, PageDirection
from acnh.designs.encode import BasicDesign, Design
from utils import limiter

def init_app(app):
	app.register_blueprint(bp)

bp = Blueprint('api', __name__, url_prefix='/api/v0')

@bp.route('/host-session/<dodo_code>')
@limiter.limit('1 per 4 seconds')
def host_session(dodo_code):
	return dodo.search_dodo_code(dodo_code)

@bp.route('/design/<design_code>')
@limiter.limit('5 per second')
def design(design_code):
	InvalidDesignCodeError.validate(design_code)
	return designs_api.download_design(design_code)

def get_scale_factor():
	scale_factor = request.args.get('scale', '1')
	InvalidScaleFactorError.validate(scale_factor)
	return int(scale_factor)

def maybe_scale(image):
	scale_factor = get_scale_factor()
	if scale_factor == 1:
		return image

	return utils.xbrz_scale_wand_in_subprocess(image, scale_factor)

@bp.route('/design/<design_code>.tar')
@limiter.limit('2 per 10 seconds')
def design_archive(design_code):
	InvalidDesignCodeError.validate(design_code)
	render_internal = 'internal_layers' in request.args
	get_scale_factor()  # do the validation now since apparently it doesn't work in the generator
	data = designs_api.download_design(design_code)
	meta, body = data['mMeta'], data['mData']
	# pylint: disable=unused-variable
	type_code = meta['mMtUse']
	design_name = meta['mMtDNm']  # hungarian notation + camel case + abbreviations DO NOT mix well

	def gen():
		# pylint: disable=no-member  # pylint are you drunk?
		if type_code == BasicDesign.type_code or render_internal:
			layers = designs_render.render_layers(body)
		else:
			layers = Design.from_data(data).layer_images.items()

		yield from make_tar(design_name, data['updated_at'], layers)

	encoded_filename = urllib.parse.quote(design_name + '.tar')
	return current_app.response_class(
		stream_with_context(gen()),
		mimetype='application/x-tar',
		headers={'Content-Disposition': f"attachment; filename*=utf-8''{encoded_filename}"},
	)

def make_tar(design_name, updated_at, layers):
	tar = tarfile_stream.open(mode='w|')
	yield from tar.header()

	for name, image in layers:
		tarinfo = tarfile_stream.TarInfo(f'{design_name}/{name}.png')
		tarinfo.mtime = updated_at

		image = maybe_scale(image)
		out = io.BytesIO()
		with image.convert('png') as c:
			c.save(file=out)
		tarinfo.size = out.tell()
		out.seek(0)

		yield from tar.addfile(tarinfo, out)

	yield from tar.footer()

# no rate limit as we need to render the thumbnails for all of an author's designs quickly
@bp.route('/design/<design_code>/<layer>.png')
def design_layer(design_code, layer):
	InvalidDesignCodeError.validate(design_code)
	data = designs_api.download_design(design_code)
	meta, body = data['mMeta'], data['mData']
	design_name = meta['mMtDNm']

	if layer == 'thumbnail':
		if request.args.get('scale', '1') != '1':
			raise CannotScaleThumbnailError
		rendered = Design.from_data(data).net_image()
	else:
		try:
			int(layer)
		except ValueError:
			rendered = designs_render.render_layer_name(data, layer)
		else:
			rendered = designs_render.render_layer(body, layer)

	rendered = maybe_scale(rendered)
	out = rendered.make_blob('png')

	encoded_filename = urllib.parse.quote(f'{design_name}-{layer}.png')
	return current_app.response_class(out, mimetype='image/png', headers={
		'Content-Length': len(out),
		'Content-Disposition': f"inline; filename*=utf-8''{encoded_filename}"
	})

@bp.route('/designs/<author_id>')
@limiter.limit('5 per 1 seconds')
def list_designs(author_id):
	author_id = int(InvalidAuthorIdError.validate(author_id).replace('-', ''))
	pro = request.args.get('pro', 'false')
	InvalidProArgument.validate(pro)

	page = designs_api.list_designs(author_id, pro=pro)
	del page['offset'], page['count'], page['total']
	page['designs'] = page.pop('headers')
	page['creator_name'] = page['designs'][0]['design_player_name']
	page['author_id'] = page['designs'][0]['design_player_id']

	for d in page['designs']:
		d['design_code'] = designs_api.design_code(d['id'])
		del d['id']
		del d['design_player_name'], d['design_player_id'], d['digest']
		d['created_at'] = dt.datetime.utcfromtimestamp(d['created_at'])
		# designs cannot be updated, so why is this even here??
		del d['updated_at']

	return page

@bp.route('/images', methods=['POST'])
@limiter.limit('1 per 15s')
def create_image():
	gen = format_created_design_results(create_image_gen())
	# Note: this is currently the only method (other than the rendering methods) which does *not* return JSON.
	# This is due to its iterative nature. I considered using JSON anyway, but very few libraries
	# support iterative JSON decoding, and we don't need anything other than an array anyway.
	return current_app.response_class(stream_with_context(gen), mimetype='text/plain')

def create_image_gen():
	try:
		image_name = request.values['image_name']
	except KeyError:
		raise InvalidImageArgument('image_name')

	author_name = request.values.get('author_name') or 'Anonymous'  # we are legion

	design_type_name = request.values.get('design_type', 'basic-design')
	try:
		if design_type_name == 'basic-design':
			yield from create_basic_image(image_name, author_name)
		else:
			yield from create_pro_image(image_name, author_name, design_type_name)
	except ACNHError as ex:
		yield ex.to_dict()

def create_pro_image(image_name, author_name, design_type_name):
	try:
		layers = {
			filename: wand.image.Image(blob=file.read()).convert('PNG')
			for filename, file
			in request.files.items()
		}
	except wand.image.WandException:
		print('In:', request.path)
		traceback.print_exc()
		raise InvalidImageError

	design = Design(
		design_type_name,
		island_name=designs_db.island_name(),
		author_name=author_name,
		design_name=image_name,
		layers=layers,
	)

	with contextlib.ExitStack() as stack:
		for img in layers.values():
			stack.enter_context(img)
		yield from designs_db.create_image(design)

def create_basic_image(image_name, author_name):
	width = height = None

	def get_int_value(name):
		v = request.values.get(name)
		if not v:
			return None
		try:
			return int(v)
		except ValueError:
			raise InvalidImageArgument(name)

	try:
		width, height = map(int, request.values['resize'].split('x'))
	except KeyError:
		width, height = map(get_int_value, ('resize-width', 'resize-height'))
	except ValueError:
		raise InvalidImageArgument('resize')

	scale = 'scale' in request.values or request.values.get('mode') == 'scale'

	try:
		img = wand.image.Image(blob=request.files['0'].read()).convert('PNG')
	except wand.image.WandException as exc:
		print('In', request.path)
		traceback.print_exc()
		raise InvalidImageError
	except KeyError:
		# pylint: disable=no-member  # external_layers is defined dynamically
		raise MissingLayerError(BasicDesign.external_layers[0])

	if width is not None and not scale:
		img.transform(resize=f'{width}x{height}')
	# do this again now because custom exception handlers don't run for generators ¯\_(ツ)_/¯
	TiledImageTooBigError.validate(img)

	design = BasicDesign(
		island_name=designs_db.island_name(),
		author_name=author_name,
		design_name=image_name,
		layers={'0': img},
	)

	with img:
		yield from designs_db.create_image(design, scale=scale)

def format_created_design_results(gen, *, header=True):
	def maybe_error(row):
		if isinstance(row, dict):
			return 'error: ' + flask.json.dumps(row)
		return None

	if header:
		# pylint: disable=stop-iteration-return  # this will never raise StopIteration
		row = next(gen)
		yield maybe_error(row) or str(row) + '\n'

	for row in gen:
		err = maybe_error(row)
		if err:
			yield err
			return

		was_quantized, design_id = row
		yield f'{int(was_quantized)},{designs_api.design_code(design_id)}\n'

@bp.route('/images')
def images():
	page = parse_keyset_params()
	rv = designs_db.images_keyset(page)
	for i, image_info in enumerate(rv):
		rv[i] = image_info = dict(rv[i])
		# images are meant to be anonymous, with the author identified solely by their chosen name
		del image_info['author_id']
		image_info['design_type'] = Design(image_info.pop('type_code')).name
	return jsonify(rv)

def parse_keyset_params():
	# before='' means last
	# after='' means first
	before = request.args.get('before')
	after = request.args.get('after')
	limit = request.args.get('limit')
	if limit is not None:
		limit = int(InvalidPaginationLimitError.validate(limit))

	if before is None and after is None:
		# default to first page
		return PageSpecifier.first()

	if before is not None and after is not None:
		raise TwoPaginationReferencesPassedError

	if not before and not after:
		reference = None
	else:
		reference = int(InvalidImageIdError.validate(before or after))

	if before is not None:
		direction = PageDirection.before
	elif after is not None:
		direction = PageDirection.after

	return PageSpecifier(direction, reference, limit)

@bp.route('/image/<image_id>')
def image(image_id):
	rv = designs_db.image(int(InvalidImageIdError.validate(image_id)))
	# images are meant to be anonymous, with the author identified solely by their chosen name
	del rv['image']['author_id']
	rv['image']['design_type'] = Design(rv['image'].pop('type_code')).name
	return rv

@bp.route('/image/<image_id>.tar')
@limiter.limit('2 per 10 seconds')
def image_archive(image_id):
	image_id = int(InvalidImageIdError.validate(image_id))
	image_info = designs_db.image(image_id)['image']
	render_internal = 'internal_layers' in request.args
	layers = {}
	cls = Design(image_info['type_code'])
	for layer, image_blob in zip(cls.external_layers, image_info['layers']):
		if image_info['pro']:
			layers[layer.name] = img = layer.as_wand()
		else:
			layers[layer.name] = img = wand.image.Image(width=image_info['width'], height=image_info['height'])

		img.import_pixels(channel_map='RGBA', data=image_blob)

	# pylint: disable=not-callable
	design = cls(layers=layers)
	if render_internal:
		requested_layers = enumerate(design.internalize())
	else:
		requested_layers = layers.items()

	gen = make_tar(image_info['image_name'], image_info['created_at'].timestamp(), requested_layers)
	encoded_filename = urllib.parse.quote(image_info['image_name'] + '.tar')
	return current_app.response_class(
		stream_with_context(gen),
		mimetype='application/x-tar',
		headers={
			'Content-Disposition': f"attachment; filename*=utf-8''{encoded_filename}",
		},
	)

@bp.route('/image/<image_id>/refresh', methods=['POST'])
def refresh_image(image_id):
	gen = stream_with_context(format_created_design_results(_refresh_image(image_id), header=False))
	return current_app.response_class(gen, mimetype='text/plain')

def _refresh_image(image_id):
	return designs_db.refresh_image(int(InvalidImageIdError.validate(image_id)))

@bp.route('/image/<image_id>', methods=['DELETE'])
def delete_image(image_id):
	image_id = int(InvalidImageIdError.validate(image_id))
	designs_db.delete_image(image_id)
	return jsonify('OK')

@bp.errorhandler(HTTPException)
def handle_exception(ex):
	"""Return JSON instead of HTML for HTTP errors."""
	# start with the correct headers and status code from the error
	response = ex.get_response()
	# replace the body with JSON
	response.data = json.dumps({
		'http_status': ex.code,
		'http_status_name': ex.name,
		'http_status_description': ex.description,
	})
	response.content_type = 'application/json'
	return response


from pymongo import MongoClient

if __name__ == '__main__':
    earliest = 7804800
    count = 0
    client = MongoClient('localhost', 27017)
    db = client.darksky
    collection = db.pastCurrentConditions
    cursor = collection.find({}).sort("time",1)
    #make a list of each document that doesn't have a time greater than 3600 from the last record
    gap_list = []
    prior_time = 7801200
    print("STARTING TIME", prior_time)
    # for document in cursor:
    #     print("beginning of for loop, count is",count)
    #     if count > 0:
    #         if document["time"] != (prior_time + 3600):
    #             print("DOC TIME (IN THE IF LOOP)",document["time"])
    #             print("prior time plus 3600",str((prior_time + 3600)))
    #             gap_list.append(document)
    #             #print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^")
    #             #print(document)
    #             #print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^")
    #     prior_time = document["time"]
    #     print("SET the prior_time by document time", prior_time)
    #     count +=1
    #     print("count is now",count)

    for document in cursor:
        if document["time"] != (prior_time + 3600):
            print("DOC TIME",document["time"])
            print("prior time plus 3600",str((prior_time + 3600)))
            gap_list.append(document)
            print(document["_id"])
        # else:
        #     print("ok",document["time"])
        prior_time = document["time"]
        #print("SET the prior_time by document time", prior_time)


import torch
import torch.nn as nn

class FeedForward(nn.Module):
    def __init__(self, d_model, d_ffn, dropout=0.1):
        super(FeedForward, self).__init__()
        self.linear1 = nn.Linear(d_model, d_ffn)
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(dropout)
        self.linear2 = nn.Linear(d_ffn, d_model)

    def forward(self, x):
        x = self.linear1(x)
        x = self.relu(x)
        x = self.dropout(x)
        x = self.linear2(x)
        return x


import aiohttp
import asyncio
import pathlib

BACKEND_URL = "http://localhost:8000"
API_URL = f"{BACKEND_URL}/api"
AUTH_URL = f"{BACKEND_URL}/auth"

NUM_REQUESTS = 20
NUM_QUESTIONS = 5
CONTENT_FILE = pathlib.Path(__file__).parent.resolve().parent.joinpath("plai/smol-reactivity.md")

# POST data for new quiz
with open(CONTENT_FILE) as f:
    content = f.read()

data = {
    "title": "Test quiz",
    "content": content,
    "count": NUM_QUESTIONS,
    "is_markdown": True,
}

# call /upload route
async def make_gpt_request(session: aiohttp.ClientSession):
    response = await session.post(f"{API_URL}/upload", json=data)
    result = await response.json()
    return result

async def main():
    async with aiohttp.ClientSession() as session:
        # authenticate
        await session.post(f"{AUTH_URL}/authenticate")

        tasks = []

        for _ in range(NUM_REQUESTS):
            tasks.append(make_gpt_request(session))

        results = await asyncio.gather(*tasks, return_exceptions=True)

    return results

if __name__ == "__main__":
    data = asyncio.run(main())

    for result in data:
        print(result)


# coding: utf-8

# In[1]:

from PIL import Image
import glob
from flask import Blueprint, request, render_template, flash, redirect, url_for
from flask import current_app as current_app

class MatchHair():
    def __inti__(self):

        print("")
        #print("init")

    def recoHairShape(self,shape,gender):

        root_path='static/img/hairShape'

        ownshape=shape["shape"]
        owngen=gender["gender"]

        if ownshape=='ang':
            images = glob.glob(root_path+'/' + owngen +'/' + ownshape + '/'+'*')
#             print(images)
#             for image_path in images:
#                 im = Image.open(image_path) # 이미지 불러오기
#                 #im.save('rename.jpeg') # 이미지 다른 이름으로 저장
#                 im.show()

            return images

        elif ownshape=='egg':
            images = glob.glob(root_path+'/' + owngen +'/' + ownshape + '/'+'*')

            return images

        elif ownshape=='long':
            images = glob.glob(root_path+'/' + owngen +'/' + ownshape + '/'+'*')

            return images

        elif ownshape=='round':
            images = glob.glob(root_path+'/' + owngen +'/' + ownshape + '/'+'*')

            return images

    #@app.route("/", methods=['POST'])
    def send_recohair_to_html(self,shape,gender):
        hairpath=self.recoHairShape(shape,gender)

        recoHairPath={}

        for i in range(0,len(hairpath)):

            recoHairPath['reco_Hair_Path'+str(i+1)]=hairpath[i]

        print(recoHairPath)

        return render_template('/index.html', hairPathHtml=recoHairPath)

#아래와같은 모양과 성별을 받은뒤 머리모양 파일의 위치를 dict으로 알려준다.
shape={'shape' : "egg"}
gen={'gender' : "Man"}
go=MatchHair()
#go.recoHairShape(shape,gen)
go.send_recohair_to_html(shape,gen)


import torch.nn as nn
import torch.nn.init as init
import torchvision.models as models
import torch

def xavier_init(tensor):
    init.xavier_uniform_(tensor)

def gaussian_init(tensor):
    init.normal_(tensor, mean=0.0, std=0.02)

def uniform_init(tensor):
    init.uniform_(tensor, a=-0.1, b=0.1)

class VGG(nn.Module):
    def __init__(self, num_classes=1000, pretrained=True, init_type='pretrained',
                 saved_weights_path=None):
        super(VGG, self).__init__()

        self.features = models.vgg16(pretrained=pretrained).features

        self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
        self.classifier = nn.Sequential(
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, num_classes),
        )

        # Initialize the weights based on the selected initialization type
        if init_type == "pretrained":
            self.reset_classifier()
            return
        elif init_type == 'xavier':
            self.apply_init(xavier_init)
            self.reset_classifier()
        elif init_type == 'gaussian':
            self.apply_init(gaussian_init)
            self.reset_classifier()
        elif init_type == 'uniform':
            self.apply_init(uniform_init)
            self.reset_classifier()
        elif init_type == 'finetuned':
            if saved_weights_path is not None:
                self.load_saved_weights(saved_weights_path)
            else:
                raise ValueError('No path given.')

    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

    def load_pretrained_weights(self):
        vgg16 = models.vgg16(pretrained=True)
        self.features.load_state_dict(vgg16.features.state_dict())

    def load_saved_weights(self, saved_weights_path):
        saved_weights = torch.load(saved_weights_path, map_location='cuda:1')
        self.load_state_dict(saved_weights["state_dict"])

    def apply_init(self, init_func):
        for m in self.modules():
            if isinstance(m, nn.Conv2d) or isinstance(m, nn.Linear):
                init_func(m.weight.data)
                if m.bias is not None:
                    m.bias.data.zero_()

    def reset_classifier(self):
        for m in self.classifier.modules():
            if isinstance(m, nn.Linear):
                init.kaiming_uniform_(m.weight, mode='fan_in', nonlinearity='relu')
                if m.bias is not None:
                    m.bias.data.zero_()


from clases.preguntas import Pregunta
from clases.respuestas import Respuesta
import sqlite3

contadorPreguntas = 0
puntos = 0

#CREAR PREGUNTAS
p1 = Pregunta(1,"En qué año fue el descubrimiento de América?",1,1)
p2 = Pregunta(2,"Cuál es el país con mayor población del mundo?",1,1)
p3 = Pregunta(3,"Cuál era el nombre del dios del Sol en el Antiguo Egipto?",1,1)
p4 = Pregunta(4,"Quién fue el primer presidente de Estados Unidos?",1,1)
p5 = Pregunta(5,"Quién es el autor de La Odisea?",1,1)

p6 = Pregunta(6,"Cómo se llama el estadio de fútbol del Real Madrid?",2,2)
p7 = Pregunta(7,"En qué deporte destaca Tiger Woods?",2,2)
p8 = Pregunta(8,"Quién ganó el mundial de de fútbol del año 2014?",2,2)
p9 = Pregunta(9,"De que país es el futbolista Radamel Falcao Garcia?",2,2)
p10 = Pregunta(10,"En qué equipo jugó Francesco Totti durante toda su carrera?",2,2)

p11 = Pregunta(11,"Cuál es el río más largo del mundo?",3,3)
p12 = Pregunta(12,"Cuál es el océano más grande del mundo?",3,3)
p13 = Pregunta(13,"Cuántos lados tiene un heptágono?",3,3)
p14 = Pregunta(14,"Cuál es el planeta más grande del Sistema Solar?",3,3)
p15 = Pregunta(15,"Cuántos huesos tiene el cuerpo humano?",3,3)

p16 = Pregunta(16,"Cuántos corazones tiene un gusano de tierra?",4,4)
p17 = Pregunta(17,"Cuántos días tiene un año bisiesto??",4,4)
p18 = Pregunta(18,"Cuántas patas tiene una araña?",4,4)
p19 = Pregunta(19,"Cuántos corazones tiene un pulpo?",4,4)
p20 = Pregunta(20,"Cuanto es 10+80 ?",4,4)

p21 = Pregunta(21,"Cuántas horas tiene un día ?",5,5)
p22 = Pregunta(22,"Cuantos minutos tiene una hora ?",5,5)
p23 = Pregunta(23,"Cuantos departamentos tiene Colombia ?",5,5)
p24 = Pregunta(24,"Cuantas son las ramas del poder público en Colombia ?",5,5)
p25 = Pregunta(25,"Cual es la capital de Colombia ?",5,5)

#crear respuestas

r1 = Respuesta(1,"(1492)",1,True)
r2 = Respuesta(2,"(1342)",1,False)
r3 = Respuesta(3,"(1429)",1,False)
r4 = Respuesta(4,"(1352)",1,False)

r5 = Respuesta(5,"(Perú)",2,False)
r6 = Respuesta(6,"(Colombia)",2,False)
r7 = Respuesta(7,"(China)",2,True)
r8 = Respuesta(8,"(Uruguay)",2,False)

r9 = Respuesta(9,"(Odín)",3,False)
r10 = Respuesta(10,"(Ra)",3,True)
r11 = Respuesta(11,"(platón)",3,False)
r12 = Respuesta(12,"(David)",3,False)

r13 = Respuesta(13,"(Álvaro Uribe)",4,False)
r14 = Respuesta(14,"(George Washington)",4,True)
r15 = Respuesta(15,"(Simón Bolívar)",4,False)
r16 = Respuesta(16,"(Elkin Patarroyo)",4,False)

r17 = Respuesta(17,"(benjamín)",5,False)
r18 = Respuesta(18,"(Simón)",5,False)
r19 = Respuesta(19,"(Alberto)",5,False)
r20 = Respuesta(20,"(Homero)",5,True)

r21 = Respuesta(21,"(Santiago Bernabéu) ",6,True)
r22 = Respuesta(22,"(Wanda Metropolitano)",6,False)
r23 = Respuesta(23,"(Camp Nou)",6,False)
r24 = Respuesta(24,"(San Mames)",6,False)

r25 = Respuesta(25,"((Futbol))",7,False)
r26 = Respuesta(26,"((Natación))",7,False)
r27 = Respuesta(27,"(vóleibol)",7,False)
r28 = Respuesta(28,"(Golf)",7,True)

r29 = Respuesta(29,"(Perú)",8,False)
r30 = Respuesta(30,"(China)",8,False)
r31 = Respuesta(31,"(España)",8,False)
r32 = Respuesta(32,"(Alemania)",8,True)

r33 = Respuesta(33,"(Colombia)",9,True)
r34 = Respuesta(34,"(Chile)",9,False)
r35 = Respuesta(35,"(Ecuador)",9,False)
r36 = Respuesta(36,"(Alemania)",9,False)

r37 = Respuesta(37,"(AC Milán)",10,False)
r38 = Respuesta(38,"(Juventus FC)",10,False)
r39 = Respuesta(39,"(S.S Lazio)",10,False)
r40 = Respuesta(40,"(AS Roma)",10,True)

r41 = Respuesta(41,"(Nilo)",11,False)
r42 = Respuesta(42,"(Amazonas)",11,True)
r43 = Respuesta(43,"(Congo)",11,False)
r44 = Respuesta(44,"(Misisipi)",11,False)

r45 = Respuesta(45,"(Atlántico)",12,False)
r46 = Respuesta(46,"(Indico)",12,False)
r47 = Respuesta(47,"(océano Pacífico)",12,True)
r48 = Respuesta(48,"(Ártico)",12,False)

r49 = Respuesta(49,"(Siete lados) ",13,True)
r50 = Respuesta(50,"(Seis lados)",13,False)
r51 = Respuesta(51,"(Cinco lados)",13,False)
r52 = Respuesta(52,"(Diez lados)",13,False)

r53 = Respuesta(53,"(Plutón)",14,False)
r54 = Respuesta(54,"(Júpiter)",14,True)
r55 = Respuesta(55,"(Urano)",14,False)
r56 = Respuesta(56,"(Neptuno)",14,False)

r57= Respuesta(57,"(206)",15,True)
r58= Respuesta(58,"(300)",15,False)
r59= Respuesta(59,"(400)",15,False)
r60= Respuesta(60,"(150)",15,False)

r61= Respuesta(61,"(Dos)",16,False)
r62= Respuesta(62,"(Quince)",16,False)
r63= Respuesta(63,"(Cinco)",16,True)
r64= Respuesta(64,"(Diez)",16,False)

r65= Respuesta(65,"(380 días)",17,False)
r66= Respuesta(66,"(300 días)",17,False)
r67= Respuesta(67,"(400 días)",17,False)
r68= Respuesta(68,"(366 días)",17,True)

r69= Respuesta(69,"(Ocho)",18,True)
r70= Respuesta(70,"(Dos)",18,False)
r71= Respuesta(71,"(Diez)",18,False)
r72= Respuesta(72,"(Cinco)",18,False)

r73= Respuesta(73,"(Un corazón)",19,False)
r74= Respuesta(74,"(Dos corazones)",19,False)
r75= Respuesta(75,"(Tres corazones)",19,True)
r76= Respuesta(76,"(Cinco corazones)",19,False)

r77= Respuesta(77,"(70)",20,False)
r78= Respuesta(78,"(90)",20,True)
r79= Respuesta(79,"(100)",20,False)
r80= Respuesta(80,"(60)",20,False)

r81= Respuesta(81,"(20 Horas)",21,False)
r82= Respuesta(82,"(15 Horas)",21,False)
r83= Respuesta(83,"(12 Horas)",21,False)
r84= Respuesta(84,"(24 Horas)",21,True)

r85= Respuesta(85,"(50 minutos)",22,False)
r86= Respuesta(86,"(40 minutos)",22,False)
r87= Respuesta(87,"(60 minutos",22,True)
r88= Respuesta(88,"(24 Minutos)",22,False)

r89= Respuesta(89,"(20)",23,False)
r90= Respuesta(90,"(32)",23,True)
r91= Respuesta(91,"(40)",23,False)
r92= Respuesta(92,"(24)",23,False)

r93= Respuesta(93,"(Tres)",24,True)
r94= Respuesta(94,"(Cuatro)",24,False)
r95= Respuesta(95,"(Cinco)",24,False)
r96= Respuesta(96,"(Diez)",24,False)

r97= Respuesta(97,"(Pereira)",25,False)
r98= Respuesta(98,"(Cali)",25,False)
r99= Respuesta(99,"(Bogota)",25,True)
r100= Respuesta(100,"(Barranquilla)",25,False)

#lista de preguntas
preguntas = [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25]
# lista de respuestas
respuestas = [r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,
    r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31,r32,r33,r34,r35,r36,r37,r38,r39,r40,
    r41,r42,r43,r44,r45,r46,r47,r48,r49,r50,r51,r52,r53,r54,r55,r56,r57,r58,r59,r60,r61,r62,r63,
    r64,r65,r66,r67,r68,r69,r70,r71,r72,r73,r74,r75,r76,r77,r78,r79,r80,r81,r82,r83,r84,r85,r86,r87,r88,r89,r90,
    r91,r92,r93,r94,r95,r96,r97,r98,r99,r100]

print("Jugar")

# datos del jugador
nombres = input("registrar nombres:")
apellidos = input("registrar apellidos:")

#funcion  retorna las respuestas de la pregunta
def dimeRespuestas(preguntaId):
    lista = []
    for r in respuestas:
        if r.dime_preguntaId() == preguntaId:
            lista.append(r)
    return lista

# Se crea en la raiz, la base de datos "historico_jugador" al finalizar la ejecucion del programa.
def guardar(nom,apell,puntaje):
    conexion = sqlite3.connect("historico_jugador")
    cursor = conexion.cursor()
    sql = "CREATE TABLE IF NOT EXISTS HISTORICO (NOMBRE VARCHAR(50),APELLIDO VARCHAR(50),PUNTAJE INTEGER)"
    cursor.execute(sql)
    insert = "INSERT INTO HISTORICO VALUES (?,?,?)"
    jugador = [(nom,apell,puntaje)]
    cursor.executemany(insert,jugador)
    conexion.commit()
    cursor.close()

for i in preguntas:
    contadorPreguntas +=1
    print("Pregunta ", contadorPreguntas)
    print("Categoria ", i.dime_categoria())
    print(i.dime_descripcion())
    print("RESPUESTAS")
    #buscar pregunta
    respuestaOpciones = dimeRespuestas(i.dime_id())
    print("A:",respuestaOpciones[0].dime_opcion())
    print("B:",respuestaOpciones[1].dime_opcion())
    print("C:",respuestaOpciones[2].dime_opcion())
    print("D:",respuestaOpciones[3].dime_opcion())
    A = respuestaOpciones[0].dime_isTrue()
    B = respuestaOpciones[1].dime_isTrue()
    C = respuestaOpciones[2].dime_isTrue()
    D = respuestaOpciones[3].dime_isTrue()
    opcionSeleccionada =  input("ESCRIBA LA RESPUESTA: (A,B,C,D):")
    if contadorPreguntas <= 5:
        if opcionSeleccionada.upper() == "A":
            if A:
                print("Correcto!")
                puntos += 1
                print("Puntos:",puntos)

            else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "B":
             if B:
                print("Correcto!")
                puntos += 1
                print("Puntos:",puntos)

             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "C":
             if C:
                print("Correcto!")
                puntos += 1
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "D":
             if D:
                print("Correcto!")
                puntos += 1
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
    elif contadorPreguntas > 5 and contadorPreguntas <= 10:
        if opcionSeleccionada.upper() == "A":
            if A:
                print("Correcto!")
                puntos += 2
                print("Puntos:",puntos)

            else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "B":
             if B:
                print("Correcto!")
                puntos += 2
                print("Puntos:",puntos)

             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "C":
             if C:
                print("Correcto!")
                puntos += 2
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "D":
             if D:
                print("Correcto!")
                puntos += 2
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
    elif contadorPreguntas > 10 and contadorPreguntas <= 15:
        if opcionSeleccionada.upper() == "A":
            if A:
                print("Correcto!")
                puntos += 3
                print("Puntos:",puntos)
            else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "B":
             if B:
                print("Correcto!")
                puntos += 3
                print("Puntos:",puntos)

             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "C":
             if C:
                print("Correcto!")
                puntos += 3
                print("Puntos:",puntos)

             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "D":
             if D:
                print("Correcto!")
                puntos += 3
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
    elif contadorPreguntas > 15 and contadorPreguntas <= 20:
        if opcionSeleccionada.upper() == "A":
            if A:
                print("Correcto!")
                puntos += 4
                print("Puntos:",puntos)

            else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "B":
             if B:
                print("Correcto!")
                puntos += 4
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "C":
             if C:
                print("Correcto!")
                puntos += 4
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "D":
             if D:
                print("Correcto!")
                puntos += 4
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
    elif contadorPreguntas > 20 and contadorPreguntas <= 25:
        if opcionSeleccionada.upper() == "A":
            if A:
                print("Correcto!")
                puntos += 5
                print("Puntos:",puntos)
            else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "B":
             if B:
                print("Correcto!")
                puntos += 5
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "C":
             if C:
                print("Correcto!")
                puntos += 5
                print("Puntos:",puntos)
             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break
        elif opcionSeleccionada.upper() == "D":
             if D:
                print("Correcto!")
                puntos += 5
                print("Puntos:",puntos)

             else:
                puntos = 0
                print('inCorrecta')
                guardar(nombres,apellidos,puntos)
                break

    if contadorPreguntas == 25:
        print('FELICIDADES TERMINASTE EL JUEGO')
        print("PUNTAJE TOTAL OBTENIDO:", puntos)
        guardar(nombres,apellidos,puntos)
        break
    else:
        respuesta = input('Desea seguir en el juego?: ("SI,NO"):')
        if respuesta.upper() == "NO":
            print('JUEGO TERMINADO')
            print("PUNTAJE OBTENIDO:",puntos)
            guardar(nombres,apellidos,puntos)
            break


''' NeuralNetPurePython.py '''

import numpy as np
import matplotlib.pyplot as plt

def initialize(p, w_sig = 1):
    W, b = [[]]*len(p), [[]]*len(p)

    for l in range(1,len(p)):
       W[l]= w_sig * np.random.randn(p[l], p[l-1])
       b[l]= w_sig * np.random.randn(p[l], 1)
    return W,b

def list2vec(W,b):
    # converts list of weight matrices and bias vectors into one column vector
    b_stack = np.vstack([b[i] for i in range(1,len(b))] )
    W_stack = np.vstack(W[i].flatten().reshape(-1,1) for i in range(1,len(W)))
    vec = np.vstack([b_stack, W_stack])
    return vec
#%%
def vec2list(vec, p):
    # converts vector to weight matrices and bias vectors
    W, b = [[]]*len(p),[[]]*len(p)
    p_count = 0

    for l in range(1,len(p)): # construct bias vectors
        b[l] = vec[p_count:(p_count+p[l])].reshape(-1,1)
        p_count = p_count + p[l]

    for l in range(1,len(p)): # construct weight matrices
        W[l] = vec[p_count:(p_count + p[l]*p[l-1])].reshape((p[l], p[l-1]))
        p_count = p_count + (p[l]*p[l-1])

    return W, b
#%%
def RELU(z,l):
    # RELU activation function: value and derivative
    if l == L: return z, np.ones_like(z) # if last layer return identity
    else:
        val = np.maximum(0,z) # RELU function element-wise
        J = np.array(z>0, dtype = float) # derivative of RELU element-wise
        return val, J

#%%
def loss_fn(y,g):
    return (g - y)**2, 2 * (g - y)

#%%
def feedforward(x,W,b):
    a, z, gr_S = [0]*(L+1), [0]*(L+1), [0]*(L+1)

    a[0] = x.reshape(-1,1)
    for l in range(1,L+1):
        z[l] = W[l] @ a[l-1] + b[l] # affine transformation
        a[l], gr_S[l] = S(z[l],l) # activation function
    return a, z, gr_S

#%%
def backward(W,b,X,y):
    n =len(y)
    delta = [0]*(L+1)
    dC_db, dC_dW = [0]*(L+1), [0]*(L+1)
    loss=0

    for i in range(n): # loop over training examples
        a, z, gr_S = feedforward(X[i,:].T, W, b)
        cost, gr_C = loss_fn(y[i], a[L]) # cost i and gradient wrt g
        loss += cost/n

        delta[L] = gr_S[L] @ gr_C

        for l in range(L,0,-1): # l = L,...,1
            dCi_dbl = delta[l]
            dCi_dWl = delta[l] @  a[l-1].T

            # ---- sum up over samples ----
            dC_db[l] = dC_db[l] + dCi_dbl/n
            dC_dW[l] = dC_dW[l] + dCi_dWl/n
            # -----------------------------

            delta[l-1] =  gr_S[l-1] * W[l].T @ delta[l]

    return dC_dW, dC_db, loss

#%%
# import data
data = np.genfromtxt('polyreg.csv',delimiter=',')
X = data[:,0].reshape(-1,1)
y = data[:,1].reshape(-1,1)

    # Network setup
p = [X.shape[1],20,20,1] # size of layers
L = len(p)-1             # number of layers
W,b = initialize(p) # initialize weight matrices and bias vectors
S = RELU

batch_size = 20
lr = 0.005
beta = list2vec(W,b)
loss_arr = []
n = len(X)
num_epochs = 10000
print("epoch | batch loss")
print("----------------------------")
for epoch in range(1,num_epochs+1):
    batch_idx = np.random.choice(n,batch_size)
    batch_X = X[batch_idx].reshape(-1,1)
    batch_y=y[batch_idx].reshape(-1,1)
    dC_dW, dC_db, loss = backward(W,b,batch_X,batch_y)
    d_beta = list2vec(dC_dW,dC_db)
    loss_arr.append(loss.flatten()[0])
    if(epoch==1 or np.mod(epoch,1000)==0):
        print(epoch,": ",loss.flatten()[0])
    beta = beta - lr*d_beta
    W,b = vec2list(beta,p)

    # calculate the loss of the entire training set
dC_dW, dC_db, loss = backward(W,b,X,y)
print("entire training set loss = ",loss.flatten()[0])

#%%
xx = np.arange(0,1,0.01)
y_preds = np.zeros_like(xx)

for i in range(len(xx)):
    a, _, _ = feedforward(xx[i],W,b)
    y_preds[i],  = a[L]

plt.plot(np.array(xx), y_preds, 'b',label = 'fit')
plt.plot(X,y, 'r.', markersize = 4,label = 'y')

plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.show()

plt.plot(np.array(loss_arr), 'b')
plt.xlabel('iteration')
plt.ylabel('Training Loss')
plt.show()

#%% latex plots
plt.rc('text', usetex=True)
plt.rc('font', family='serif',size=20)
plt.tight_layout()
plt.clf()
xx = np.arange(0,1,0.01)
y_preds = np.zeros_like(xx)

for i in range(len(xx)):
    a, _, _ = feedforward(xx[i],W,b)
    y_preds[i],  = a[L]

plt.plot(np.array(xx), y_preds, 'b',label = 'fit')
plt.plot(X,y, 'r.', markersize = 4, label='$y$')

    #beta = np.array([[10, -140, 400, -250]]).T
    #yy = np.polyval(np.flip(beta), xx)
    #plt.plot(xx, yy, 'k',  alpha = 0.4, label = 'Ground truth')

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

plt.legend()
#plt.xlabel('$x$',fontsize=30)
#plt.ylabel('$y$',fontsize=30)
plt.xlabel('input $u$',fontsize=20)
plt.ylabel('output $y$',fontsize=20)
plt.savefig("nnpolyreg1.pdf",bbox_inches = "tight")
plt.show()

plt.plot(np.array(loss_arr), 'b', label = 'Batch Loss')
plt.xlabel(r'{iteration}')
plt.ylabel(r'{Batch Loss}')

plt.savefig("nnpolyreg2.pdf",bbox_inches = "tight")

plt.show()


"""
Transaction file handles everything related to transaction.

# Name1: Nash Baek (nash4comp@gmail.com)
# Student number1: A01243888

# Name2: Taylor Ji (taylor.ji719@gmail.com)
# Student number2: A01304056

UML diagram: https://app.diagrams.net/#G1DUxHF4SH4QveN8GbqGaHewuu07bC5lDG
"""

import datetime
from budget import BudgetTypeEnum

class Transaction:
    """
    Transaction class creates transactions,
    """
    transactions = []

    def __init__(self, dollar_amount, shop_name, budget_type):
        """
        initialize transaction with dollar amount you spent, and the store name
        :param dollar_amount: positive float
        :param shop_name: string
        :param budget_type: string
        """
        self._raw_temp_time = (datetime.datetime.now())
        self._time_stamp = self._raw_temp_time.strftime("%c")
        self._dollar_amount = dollar_amount
        self._shop_name = shop_name
        self._budget_type = budget_type

    def add_transaction(self):
        """
        This method returns a transaction that will be saved under user class.
        For lab 4, I create a transaction list that stores transactions.
        :return: Transaction
        """
        user_input_store_name = input("Enter the place you went: ")
        self.set_shop_name(user_input_store_name)
        user_input_dollar_amount = float(input("Enter the amount you spent: "))
        self.set_dollar_amount(user_input_dollar_amount)
        print("Please select one budget type")
        print("1. Game and Entertainment")
        print("2. Clothing and Accessories")
        print("3. Eating Out")
        print("4. Miscellaneous")
        user_budget_type = int(input("Enter the budget type number: "))
        if user_budget_type == 1:
            self.set_budget_type("Game and Entertainment")
        elif user_budget_type == 2:
            self.set_budget_type("Clothing and Accessories")
        elif user_budget_type == 3:
            self.set_budget_type("Eat out")
        elif user_budget_type == 4:
            self.set_budget_type("Miscellaneous")
        transaction_to_add = Transaction(self.get_dollar_amount(), self.get_shop_name(), self.get_budget_type())
        Transaction.add_transactions_to_list(transaction_to_add)
        return transaction_to_add

    @classmethod
    def add_transactions_to_list(cls, transaction):
        """
        Save transactions to the transaction list.
        Used for lab4, transactions will be stored into user's transaction list.
        :param transaction
        """
        cls.transactions.append(transaction)

    def get_time(self):
        """
        Getter for dollar amount.
        :return: self._dollar_amount
        """
        return self._time_stamp

    def get_dollar_amount(self):
        """
        Getter for dollar amount.
        :return: self._dollar_amount
        """
        return self._dollar_amount

    def set_dollar_amount(self, user_input_dollar_amount):
        """
        Setter for dollar_amount.
        :param user_input_dollar_amount
        """
        self._dollar_amount = user_input_dollar_amount

    def get_shop_name(self):
        """
        Getter for shop_name.
        :return: self._shop_name
        """
        return self._shop_name

    def get_budget_type(self):
        """
        Getter for dollar amount.
        :return: self._dollar_amount
        """
        return self._budget_type

    def get_budget_type_for_key(self):
        """
        Convert budget type string value to Enum class name
        Return String
        """
        type_to_change = self.get_budget_type()
        key = None
        if type_to_change == BudgetTypeEnum.GE.value:
            key = BudgetTypeEnum.GE.name
        elif type_to_change == BudgetTypeEnum.CA.value:
            key = BudgetTypeEnum.CA.name
        elif type_to_change == BudgetTypeEnum.EO.value:
            key = BudgetTypeEnum.EO.name
        elif type_to_change == BudgetTypeEnum.MIS.value:
            key = BudgetTypeEnum.MIS.name
        return key

    def set_shop_name(self, user_input_shop_name):
        """
        Setter for shop_name
        :param user_input_shop_name
        """
        self._shop_name = user_input_shop_name

    def set_budget_type(self, user_input_budget_type):
        """
        Setter for shop_name
        :param user_input_budget_type
        """
        self._budget_type = user_input_budget_type

    def __str__(self):
        """
        String representation of Transaction class
        :return: string to print
        """
        to_str = f"Budget type is {self.get_budget_type()}, Date is {self.get_time()}, " \
                 f"Amount spent is ${self.get_dollar_amount()}, " \
                 f"Store name is {self.get_shop_name()}"
        return to_str