# The network design is based on Tinghui Zhou & Clement Godard's works:
# https://github.com/tinghuiz/SfMLearner/blob/master/nets.py
# https://github.com/mrharicot/monodepth/blob/master/monodepth_model.py
from __future__ import division
import tensorflow as tf
import tensorflow.contrib.slim as slim
import numpy as np

# Range of disparity/inverse depth values
DISP_SCALING_RESNET50 = 5
DISP_SCALING_VGG = 10
FLOW_SCALING = 0.1

def disp_net(opt, dispnet_inputs):
    is_training = opt.mode == 'train_rigid'
    if opt.dispnet_encoder == 'vgg':
        return build_vgg(dispnet_inputs, get_disp_vgg, is_training, 'depth_net')
    else:
        return build_resnet50(dispnet_inputs, get_disp_resnet50, is_training, 'depth_net')

def flow_net(opt, flownet_inputs):
    is_training = opt.mode == 'train_flow'
    return build_resnet50(flownet_inputs, get_flow, is_training, 'flow_net')

def pose_net(opt, posenet_inputs):
    is_training = opt.mode == 'train_rigid'
    batch_norm_params = {'is_training': is_training}
    with tf.variable_scope('pose_net') as sc:
        with slim.arg_scope([slim.conv2d],
                            normalizer_fn=slim.batch_norm,
                            normalizer_params=batch_norm_params,
                            weights_regularizer=slim.l2_regularizer(0.0001),
                            activation_fn=tf.nn.relu):
            conv1  = slim.conv2d(posenet_inputs, 16,  7, 2)
            conv2  = slim.conv2d(conv1, 32,  5, 2)
            conv3  = slim.conv2d(conv2, 64,  3, 2)
            conv4  = slim.conv2d(conv3, 128, 3, 2)
            conv5  = slim.conv2d(conv4, 256, 3, 2)
            conv6  = slim.conv2d(conv5, 256, 3, 2)
            conv7  = slim.conv2d(conv6, 256, 3, 2)
            pose_pred = slim.conv2d(conv7, 6*opt.num_source, 1, 1,
                                    normalizer_fn=None, activation_fn=None)
            pose_avg = tf.reduce_mean(pose_pred, [1, 2])
            pose_final = 0.01 * tf.reshape(pose_avg, [-1, opt.num_source, 6])
            return pose_final

def build_vgg(inputs, get_pred, is_training, var_scope):
    batch_norm_params = {'is_training': is_training}
    H = inputs.get_shape()[1].value
    W = inputs.get_shape()[2].value
    with tf.variable_scope(var_scope) as sc:
        with slim.arg_scope([slim.conv2d, slim.conv2d_transpose],
                            normalizer_fn=slim.batch_norm,
                            normalizer_params=batch_norm_params,
                            weights_regularizer=slim.l2_regularizer(0.0001),
                            activation_fn=tf.nn.relu):
            # ENCODING
            conv1  = slim.conv2d(inputs, 32,  7, 2)
            conv1b = slim.conv2d(conv1,  32,  7, 1)
            conv2  = slim.conv2d(conv1b, 64,  5, 2)
            conv2b = slim.conv2d(conv2,  64,  5, 1)
            conv3  = slim.conv2d(conv2b, 128, 3, 2)
            conv3b = slim.conv2d(conv3,  128, 3, 1)
            conv4  = slim.conv2d(conv3b, 256, 3, 2)
            conv4b = slim.conv2d(conv4,  256, 3, 1)
            conv5  = slim.conv2d(conv4b, 512, 3, 2)
            conv5b = slim.conv2d(conv5,  512, 3, 1)
            conv6  = slim.conv2d(conv5b, 512, 3, 2)
            conv6b = slim.conv2d(conv6,  512, 3, 1)
            conv7  = slim.conv2d(conv6b, 512, 3, 2)
            conv7b = slim.conv2d(conv7,  512, 3, 1)

            # DECODING
            upconv7 = upconv(conv7b, 512, 3, 2)
            # There might be dimension mismatch due to uneven down/up-sampling
            upconv7 = resize_like(upconv7, conv6b)
            i7_in  = tf.concat([upconv7, conv6b], axis=3)
            iconv7  = slim.conv2d(i7_in, 512, 3, 1)

            upconv6 = upconv(iconv7, 512, 3, 2)
            upconv6 = resize_like(upconv6, conv5b)
            i6_in  = tf.concat([upconv6, conv5b], axis=3)
            iconv6  = slim.conv2d(i6_in, 512, 3, 1)

            upconv5 = upconv(iconv6, 256, 3, 2)
            upconv5 = resize_like(upconv5, conv4b)
            i5_in  = tf.concat([upconv5, conv4b], axis=3)
            iconv5  = slim.conv2d(i5_in, 256, 3, 1)

            upconv4 = upconv(iconv5, 128, 3, 2)
            i4_in  = tf.concat([upconv4, conv3b], axis=3)
            iconv4  = slim.conv2d(i4_in, 128, 3, 1)
            pred4  = get_pred(iconv4)
            pred4_up = tf.image.resize_bilinear(pred4, [np.int(H/4), np.int(W/4)])

            upconv3 = upconv(iconv4, 64,  3, 2)
            i3_in  = tf.concat([upconv3, conv2b, pred4_up], axis=3)
            iconv3  = slim.conv2d(i3_in, 64,  3, 1)
            pred3  = get_pred(iconv3)
            pred3_up = tf.image.resize_bilinear(pred3, [np.int(H/2), np.int(W/2)])

            upconv2 = upconv(iconv3, 32,  3, 2)
            i2_in  = tf.concat([upconv2, conv1b, pred3_up], axis=3)
            iconv2  = slim.conv2d(i2_in, 32,  3, 1)
            pred2  = get_pred(iconv2)
            pred2_up = tf.image.resize_bilinear(pred2, [H, W])

            upconv1 = upconv(iconv2, 16,  3, 2)
            i1_in  = tf.concat([upconv1, pred2_up], axis=3)
            iconv1  = slim.conv2d(i1_in, 16,  3, 1)
            pred1  = get_pred(iconv1)

            return [pred1, pred2, pred3, pred4]

def build_resnet50(inputs, get_pred, is_training, var_scope):
    batch_norm_params = {'is_training': is_training}
    with tf.variable_scope(var_scope) as sc:
        with slim.arg_scope([slim.conv2d, slim.conv2d_transpose],
                            normalizer_fn=slim.batch_norm,
                            normalizer_params=batch_norm_params,
                            weights_regularizer=slim.l2_regularizer(0.0001),
                            activation_fn=tf.nn.relu):
            conv1 = conv(inputs, 64, 7, 2) # H/2  -   64D
            pool1 = maxpool(conv1,           3) # H/4  -   64D
            conv2 = resblock(pool1,      64, 3) # H/8  -  256D
            conv3 = resblock(conv2,     128, 4) # H/16 -  512D
            conv4 = resblock(conv3,     256, 6) # H/32 - 1024D
            conv5 = resblock(conv4,     512, 3) # H/64 - 2048D

            skip1 = conv1
            skip2 = pool1
            skip3 = conv2
            skip4 = conv3
            skip5 = conv4

            # DECODING
            upconv6 = upconv(conv5,   512, 3, 2) #H/32
            upconv6 = resize_like(upconv6, skip5)
            concat6 = tf.concat([upconv6, skip5], 3)
            iconv6  = conv(concat6,   512, 3, 1)

            upconv5 = upconv(iconv6, 256, 3, 2) #H/16
            upconv5 = resize_like(upconv5, skip4)
            concat5 = tf.concat([upconv5, skip4], 3)
            iconv5  = conv(concat5,   256, 3, 1)

            upconv4 = upconv(iconv5,  128, 3, 2) #H/8
            upconv4 = resize_like(upconv4, skip3)
            concat4 = tf.concat([upconv4, skip3], 3)
            iconv4  = conv(concat4,   128, 3, 1)
            pred4 = get_pred(iconv4)
            upred4  = upsample_nn(pred4, 2)

            upconv3 = upconv(iconv4,   64, 3, 2) #H/4
            concat3 = tf.concat([upconv3, skip2, upred4], 3)
            iconv3  = conv(concat3,    64, 3, 1)
            pred3 = get_pred(iconv3)
            upred3  = upsample_nn(pred3, 2)

            upconv2 = upconv(iconv3,   32, 3, 2) #H/2
            concat2 = tf.concat([upconv2, skip1, upred3], 3)
            iconv2  = conv(concat2,    32, 3, 1)
            pred2 = get_pred(iconv2)
            upred2  = upsample_nn(pred2, 2)

            upconv1 = upconv(iconv2,  16, 3, 2) #H
            concat1 = tf.concat([upconv1, upred2], 3)
            iconv1  = conv(concat1,   16, 3, 1)
            pred1 = get_pred(iconv1)

            return [pred1, pred2, pred3, pred4]

def conv(x, num_out_layers, kernel_size, stride, activation_fn=tf.nn.relu, normalizer_fn=slim.batch_norm):
    p = np.floor((kernel_size - 1) / 2).astype(np.int32)
    p_x = tf.pad(x, [[0, 0], [p, p], [p, p], [0, 0]])
    return slim.conv2d(p_x, num_out_layers, kernel_size, stride, 'VALID', activation_fn=activation_fn, normalizer_fn=normalizer_fn)

def maxpool(x, kernel_size):
    p = np.floor((kernel_size - 1) / 2).astype(np.int32)
    p_x = tf.pad(x, [[0, 0], [p, p], [p, p], [0, 0]])
    return slim.max_pool2d(p_x, kernel_size)

def get_disp_vgg(x):
    disp = DISP_SCALING_VGG * slim.conv2d(x, 1, 3, 1, activation_fn=tf.nn.sigmoid, normalizer_fn=None) + 0.01
    return disp

def get_disp_resnet50(x):
    disp = DISP_SCALING_RESNET50 * conv(x, 1, 3, 1, activation_fn=tf.nn.sigmoid, normalizer_fn=None) + 0.01
    return disp

def get_flow(x):
    # Output flow value is normalized by image height/width
    flow = FLOW_SCALING * slim.conv2d(x, 2, 3, 1, activation_fn=None, normalizer_fn=None)
    return flow

def resize_like(inputs, ref):
    iH, iW = inputs.get_shape()[1], inputs.get_shape()[2]
    rH, rW = ref.get_shape()[1], ref.get_shape()[2]
    if iH == rH and iW == rW:
        return inputs
    return tf.image.resize_nearest_neighbor(inputs, [rH.value, rW.value])

def upsample_nn(x, ratio):
    h = x.get_shape()[1].value
    w = x.get_shape()[2].value
    return tf.image.resize_nearest_neighbor(x, [h * ratio, w * ratio])

def upconv(x, num_out_layers, kernel_size, scale):
    upsample = upsample_nn(x, scale)
    cnv = conv(upsample, num_out_layers, kernel_size, 1)
    return cnv

def resconv(x, num_layers, stride):
    # Actually here exists a bug: tf.shape(x)[3] != num_layers is always true,
    # but we preserve it here for consistency with Godard's implementation.
    do_proj = tf.shape(x)[3] != num_layers or stride == 2
    shortcut = []
    conv1 = conv(x,         num_layers, 1, 1)
    conv2 = conv(conv1,     num_layers, 3, stride)
    conv3 = conv(conv2, 4 * num_layers, 1, 1, None)
    if do_proj:
        shortcut = conv(x, 4 * num_layers, 1, stride, None)
    else:
        shortcut = x
    return tf.nn.relu(conv3 + shortcut)

def resblock(x, num_layers, num_blocks):
    out = x
    for i in range(num_blocks - 1):
        out = resconv(out, num_layers, 1)
    out = resconv(out, num_layers, 2)
    return out

# def resconv(x, num_layers, stride):
#     shortcut = []
#     conv1 = conv(x,         num_layers, 1, 1)
#     conv2 = conv(conv1,     num_layers, 3, stride)
#     conv3 = conv(conv2, 4 * num_layers, 1, 1, None)
#     if stride == 2:
#         shortcut = conv(x, 4 * num_layers, 1, stride, None)
#     else:
#         shortcut = x
#     return tf.nn.relu(conv3 + shortcut)

# def resblock(x, num_layers, num_blocks):
#     out = x
#     out = resconv(out, num_layers, 2)
#     for i in range(num_blocks - 1):
#         out = resconv(out, num_layers, 1)
#     return out


import copy
from typing import List

class Solution:

    def rec(self, index:int, tempList:List[int], nums:List[int], output:List[List[int]]):
        prev = -100

        for i in range(index, len(nums)) :
            if prev == nums[i] :
                continue
            prev = nums[i]

            midList = copy.deepcopy(tempList)
            midList.append(nums[i])
            output.append(midList)
            self.rec(i+1, midList, nums, output)
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        output = [[]]
        nums.sort()

        self.rec(0,[], nums, output)
        return output


import torch
from cross_attn.main import MultiModalCrossAttention

# Test the MultiModalCrossAttention module
dim = 512  # For example
num_heads = 8

cross_attn = MultiModalCrossAttention(dim, num_heads)

Hllm_sample = torch.randn(32, dim, dim)  # Batch size = 32, Sequence length = 10
Himg_sample = torch.randn(32, dim, dim)

output = cross_attn(Hllm_sample, Himg_sample)
print(output)

print(output.shape)  # Expected: [32, 10, 512]


import sys
sys.stdin = open("baek11866.txt")

"""
특정 루프를 돌떄 (a % 루프단위)
이 방법을 요긴하게 쓸 수 있다.
"""

def josephus(n, k):
    # 0 부터 n-1 까지
    visited = [False] * n
    # 인덱스와 실제값이 1차이
    idx = k-1
    # 실제 order에는 1 더해준값을 저장
    order = [idx+1]
    visited[idx] = True
    count = 1
    while count < n:
        time = 0
        while time < k:
            idx = (idx + 1) % n
            if visited[idx]:
                continue
            time += 1
        visited[idx] = True
        order.append(idx+1)
        count += 1
    return order

N, K = map(int, input().split())
answer = josephus(N, K)
print("<", end="")
for i in range(0, N):
    if i == N-1:
        print(answer[i], end="")
    else:
        print(answer[i], end=", ")
print(">")


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import logging

from tornado.ioloop import IOLoop
from tornado.options import define, options
from tornado.web import Application, RequestHandler
from tornado.websocket import WebSocketHandler

rel = lambda *x: os.path.abspath(os.path.join(os.path.dirname(__file__), *x))

class MainHandler(RequestHandler):
	def get(self):
		self.render('index.html')

class WebRTCHandler(RequestHandler):
	def get(self):
		self.render('index3.html')

class EchoWebSocket(WebSocketHandler):
	clients = []

	def open(self):
		logging.info('WebSocket opened from %s', self.request.remote_ip)
		EchoWebSocket.clients.append(self)

	def on_message(self, message):
		logging.info('got message from %s: %s', self.request.remote_ip, message)
		for client in EchoWebSocket.clients:
			if client is self:
				continue
			client.write_message(message)

	def on_close(self):
		logging.info('WebSocket closed')
		EchoWebSocket.clients.remove(self)

class SignallingHandler(WebSocketHandler):
	clients = []

	def open(self):
		logging.info('WebSocket opened from %s', self.request.remote_ip)
		SignallingHandler.clients.append(self)

	def on_message(self, message):
		logging.info('got message from %s: %s', self.request.remote_ip, message)
		for client in SignallingHandler.clients:
			if client is not self:
				client.write_message(message)

	def on_close(self):
		logging.info('WebSocket closed')
		SignallingHandler.clients.remove(self)

def main():
	define('listen', metavar='IP', default='127.0.0.1', help='listen on IP address (default 127.0.0.1)')
	define('port', metavar='PORT', default=8888, type=int, help='listen on PORT (default 8888)')
	define('debug', metavar='True|False', default=False, type=bool,
			help='enable Tornado debug mode: templates will not be cached '
			'and the app will watch for changes to its source files '
			'and reload itself when anything changes')

	options.parse_command_line()

	settings = dict(
			template_path=rel('templates'),
			static_path=rel('static'),
			debug=options.debug
			)

	application = Application([
		(r'/', MainHandler),
		(r'/ws', EchoWebSocket),
		(r'/websocket', SignallingHandler),
		(r'/webrtc', WebRTCHandler)
		], **settings)

	#application.listen(address=options.listen, port=options.port)
	application.listen(7080)
	IOLoop.instance().start()

if __name__ == '__main__':
	main()


from datetime import datetime
from decimal import Decimal
from typing import Any, Dict

import pytest
from bson import Decimal128, ObjectId
from pymongo.database import Database

from surebets_finder.bet.domain.entities import Bet
from surebets_finder.bet.domain.errors import BetNotFoundError
from surebets_finder.bet.infrastructure.mongodb_bet_repo import MongoDBBetRepository
from surebets_finder.shared.category import Category
from surebets_finder.shared.provider import Provider

def test_can_create_bet(mongodb: Database) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # and
    bet = Bet(
        id=ObjectId(),
        opponent_1="test 1",
        opponent_2="test 2",
        odds_1=Decimal(4.12),
        odds_2=Decimal(3.56),
        category=Category.ESPORT,
        provider=Provider.EFORTUNA,
        date=datetime.utcnow(),
        url="/test/bet/url",
        updated_at=datetime.utcnow(),
    )

    # when
    repo.create(bet)

    # then
    document = mongodb["bet"].find_one({"_id": bet.id})
    assert document["_id"] == bet.id
    assert document["opponent_1"] == bet.opponent_1
    assert document["opponent_2"] == bet.opponent_2

def test_can_get_bet(mongodb: Database) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # when
    bet_id = ObjectId()
    mongodb["bet"].insert_one(
        {
            "_id": bet_id,
            "opponent_1": "test 1",
            "opponent_2": "test 2",
            "odds_1": Decimal128("4.12"),
            "odds_2": Decimal128("3.56"),
            "category": Category.ESPORT.value,
            "provider": Provider.EFORTUNA.value,
            "date": datetime.utcnow(),
            "url": "/test/bet/url",
            "updated_at": datetime.utcnow(),
            "created_at": datetime.utcnow(),
        }
    )

    # and
    bet = repo.get(bet_id)

    # then
    assert isinstance(bet, Bet)
    assert bet.id == bet_id
    assert bet.opponent_1 == "test 1"
    assert bet.opponent_2 == "test 2"
    assert bet.odds_1.compare(Decimal(4.12))
    assert bet.odds_2.compare(Decimal(3.56))
    assert bet.url == "/test/bet/url"

def test_get_bet_should_raise_an_exception_when_entity_does_not_exist(mongodb: Database) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # then
    with pytest.raises(BetNotFoundError):
        repo.get(ObjectId())

@pytest.mark.usefixtures("fill_in_db_with_bets_which_are_in_future")
def test_get_all_bets_which_are_in_future(mongodb: Database) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # when
    in_future = repo.get_all_which_are_in_future()

    # then
    assert len(in_future) == 5

def test_find_one(mongodb: Database, dummy_bet_document: Dict[str, Any]) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # when
    bet = repo.find_one(
        {
            "opponent_1": dummy_bet_document["opponent_1"],
            "opponent_2": dummy_bet_document["opponent_2"],
            "date": dummy_bet_document["date"],
        }
    )

    # then
    assert isinstance(bet, Bet)

def test_find_one_should_raise_an_exception_when_there_is_not_such_bet(
    mongodb: Database, dummy_bet_document: Dict[str, Any]
) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # then
    with pytest.raises(BetNotFoundError):
        repo.find_one(
            {"opponent_1": "john", "opponent_2": dummy_bet_document["opponent_2"], "date": dummy_bet_document["date"]}
        )

def test_can_save_bet(mongodb: Database, dummy_bet_id: ObjectId) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # and
    bet = repo.get(dummy_bet_id)

    # and
    bet.odds_1 = Decimal(6.12)
    bet.url = "another/new/url"

    # when
    repo.save(bet)

    # then
    document = mongodb["bet"].find_one({"_id": bet.id})
    assert str(document["odds_1"]) == str(round(bet.odds_1, 2))
    assert document["url"] == "another/new/url"


"""
This runs the experiment for testing out a ANN and recieving the predictions and uncert. in preds from said ANN.

All arguments in the args below are variable, i.e., you can change them by passing in arguemtns via CLI
Accesible via:
    $ python3 ANN_UQ.py -lr 0.001 -batch_size 350

to run the smoke test:
    $ python3 ANN_UQ --smoke_test

If you run this, below are two files that will be created (this will also overwrite the existing experiment)

- pickle file with the following dictionaries:
    - args = {'batch_size': 396, 'lr': 0.004, 'n_splits': 5, 'n_repeats': 5, 'n_estimators': 15,
            'scalex':StandardScaler, 'scaley':None , 'scale_args':(None, None),
            'hidden_layer_sizes': [483, 415, 254]}
    - results = {'y_vals': np.array(list_yvals), 'preds': np.array(list_preds), 'uncert': np.array(list_uncert),
               'score': scores}

- a temporary model state dict will be saved wherever you run this program from!

Results file is stored in same directory
To read the pickle file:
    with open(filename, 'rb') as file:
        args = pickle.load(file)
        results = pickle.load(file)
"""
from codebase.data import utils
from codebase.ANN.peanuts.models.utils import save_load_torch
from codebase.ANN.peanuts.models.torch_ensembles import AverageTorchRegressor

import numpy as np
import torch.nn as nn
import torch

from sklearn.preprocessing import StandardScaler

import pickle
import argparse

class ANNtorchdataset(torch.utils.data.Dataset):
    def __init__(self, controls, targets, scaley=None, scalex=None, train_scalers=None, scale_args=None):
        if train_scalers is None:
            if scalex is not None:
                if scale_args[0] is not None:
                    self.scalex = scalex(**scale_args[0])
                else:
                    self.scalex = scalex()
                controls = self.scalex.fit_transform(controls)
                controls = torch.tensor(controls).float()
            if scaley is not None:
                if scale_args[1] is not None:
                    self.scaley = scaley(**scale_args[1])
                else:
                    self.scaley = scaley()
                targets = self.scaley.fit_transform(targets)
                targets = torch.tensor(targets).float()
        else:
            self.scalex, self.scaley = train_scalers
            if self.scalex is not None:
                controls = self.scalex.transform(controls)
            if self.scaley is not None:
                targets = self.scaley.transform(targets)
            if not isinstance(targets, torch.Tensor):
                targets = torch.tensor(targets).float()
            if not isinstance(controls, torch.Tensor):
                controls = torch.tensor(controls).float()
        self.inputs = controls
        self.outputs = targets

    def __len__(self):
        return len(self.outputs)

    def __getitem__(self, item):
        return self.inputs[item], self.outputs[item]

    def return_scalars(self):
        try:
            return self.scalex, self.scaley
        except AttributeError:
            try:
                return self.scalex, None
            except AttributeError:
                return None

class PedFFNN(nn.Module):
    def __init__(self, **kwargs):
        super(PedFFNN, self).__init__()

        target_size = 1
        input_size = 12
        act_func = torch.nn.ELU()

        last_size = input_size

        self.hidden_layers = torch.nn.ModuleList()
        hidden_layer_sizes = kwargs['hidden_layer_sizes']

        for size in hidden_layer_sizes:
            self.hidden_layers.append(self._fc_block(last_size, size, act_func))
            last_size = size

        self.out = torch.nn.Linear(last_size, target_size)

    def forward(self, x):
        for layer in self.hidden_layers:
            x = layer(x)

        x = self.out(x)
        return x

    @staticmethod
    def _fc_block(in_c, out_c, act_func):
        block = torch.nn.Sequential(
            torch.nn.Linear(in_c, out_c),
            act_func
        )
        return block

    def predict(self, X):
        self.eval()
        pred = None

        if isinstance(X, torch.Tensor):
            pred = self.forward(X)

        elif isinstance(X, np.ndarray):
            X = torch.Tensor(X)
            pred = self.forward(X)

        else:
            msg = 'The type of input to ensemble should be a torch.tensor or np.ndarray'
            raise ValueError(msg)

        return pred

from sklearn.model_selection import RepeatedKFold
from sklearn.metrics import mean_squared_error, mean_absolute_error
from collections import OrderedDict
from tqdm import tqdm

def cross_validate_torch(control_tensor, target_tensor, **kwargs):
    control_tensor = control_tensor.float()
    target_tensor = target_tensor.float()
    ordered_preds = OrderedDict((index, []) for index in range(0, len(control_tensor)))
    ordered_error = OrderedDict((index, []) for index in range(0, len(control_tensor)))
    ordered_yvals = OrderedDict((index, []) for index in range(0, len(control_tensor)))
    error_dict = {'MAE': [], 'RMSE': []}
    cv = RepeatedKFold(n_splits=kwargs['n_splits'], n_repeats=kwargs['n_repeats'])
    iterator = tqdm(enumerate(cv.split(control_tensor)))
    for cv_id, (train, test) in iterator:
        train_dataset = ANNtorchdataset(control_tensor[train], target_tensor[train], scaley=kwargs['scaley'], scalex=kwargs['scalex'], scale_args=kwargs['scale_args'])
        test_dataset = ANNtorchdataset(control_tensor[test], target_tensor[test], train_scalers=train_dataset.return_scalars())

        train_loader = torch.utils.data.DataLoader(train_dataset, kwargs['batch_size'], shuffle=True)
        test_loader = torch.utils.data.DataLoader(test_dataset, kwargs['batch_size'], shuffle=True)

        # model = PedFFNN(hidden_layer_sizes=kwargs['hidden_layer_sizes'])
        base_model = PedFFNN
        model = AverageTorchRegressor(estimator=base_model, n_estimators=kwargs['n_estimators'],
                                      estimator_args={'hidden_layer_sizes': kwargs['hidden_layer_sizes']}).double()
        # optimizer = set_module_torch.set_optimizer(model, 'Adam', lr=kwargs['lr'])
        model.set_optimizer('Adam', lr=kwargs['lr'])

        # best_MSE =  np.inf

        model.fit(train_loader=train_loader, test_loader=test_loader, epochs=200)

        model = AverageTorchRegressor(estimator=base_model, n_estimators=kwargs['n_estimators'],
                                      estimator_args={'hidden_layer_sizes': kwargs['hidden_layer_sizes']})

        model._decide_n_outputs(test_loader)
        save_load_torch.load(model)
        predictions, std_preds = model.predict(control_tensor[test], return_std=True)
        if kwargs['scaley'] is not None:
            predictions = test_dataset.scaley.inverse_transform(predictions)

        # std_preds = predictions

        for index, std, mean_pred, yval in zip(test, std_preds, predictions, target_tensor[test]):
            ordered_error[index].append(std.item())
            ordered_preds[index].append(mean_pred.item())
            ordered_yvals[index].append(yval.item())

        RMSE = mean_squared_error(target_tensor[test], predictions, squared=False)
        MAE = mean_absolute_error(target_tensor[test], predictions)
        error_dict['RMSE'].append(RMSE)
        error_dict['MAE'].append(MAE)
        iterator.set_postfix(RMSE=RMSE, MAE=MAE)

    list_uncert = []
    list_yvals = []
    list_preds = []
    for index in ordered_error.keys():
        list_uncert.append(np.mean(ordered_error[index]))
        list_yvals.append(np.mean(ordered_yvals[index]))
        list_preds.append(np.mean(ordered_preds[index]))
    scores = {'RMSE': (np.mean(error_dict['RMSE']), np.std(error_dict['RMSE'])),
              'MAE': (np.mean(error_dict['MAE']), np.std(error_dict['MAE']))}
    results = {'y_vals': np.array(list_yvals), 'preds': np.array(list_preds), 'uncert': np.array(list_uncert),
               'score': scores}

    return results

def main(control_tensor, target_tensor, **kwargs):
    results = cross_validate_torch(control_tensor, target_tensor, torch_model=PedFFNN, **kwargs)

    return results

def generate_default_params():
    args = {'batch_size': 396, 'lr': 0.004, 'n_splits': 5, 'n_repeats': 5, 'n_estimators': 15,
            'scalex':StandardScaler, 'scaley':None , 'scale_args':(None, None),
            'hidden_layer_sizes': [483, 415, 254]
            }
    return args

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-batch_size", help='batch size during training/validation', type=int, default=396)
    parser.add_argument('-lr', help='learning rate', type=float, default=0.004)
    parser.add_argument('-n_splits', help='number of folds in CV', type=int, default=5)
    parser.add_argument('-n_repeats', help='number of repeats of CV', type=int, default=5)
    parser.add_argument('-n_estimators', help='Number of ANNs in ensemble, 1 is default ANN',type=int, default=15)
    parser.add_argument('-hidden_layer_sizes', help='Sizes of hidden layers in ANN', type=list, default=[483, 415, 254])
    parser.add_argument('--smoke_test', help='Smoke Test, quickly check if it works', action="count", default=0)
    args_namespace = parser.parse_args()
    args = vars(args_namespace)
    # make data and tensors

    torch.manual_seed(42)
    np.random.seed(42)
    control_space, target_space, _, _ = utils.process_data()
    control_tensors, target_tensors = utils.setup_tensors(control_space, target_space)
    # TODO: argparse - need for batch size, learning rate,
    try:
        if args['smoke_test'] >= 1:
            smoke_args = {'n_estimators': 2, 'hidden_layer_sizes': [10, 10], 'n_splits': 2, 'n_repeats': 2}
            params = generate_default_params()
            params.update(smoke_args)
            results = main(control_tensors, target_tensors, **params)
            print('PASSED SMOKE TEST')
        else:
            params = generate_default_params()
            params.update(args)
            results = main(control_tensors, target_tensors, **params)
            with open('{}_layer_UQ_{}_est.pickle'.format(len(params['hidden_layer_sizes']), params['n_estimators']), 'wb') as file:
                pickle.dump(params, file)
                pickle.dump(results, file)
    except Exception as exc:
        raise exc


import os,sys
import shutil
import datetime

from liblda import interfaces

from liblda.util import rungen
from liblda.util import newman_topicmodel

import subprocess

from local_settings import PROJECT_PATH, topicmodel_DIR, RUNDIRS_ROOT

import logging
logger = logging.getLogger('NewmanLdaModel')
logger.setLevel(logging.INFO)

# Errors accociated with this
class IncompleteInputError(Exception):
    """
    The user didn't supply a corpus or numT
    """
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return repr(self.msg)

class ScriptError(Exception):
    """
    An error occurred somewhere in train(), i.e creating rundir
    writing input to disk, mv-ing the executable in place in rundir
    or running ./topicmodel
    """
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return repr(self.msg)

class NewmanLdaModel(interfaces.LdaModelABC):
    """
    A class that calls Dave Newman's Gibbs sampler to train the
    model.

    Parameters:
        numT        : number of topics in model
        alpha       : Dirichlet prior on theta (topics in docs)
                      len: numT   or  constant scalar
        beta        : Dirichlet prior on phi (words in topics)

    Input data:
        corpus      : reference to a corpus object (anything that looks like [[ (termid,count) ]]
        numDocs     : len(corpus)

    Optional input:
        vocab       : ref to Vacabulary object  #calV
                      (which can map word id to word string)
        numTerms    : len(vocab) #V

    API:
        corpus=[[(1,1),(2,4)],[(1,1)]]
        lda = NewmanLdaModel( corpus=corpus, numT=17, alpha=50.0/17, beta=0.01 )
        lda.train()

    Then some time goes by...
    and the following things appear.

    Inferred model:
        phi         : topic-word distribution
                      size: numT x numTerms
                      alias: prob_w_given_t
        theta       : document-topic distibution
                      size: numDocs x numT
                      alias: prob_t_given_d
        z           : the topic assignment
                      size: ?

    """

    def __init__(self, numT=None, alpha=None, beta=None, corpus=None,  vocab=None):
        """
        This creates the LDA model.

        Must supply corpus and numT before you can train() it.
        """
        self.numT = numT                    # number of topics
        self.alpha = alpha                  # Dirichlet prior on theta (topics in docs)
        self.beta  = beta                   # Dirichlet prior on phi (words in topics)

        self.corpus= corpus
        #numDocs = len(corpus)      how do i make this lazy?

        self.vocab = vocab

        self.phi = None
        self.theta = None
        self.z = None

    def is_trained(self):
        """
        Tells you whether model has been trained or not.
        """
        raise NotImplementedError('cannot instantiate abstract base class')

    def train(self, rundir=None, rundir_root=None, iter=50,seed=None):
        """
        Runs the Dave Newman's C code:
         1/ setup a rundir, if no rundir, then create one in /tmp
         2/ write the contents of corpus to  rundir/docword.txt
         3/ extract a copy of the executable for that OS
         4/ run topicmodel
                run topic model(T=10 topics, iter=200 iterations),
                ./topicmodel 10 200 777
         5/ read in  Nwt.txt,  Ndt.txt,  z.txt into
                     p(w|t)    p(t|d)    Z_{d_i,w_j}

        """
        if not self.numT:
            raise  IncompleInputError('Must specify number of topics: self.numT')
        if self.corpus ==None:
            raise  IncompleInputError('Must provide a corpus to train on: self.corpus')

        # params
        self.iter = iter    # iter set to 50 by default..

        if not seed:
            seed = 777
        self.seed = seed

        self.mkrundir(rundir)
        self.copy_topicmodel(rundir)
        self.write_corpus_to_docword(rundir)
        self.run(rundir,iter,seed)
        self.load_probs(rundir)

    def mkrundir(self,rundir):
        # sort out the rundir
        if not rundir:
            # ok so we will generate one
            if not rundir_root:
                rundir_root=RUNDIRS_ROOT
            rundir = rungen.mk_next_rundir(rundir_root)

        # ok so we have a rundir now
        assert os.path.exists(rundir), "rundir doesn't exist!"
        self.rundir = rundir    # tag it onto the LdaModel while we are at it

    def copy_topicmodel(self, rundir):
        # move topicmodel binary into place
        binary = os.path.join(topicmodel_DIR,"topicmodel")
        assert os.path.exists(binary), "topicmodel binary doesn't exist."
        shutil.copy(binary,rundir)

    def write_corpus_to_docword(self, rundir):
        # write corpus to docwords...
        dwfile = os.path.join(rundir,"docword.txt")
        newman_topicmodel.NewmanWriter.writeCorpus(dwfile, self.corpus)
        assert os.path.exists(dwfile), "docword.txt doesn't exist."

    def run(self,rundir,iter,seed):
        # cd to rundir
        os.chdir(rundir)

        # get the party started
        logger.info("Starting Newman's Gibbs sampler")
        #logger.info("Starting run in  "+ rundir )

        runcommand = os.path.join(rundir,"topicmodel") +" "+str(self.numT)+" "+str(iter)+" "+str(seed)
        logger.info("run command: "+runcommand )

        ###### CALLING STARTS  #####################################################
        start_time = datetime.datetime.now()
        (out,err)  = subprocess.Popen(runcommand, shell=True, \
                                                   stdout=subprocess.PIPE, \
                                                   stderr=subprocess.PIPE \
                                                   ).communicate()

        end_time = datetime.datetime.now()
        duration = (end_time-start_time).seconds
        logger.info("run duration: "+str(duration)+" seconds")
        ###### CALLING STOPS  ######################################################

    def load_probs(self,rundir):
        # read Nwt.txt
        fname1 = os.path.join(rundir,"Nwt.txt")
        Nwt=newman_topicmodel.loadsparsemat(fname1)   # teruns an array of counts
        self.Nwt = Nwt
        # make into normalized probability distirbution
        self.phi = newman_topicmodel.conv_Nwt_to_phi(Nwt)

        # read Ndt
        fname2 = os.path.join(rundir,"Ndt.txt")
        Ndt=newman_topicmodel.loadsparsemat(fname2)   # teruns an array of counts
        self.Ndt = Ndt
        # make into normalized probability distirbution
        self.theta = newman_topicmodel.conv_Ndt_to_theta(Ndt)

        logger.info("Done loading LDA model (phi,theta) from files" )


import time
import codecs		# utf-8 file support
import sys
import traceback
import os
import jinja2		# template engine
import textwrap
from optparse import OptionParser

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from xmlparser.parser import Parser
from xmlparser.parser_exception import ParserException

class BuilderException(Exception):
	pass

class Builder(object):
	"""
	Base class for any builder-class

	Attributes:
	self.xmlpath		--	path to the xml-file
	self.xmlfile		--	xml-filename
	self.tree			--	evaluated xml tree, instance of Parser
	self.time			--	string containing the current date and time
	self.options		--	evaluated commandline arguments (see OptionParser)
	self.include_paths	--	paths that will be searched for include files

	To access the elements from the xml tree use for example:
	self.tree.components
	self.tree.components.actions			--	all actions
	self.tree.components.subscriptions		--	all events
	self.tree.components["driver"].actions	--	only actions form the
												component 'driver'
	self.tree.components["driver"].events.publish
	self.tree.components["driver"].events.subscribe
	self.tree.containers
	self.tree.containers["PC"].components	--	only components form the
												container 'PC'
	self.tree.types
	self.tree.events

	You have to specify a VERSION attribute.

	"""
	def __init__(self):
		optparser = OptionParser(
				usage   = "%prog [options] XML_FILE",
				version = "%prog version: " + self.VERSION )

		optparser.add_option(
				"-o", "--outpath",
				dest = "outpath",
				default = None,
				help = "Output path [optional]")

		optparser.add_option(
				"-t", "--template_path",
				dest = "templatePath",
				default = None,
				help = "Template path [optional]")

		optparser.add_option(
				"-d", "--dtdpath",
				dest = "dtdPath",
				default = None,
				help = "DTD path [optional]")

		optparser.add_option(
				"-I", "--include_path",
				dest = "includePath",
				default = None,
				help = "Include Search Path [optional]")

		self.setup(optparser)

		(self.options, args) = optparser.parse_args()

		if len(args) != 1:
			raise BuilderException("XML_FILE: You have to specify a valid xml-file")
			exit(1)

		self.xmlfile = args[0]
		self.xmlpath = os.path.dirname(os.path.abspath(self.xmlfile))

		# convert include paths to absolute paths
		self.include_paths = []
		include_paths = self.options.includePath
		if not isinstance(include_paths, list):
			include_paths = [include_paths]
		for path in include_paths:
			if isinstance(path, str):
				self.include_paths.append(os.path.abspath(path))

		try:
			parser = Parser()
			parser.parse(self.xmlfile, dtdPath=self.options.dtdPath, include_paths=self.include_paths)
		except ParserException as e:
			sys.stderr.write("Parsing Error: %s\n" % str(e))
			print(traceback.format_exc())
			sys.exit(1)

		self.tree = parser.tree
		self.globals = {
			'time': time.strftime("%d %b %Y, %H:%M:%S", time.localtime()),
		}

		if self.options.templatePath == None:
			self.templatePath = "templates/"
		else:
			self.templatePath = self.options.templatePath

	def generate(self):
		""" Generate the requested files """
		raise BuilderException("You can not use this class directly!")

	def setup(self, optparser):
		"""
		Setup the builder. Can be overwritten to customise the behavior.

		Keywords arguments:
		optparser		--	OptionParser instance. Use add_option for
							additional commandline arguments.
		"""
		pass

	def write(self, filename, data):
		"""
		Write data utf-8 decoded to a file.

		Contents of the file will be overwritten.
		"""
		# create the path if it doesn't exists
		dir = os.path.dirname(filename)
		if not os.path.isdir(dir):
			os.mkdir(dir)

		# write data
		file = codecs.open(filename, 'w', 'utf8')
		file.write(data)
		file.close()

	def read(self, filename):
		"""
		Read a utf-8 decoded file.

		Provided for convenience.
		"""
		return codecs.open(filename, 'r', 'utf8').read()

	def template(self, filename, filter=None):
		""" Open a template file

		Uses the jinja2 template engine. The following additional filters
		are included:
		xpcc.wordwrap(with)		--	like the original filter, but with correct
									handling of newlines
		xpcc.indent(level)		--	indent every line with \a level tabs

		Keyword arguments:
		filename	--	Template file
		filter		--	dict with additional filters (see the section
						'Custom Filters' in the Jinja2 documentation for details)

		Example:
		template = builder.template(file)

		output = template.render(dict)
		builder.write(outputfile, output)

		"""
		def filter_wordwrap(value, width=79):
			return '\n\n'.join([textwrap.fill(str, width) for str in value.split('\n\n')])

		def filter_indent(value, level=0, prefix=""):
			return ('\n' + '\t' * level + prefix).join(value.split('\n'))

		path = os.path.dirname(filename)
		name = os.path.basename(filename)

		if not os.path.isabs(filename):
			relpath = os.path.dirname(os.path.abspath(__file__))
			path = os.path.join(relpath, path)

		environment = jinja2.Environment(
				loader=jinja2.FileSystemLoader(path),
				extensions=["jinja2.ext.loopcontrols"])
		environment.filters['xpcc.wordwrap'] = filter_wordwrap
		environment.filters['xpcc.indent'] = filter_indent
		if filter:
			environment.filters.update(filter)
		template = environment.get_template(name, globals=self.globals)

		return template

	def run(self):
		try:
			self.generate()
		except BuilderException as e:
			sys.stderr.write("Builder Error: %s\n" % str(e))
			sys.exit(1)
		except jinja2.exceptions.TemplateSyntaxError as e:
			sys.stderr.write("Error in Template: %s\n" % str(e))
			sys.exit(1)
		#except Exception as e:
		#	sys.stderr.write("Internal Error: %s\n" % str(e))
		#	sys.exit(1)


"""
Used to extract sentiment from headlines
"""

import logging
import nltk.sentiment.vader

MAX_TWEET_LENGTH = 280

def compound_score(text):
    """
    Provides the compound sentiment score of the text provided, using the VADER sentiment
    analyser. Expects text to be less than 280 characters
    :param text: text to be analysed for sentiment
    :return: Compound sentiment score
    """
    # warning, due to vader being trained on short text -- social media posts
    if len(text) > MAX_TWEET_LENGTH:
        logging.warning('Text provided is longer than a standard tweet, VADER is designed to be '
                        'used on short pieces of text')
    vader = nltk.sentiment.vader.SentimentIntensityAnalyzer()
    return vader.polarity_scores(text)['compound']


# class user_input:

#     def __init__(self, number):
#         self.number = number

#     @classmethod
#     def take_input(num):
#         return num(
#                     int(input('Binary Input: ')),
#                     #int(input('Binary Input B: ')),
#                     )
import math

a = input("\nBinary number 1: ")
b = input("Binary number 2: ")

op = input("\nHalf Precision: 1\nSingle Precision: 2\nDouble Precision: 3\n")

print ('\na = ',a)
print ('b = ',b)
print ('op = ',op)

############### Sign Bit
if math.trunc(float(a)) >= 0:
    sign_bit_a = 0
else:
    sign_bit_a = 1

if math.trunc(float(b)) >= 0:
    sign_bit_b = 0
else:
    sign_bit_b = 1

print('\nsign_bit_a = ',sign_bit_a)
print('sign_bit_b = ',sign_bit_b)

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

############### Biased Exponent
#assuming the number is given in points i.e. with a decimal point
string_a = str(a)
string_b = str(b)

tempa = string_a.split(".")
tempb = string_b.split(".")

len_a = len(tempa[1])
len_b = len(tempb[1])

true_a = len_a - 1
true_b = len_b - 1

if int(op) == 1:
    bias_a = true_a + 5
    bias_b = true_b + 5
    print("IN THE BIAS LOOP")
if int(op) == 2:
    bias_a = true_a + 127
    bias_b = true_b + 127
if int(op) == 3:
    bias_a = true_a + 1023
    bias_b = true_b + 1023

print ('Bias_a = ',bias_a)
print ('Bias_b = ',bias_b)
###############

############### Mantissa

m_a = tempa[1]
m_b = tempb[1]
print("mantissa a", m_a)
print("mantissa b", m_b)
###############

############### Compare Exponents and Right shift Mantissa
if bias_a > bias_b:
    bias_exp = bias_a
    m_a = int(str(1) + str(m_a))
    print("shifted a", m_a)
else:
    bias_exp = bias_b
    m_b = int(str(1) + str(m_b))
    print("shifted b", m_b)
###############

############### Two's complement
if sign_bit_a == 1:
    ones_comp = ~m_a
    temp = ones_comp + 1
    m_a = int(temp)
    print("-- ", m_a)
else:
    print('bits=',m_b)
    print(type(m_b))
    #m_b = "0b" + str(m_b)
    ones_comp = ~m_b
    print('ones ', ones_comp)
    temp = ones_comp + 1
    m_b = int(temp)
    print("++ ", m_b)

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


import sys
from typing import Optional, cast
from enum import Enum
import os
import shlex
if sys.platform == "win32":
    import win32api
    import win32event
    import win32file
    import pywintypes
    import winreg
    WOW64_KEYS: list[int] = [0, winreg.KEY_WOW64_64KEY, winreg.KEY_WOW64_64KEY]
else:
    WOW64_KEYS: list[int] = []

class RegistryClass(Enum):
    if sys.platform == 'win32':
        HKEY_CLASSES_ROOT = winreg.HKEY_CLASSES_ROOT
        HKEY_CURRENT_USER = winreg.HKEY_CURRENT_USER
        HKEY_LOCAL_MACHINE = winreg.HKEY_LOCAL_MACHINE
        HKEY_USERS = winreg.HKEY_USERS
        HKEY_PERFORMANCE_DATA = winreg.HKEY_PERFORMANCE_DATA
        HKEY_CURRENT_CONFIG = winreg.HKEY_CURRENT_CONFIG
        HKEY_DYN_DATA = winreg.HKEY_DYN_DATA
    else:
        HKEY_CLASSES_ROOT = 0
        HKEY_CURRENT_USER = 1
        HKEY_LOCAL_MACHINE = 2
        HKEY_USERS = 3
        HKEY_PERFORMANCE_DATA = 4
        HKEY_CURRENT_CONFIG = 5
        HKEY_DYN_DATA = 6

def stdin_has_content(timeout: float) -> bool:
    if sys.platform != 'win32':
        raise NotImplementedError
    else:
        try:
            # without this the wait sometimes returns without there being
            # any actual data -> we woul block infinitely on the read
            win32file.FlushFileBuffers(win32api.STD_INPUT_HANDLE)
        except pywintypes.error:
            # the flush sometimes fails, too bad!
            pass
        return win32event.WaitForSingleObject(
            win32api.STD_INPUT_HANDLE, int(timeout * 1000)  # milliseconds
        ) is win32event.WAIT_OBJECT_0

def get_registry_entries(
    rc: RegistryClass,
    registry_path: str, values: list[Optional[str]] = [None],
    wow_key: int = 0
) -> Optional[list[Optional[str]]]:
    if sys.platform != 'win32':
        raise NotImplementedError
    else:
        results: list[Optional[str]] = []
        key = None
        try:
            key = winreg.OpenKey(rc.value, registry_path, 0, winreg.KEY_READ | wow_key)
            for subkey in values:
                try:
                    # subkey may be None, which is legal in winapi (returns value of the key itself)
                    # but for some reason forbidden by the type annotation in winreg
                    # we can't even type ignore it since mypy on linux will complain about
                    # an unused type ignore then ...
                    value = winreg.QueryValueEx(key, cast(str, subkey))[0]
                    results.append(value)
                except FileNotFoundError:
                    results.append(None)
            return results
        except FileNotFoundError:
            return [None] * len(values)
        finally:
            if key is not None:
                winreg.CloseKey(key)

def get_registry_entries_anywow(
    rcs: list[RegistryClass],
    key: str,
    values: list[Optional[str]] = [None],
    wow_keys: list[int] = WOW64_KEYS
) -> list[Optional[str]]:
    for rc in rcs:
        for wowkey in wow_keys:
            res = get_registry_entries(rc, key, values, wowkey)
            if res is not None:
                if any(r is not None for r in res):
                    return res
    return [None] * len(wow_keys)

def try_get_app_path_from_reg_uninstall_path(app_name: str, app_exe_name: str) -> Optional[str]:
    install_loc = get_registry_entries_anywow(
        [RegistryClass.HKEY_LOCAL_MACHINE, RegistryClass.HKEY_CURRENT_USER],
        "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + app_name,
        ["InstallLocation"]
    )[0]
    if install_loc is not None:
        loc = os.path.join(install_loc, app_exe_name)
        if os.path.exists(loc):
            return loc
    return None

def try_get_app_path_from_reg_start_menu_internet(app_name: str) -> Optional[str]:
    command = get_registry_entries_anywow(
        [RegistryClass.HKEY_LOCAL_MACHINE, RegistryClass.HKEY_CURRENT_USER],
        "SOFTWARE\\Clients\\StartMenuInternet\\" + app_name + "\\shell\\open\\command"
    )[0]
    if command is not None:
        app_path = shlex.split(command)[0]
        if os.path.exists(app_path):
            return app_path
    return None

def try_get_app_path_from_reg_app_paths(app_exe_name: str) -> Optional[str]:
    app_path = get_registry_entries_anywow(
        [RegistryClass.HKEY_LOCAL_MACHINE, RegistryClass.HKEY_CURRENT_USER],
        "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" + app_exe_name,
    )[0]
    if app_path is not None and os.path.exists(app_path):
        return app_path
    return None


from constructs import Construct
from aws_cdk import (
Stack,
Environment,
SecretValue,
pipelines
)

from .webservice_stage import WebServiceStage

APP_ACCOUNT = '782160816199'

class PipelineStack(Stack):
  def __init__(self, scope: Construct, id: str, **kwargs):
    super().__init__(scope, id, **kwargs)

    source = pipelines.CodePipelineSource.git_hub("abhishekbose86/aws-apigw-lambda-eventbridge-kinesis-S3", "main",
        authentication=SecretValue.secrets_manager("github-token"))
    pipeline = pipelines.CodePipeline(self, 'Pipeline',
      pipeline_name='TestPipeline',

      synth=pipelines.ShellStep("Synth",
        input = source,
        commands=[
          'npm install -g aws-cdk && pip install -r requirements.txt',
          'pytest unittests',
          'cdk synth'
        ]
    ))

    pre_prod_app = WebServiceStage ( self, 'Pre-Prod',
     env = Environment (account = APP_ACCOUNT, region = "us-east-2" ))
    pipeline.add_stage(pre_prod_app)


# flake8: noqa
# fmt: off
import json
import uuid
import pytest
import requests.auth
from CEI_TestSetup import *

def test_incident_key_failure():
    """Test to ensure a faulty (Broken Key) call is handled properly
    API must return 400 error or the test fails
    """

    data = open_json_file("KeyErrorTest.json", False)
    data_call = json.dumps(data).replace("RANDOMIZEGUID", str(uuid.uuid4()))
    api_url = get_API_url()
    # Get API Token
    headers["Authorization"] = get_API_token()

    # construct API Call
    incident_url = f"{api_url}/cad/incidents"
    incident_post_results = requests.post(incident_url, data=data_call, headers=headers)
    if "400" not in str(incident_post_results):
        pytest.fail(f"API post has failed - response: {str(incident_post_results)}")

def test_config_msg_bad_format():
    """Test that the configuration call handles msg format failures gracefully
    Fails if the resulting response indicates success
    """
    data = open_json_file("ConfigurationBadFormatCall.json", False)
    data_call = json.dumps(data).replace("'", '"').replace("|||", "'").replace("|", "")
    api_url = get_API_url()
    # construct API Call
    config_url = f"{api_url}/cad/configuration"
    config_post_results = requests.post(config_url, data=data_call, headers=headers)
    if "200" in str(config_post_results):
        pytest.fail(f"API post has failed - response: {str(config_post_results)}")

def test_config_msg_incomplete():
    """Test that the configuration call handles incomplete failures gracefully
    Fails if the resulting response indicates success
    """
    data = open_json_file("ConfigurationIncompleteCall.json", False)
    data_call = json.dumps(data).replace("'", '"').replace("|||", "'").replace("|", "")
    api_url = get_API_url()
    # construct API Call
    config_url = f"{api_url}/cad/configuration"
    config_post_results = requests.post(config_url, data=data_call, headers=headers)
    if "200" in str(config_post_results):
        pytest.fail(f"API post has failed - response: {str(config_post_results)}")

# fmt: on


import os, sys

from setuptools import setup, find_packages

def read_requirements():
    """Parse requirements from requirements.txt."""

    reqs_path = os.path.join('.', 'requirements.txt')
    with open(reqs_path, 'r') as f:
        requirements = [line.rstrip() for line in f]
    return requirements

setup(
    name='primely_docker_flask',
    version='0.0.1',
    description='Host Primely on Docker',
    long_description='README.md',
    author='Yoshiki Nakagawa',
    author_email='ben.nakagawa01@gmail.com',
    install_requires=read_requirements(),
    url='https://github.com/yoshiki-o0/primely_package',
    lincense='LICENCE',
    # package_dir={'': 'primely'},
    packages=find_packages(),
    # packages=[
    #     'primely.controller',
    #     'primely.models',
    #     'primely.templates',
    #     'primely.views',
    #     'tests',
    # ],
    test_suite='tests'
)


import socketio
from mode import Service
from mode.threads import ServiceThread

import settings
from app.meth_one.stream import fx_message_stream_topic_eur_usd, FxStreamMessage, fx_message_live_stream_topic, \
    fx_price_prediction_stream, fx_candle_stream, Candle, fx_candle_1min_stream, PricePrediction
from app.meth_one.utils import read_from_ws_history, read_from_ws_live, process_message
from application import stapp
from utils.stream_helper import stream_last_

m_sio = socketio.AsyncRedisManager(settings.SOCKET_IO_MESSAGE_BROKER, write_only=True)

EURUSD = "EURUSD"

class MethodOne(ServiceThread):

    async def on_start(self) -> None:
        print('MethodOne STARTING')

    @Service.task
    async def web_stream_live_data_eur_usd(self):
        async def result_reader(message):
            await fx_message_live_stream_topic.send(value=FxStreamMessage(message=message, type="TICK"))

        await read_from_ws_live(EURUSD, result_reader)

    @Service.task
    async def web_steam_data_eur_usd(self):
        async def result_reader(message):
            await fx_message_stream_topic_eur_usd.send(value=FxStreamMessage(message=message, type="CANDLE"))

        await read_from_ws_history(EURUSD, result_reader, count=120)

    @Service.task
    async def web_steam_data_eur_jpy(self):
        async def result_reader(message):
            await fx_message_stream_topic_eur_usd.send(value=FxStreamMessage(message=message, type="CANDLE"))

        await read_from_ws_history(EURUSD, result_reader)

async def call_after_process_candle_live_feed(candle):
    await fx_candle_stream.send(value=candle)

@stream_last_(fx_candle_stream, stapp)
async def candle_stream_fx(stream):
    await fx_candle_1min_stream.send(value=stream)

@stapp.agent(fx_message_stream_topic_eur_usd)
async def process_bar_data(views):
    async for fx_msg in views:
        await process_message(fx_msg.message, call_back=call_after_process_candle_live_feed)

@stapp.agent(fx_candle_1min_stream)
async def live_stream_candle_fx_data(messages):
    async  for candle in messages:
        candle: Candle = candle
        await m_sio.emit('candle_live_stream_eur_usd',
                         {
                             "open": candle.open,
                             "close": candle.close,
                             "high": candle.high,
                             "low": candle.low,
                             "date": candle.open_time,
                             "close_time": candle.epoch
                         },
                         namespace='/trading'
                         )

@stapp.agent(fx_message_live_stream_topic)
async def live_stream_fx_data(messages):
    async for fx_msg in messages:
        tick = await process_message(fx_msg.message)
        await m_sio.emit('original_data',
                         {'data': [tick['ask'], tick['bid'], tick['quote']], 'time': tick['timestamp']},
                         namespace='/trading'
                         )

@stapp.agent(fx_price_prediction_stream)
async def fx_price_prediction_stream_broad_cast(predictions):
    async for prediction in predictions:
        prediction: PricePrediction = prediction
        await m_sio.emit('price_prediction',
                         {
                             "time": prediction.time,
                             "price": prediction.price,
                             "price_change": prediction.price_change,
                             "origin_time": prediction.origin_time,
                             "originator": prediction.originator,
                         },
                         namespace='/trading'
                         )


from functools import lru_cache

@lru_cache
def divs(n):
    s = {1, n}
    for d in range(2, int(n**0.5) + 1):
        if n % d == 0:
            s.add(d)
            s.add(n // d)
    return s

# print(divs(100), len(divs(100)))
a = list(map(int, open('17_adv.txt').readlines()))
# print(a)
mx = -10**10
divs_key = None
for el in a:
    if len(divs(el)) > mx:
        mx = len(divs(el))
        divs_key = divs(el)

ans = []
for i in range(1, len(a)):
    p1, p2 = a[i - 1], a[i]
    if len(divs(p1) & divs_key) >= 3 and len(divs(p2) & divs_key) >= 3:
        ans.append(len(divs(p1) & divs(p2)))
print(len(ans), max(ans))


import os;
from sys import argv;
import glob;

#expects one command-line argument
current_path = os.getcwd()
new_path = current_path + "\\" + argv[1]
os.chdir(new_path)

#helper function to clean transcript files when copied directly from Panopto and create new files ready for main.py
texts = {}
all_txt_files = glob.glob('*.txt')
for i in range(len(all_txt_files)):
    #creates new file in other folder with every other line of og file
    #because panopto has timestamps every other line
    inputFile = open(all_txt_files[i],'r')
    new_file_path = current_path + "\\new_lectures\\" + all_txt_files[i]
    outputFile = open(new_file_path,'x')
    count = True
    for line in inputFile:
        if (count):
            outputFile.write(line)
        count = not count
    #closes files
    inputFile.close()
    outputFile.close()


'''Access information about the database's time dimension

The temporal concepts in most World Bank databases are named 'time' but in
some cases are named 'year' or something else. Keys for time elements are
not always consistent across databases. The wbgapi module tries to insulate
the user from most of these inconsistencies. The module will also generally
accept both numeric values and element keys as parameters where this is possible,
e.g., 'YR2015,' '2015' and 2015 are acceptable.
'''
import wbgapi as w
from . import utils
import builtins

# this is an array of reverse value lookup tables
_time_values = {}

def list(id='all', q=None, db=None):
    '''Return a list of time elements in the current database

    Arguments:
        id:     a time identifier or list-like

        q:      search string (on value name)

        db:     database; pass None to access the global database

    Returns:
        a generator object

    Example:
        # fetch even-numbered time elements for a decade
        for elem in wbgapi.time.list(range(2010,2020,2)):
            print(elem['id'], elem['value'])
    '''

    q,_ = utils.qget(q)

    for row in  w.source.features('time', w.queryParam(id, 'time', db=db), db=db):
        if utils.qmatch(q, row['value']):
            yield row

def get(id, db=None):
    '''Retrieve the specified time element

    Arguments:
        id:     the time identifier

        db:     database; pass None to access the global database

    Returns:
        a time object

    Example:
        print(wbgapi.time.get('YR2015')['value'])
    '''

    return w.source.feature('time', w.queryParam(id, 'time', db=db), db=db)

def Series(id='all', q=None, db=None, name='TimePeriodName'):
    '''Return a pandas series by calling list
    '''

    return w.Series(list(id, q=q, db=db), name=name)

def periods(db=None):
    '''Returns a dict of time features keyed by value for the current database. This is
    primarily used internally to recognize both values and keys as equivalent
    '''
    global _time_values

    if db is None:
        db = w.db

    v = _time_values.get(db)
    if v is None:
        v = {}
        for row in w.source.features('time', 'all', db=db):
            v[row['value']] = row['id']

        _time_values[db] = v

    return v

def info(id='all', q=None, db=None):
    '''Print a user report of time features

    Arguments:
        id:         a time identifier or list-like

        q:          search string (on value name)

        db:         database; pass None to access the global database

    Returns:
        None
    '''

    return w.Featureset(list(id, q=q, db=db))


import sqlite3
import os
import numpy.random as random

# Sets Database Name

database_file = "school.db"

# Tells the program if it should
# delete the database if it fails
# to set up.

database_remove_on_failure = True

# Checks if the file exists

setup = os.path.exists(database_file)

# Initialises the variable

con = None

# Sets debug mode to false
# will avoid showing any errors
# that might occur when running
# the program.

program_debug = False

try:
    # Connects to the database
    con = sqlite3.connect(database_file)
except Exception as error:
    if program_debug:
        print(error)

def setup_database(force=False):
    global con

    # Sets up the database by
    # adding the tables that will
    # be needed in the database
    # for the program to successfully
    # run.

    if force:
        # Force will remove the database
        # and make sure that the program
        # creates a clean version of the
        # database which might be handy
        # for the teacher or program.

        if os.path.exists(database_file):
            if con:
                con.close()
            os.remove(database_file)
        try:
            con = sqlite3.connect(database_file)
        except Exception as err:
            if program_debug:
                print(err)

    try:

        con.execute('''
            CREATE TABLE students(
                ID INTEGER PRIMARY KEY NOT NULL,
                first_name TEXT(30) NOT NULL,
                last_name TEXT(30) NOT NULL,
                class_name TEXT NOT NULL
            )
        ''')

        con.execute('''
            CREATE TABLE arithmetic_test(
                ID INTEGER PRIMARY KEY NOT NULL,
                student_ID INTEGER NOT NULL,
                score_1 REAL NOT NULL,
                score_2 REAL NOT NULL,
                score_3 REAL NOT NULL,
                average_score REAL NOT NULL
            )
        ''')

        # Saves the database

        con.commit()

    except Exception as err:
        if con:
            con.close()
        if database_remove_on_failure:
            os.remove(database_file)
        raise SystemError(f"Failed to setup database file with error: {err}")

if not setup:
    setup_database()

def get_test_id():
    # Sets Min
    largest_id = 100000
    try:
        # Gets ID from table
        for row in con.execute("SELECT ID FROM arithmetic_test"):
            if row[0] > largest_id:
                largest_id = row[0]  # Sets largest ids
        # Increments
        return largest_id + 1
    except Exception as err:
        print(f"Failed to get test id with error: {err}")

def get_student_id():
    # Sets Min
    largest_id = 100000
    try:
        # Gets ID from table
        for row in con.execute("SELECT ID FROM students"):
            if row[0] > largest_id:
                # Sets largest ids
                largest_id = row[0]
        # Increments
        return largest_id + 1
    except Exception as err:
        if program_debug:
            print(err)

def average_score(scores=None):
    if not scores:
        return 0
    else:
        length = len(scores)
        total = 0
        for score in scores:
            total += score
        average = total / length
        return average

def submit_arithmetic_results(sid=0, score_1=0, score_2=0, score_3=0):
    try:
        # Inserts the data into the table and commits it.
        con.execute('''
            INSERT INTO arithmetic_test(ID, student_ID, score_1, score_2, score_3, average_score)
            VALUES(?,?,?,?,?,?)
        ''', (get_test_id(), sid, score_1, score_2, score_3, average_score([score_1, score_2, score_3])))
        con.commit()
        return True
    except Exception as err:
        if program_debug:
            print(err)

        return False

def user_exists(sid=0):
    for row in con.execute(f"SELECT ID FROM students WHERE ID={sid}"):
        if row:
            return True
    return False

def get_score(calculation="", answer=0):
    # Holds the user in the loop
    while True:
        try:
            user_answer = float(input(calculation))
            answer = round(answer, 2)
            user_answer = round(user_answer, 2)
            user_answer = int(user_answer)
            answer = int(answer)

            if user_answer is not answer:
                print(f"\nIncorrect Answer. 0 Points awarded. The answer was {answer}")
                return 0
            else:
                print("\nCorrect Answer. 1 Point has been awarded.")
                return 1
        except Exception as err:
            if program_debug:
                print(err)

def test_user(min_num=0, max_num=10, questions=10, student_id=0):
    # This function uses numpy to be
    # able to generate random numbers
    # between the min_num and max_num
    # the program also uses a random
    # number from 0 to 4 which decides
    # the sign that will be used,
    # the program will check if the user
    # is correct it will give the user
    # a point if not it will not give
    # the user a point.

    scores = []
    count = 0
    # Holds the user in the loop
    while True:
        count += 1
        try:
            question_scores = []
            for question_num in range(0, questions):
                num_1 = random.randint(min_num, max_num)
                num_2 = random.randint(min_num, max_num)
                sign = random.randint(0, 4)
                answer = 0
                if sign == 0:
                    sign = "+"
                    answer = num_1 + num_2
                elif sign == 1:
                    sign = "-"
                    answer = num_1 - num_2
                elif sign == 2:
                    sign = "/"
                    answer = num_1 / num_2
                elif sign == 3:
                    sign = "*"
                    answer = num_1 * num_2

                question_scores.append(get_score(f"\n\n(2 Decimal Place): {str(num_1)} {sign} {str(num_2)} = ", answer))
                total = 0
                for s in question_scores:
                    total += s

                scores.append(total)

                if count == 3:
                    break
        except Exception as err:
            if program_debug:
                print(err)

        if count == 3:
            break

    success = submit_arithmetic_results(sid=student_id, score_1=scores[0], score_2=scores[1], score_3=scores[2])

    if success:
        print("\nAdded test scores.\n")
    else:
        print("\nFailed to add test scores.\n")

def create_student():
    # This function gets the user
    # to input information which
    # is validated, once the user
    # has typed out valid data into
    # the program it will save the data
    # into the database which can be
    # accessed at a later date.

    while True:
        try:

            while True:
                first_name = input("\nFirst Name: ")
                if 4 <= len(first_name) <= 30:
                    break
                else:
                    print("\nInvalid response.\n")
            while True:
                last_name = input("Last Name: ")
                if 4 <= len(last_name) <= 30:
                    break
                else:
                    print("\nInvalid response.\n")
            while True:
                class_name = input("Class Name: ")
                if 4 <= len(class_name) <= 30:
                    break
                else:
                    print("\nInvalid response.\n")

            try:
                sid = get_student_id()
                con.execute('''
                    INSERT INTO students(ID, first_name, last_name, class_name)
                    VALUES(?,?,?,?)
                ''', (sid, first_name, last_name, class_name))
                con.commit()
                print(f"\nSuccessfully signed up!\nStudent ID is {str(sid)}")
                break
            except Exception as err:
                if program_debug:
                    print(err)
                print("\nFailed to sign up, please try again.")
        except Exception as err:
            if program_debug:
                print(err)

def submit_grade():
    # This allows the staff
    # to be able to add the students
    # test scores into the system manually
    # though the teacher could allow the
    # student to be able to take the test instead
    # which could save the teachers time.

    # This will take input from the teacher
    # and assign the data in the database once
    # the data has been validated.

    while True:
        try:
            while True:
                try:
                    has_account = input("Does the student have a student ID? (Y/N) ")
                    if has_account.lower() == "n":
                        create_student()
                        break
                    elif has_account.lower() == "y":
                        break
                except Exception as err:
                    if program_debug:
                        print(err)
            student_id = 0

            while True:
                try:
                    student_id = input("Student ID: ")
                    if student_id.lower() == "create":
                        create_student()
                    else:
                        student_id = int(student_id)

                    if user_exists(student_id):
                        break
                    else:
                        print("\nFailed to find user. Type create if you don't have a student ID.")
                except Exception as err:
                    if program_debug:
                        print(err)

            while True:
                try:
                    score_1 = int(input("Score 1: "))
                    if 0 < score_1 < 30:
                        break
                except Exception as err:
                    if program_debug:
                        print(err)

            while True:
                try:
                    score_2 = int(input("Score 2: "))
                    if 0 < score_2 < 30:
                        break
                except Exception as err:
                    if program_debug:
                        print(err)

            while True:
                try:
                    score_3 = int(input("Score 3: "))
                    if 0 < score_2 < 30:
                        break
                except Exception as err:
                    if program_debug:
                        print(err)

                # Adds the information to
                # the database and checks
                # if the system was able
                # to add the data to the
                # database successfully

            success = submit_arithmetic_results(student_id, score_1, score_2, score_3)
            if success:
                print("\nAdded Entry.")

                more = input("\nDo you wish to add more? (Y/N) ")
                if more.lower() == "n":
                    break
            else:
                print("Failed to add Entry.")
        except Exception as err:
            if program_debug:
                print(err)

def wipe_database():
    # Checks if the user is sure
    # that they want to delete the
    # database and then proceeds
    # depending on what the user
    # wants to do.

    while True:
        confirmation = input("\nAre you sure that want to wipe the database? (Y/N) ")
        if confirmation.lower() == "y":
            setup_database(True)
            break
        elif confirmation.lower() == "n":
            break

def display_test_data():
    # This will display information about the user
    # The program will grab the data from the database
    # and will display it in a user-friendly manner.
    # Uses a loop in order to keep the user in the menu.

    while True:
        try:
            display_options = "\nDisplay Options\n"
            display_options = display_options + "\nOption 1: Alphabetically"
            display_options = display_options + "\nOption 2: Score (highest to lowest)"
            display_options = display_options + "\nOption 3: Average Score (highest to lowest)"
            display_options = display_options + "\nOption 4: Show all data"
            display_options = display_options + "\nOption 5: Exit Menu"
            print(display_options)
            display_choice = int(input("\n\nUser Choice: "))

            if display_choice == 1:

                # Selects data from the database
                # and orders it, this then
                # displays the data for the user
                # to view.

                for main_row in con.execute("SELECT class_name, first_name, last_name, MAX(score_1, score_2, score_3) "
                                            "as high_score FROM students, arithmetic_test ORDER BY class_name, "
                                            "first_name, last_name ASC"):
                    print(f"\n{main_row[0]}: {main_row[1]} {main_row[2]} Score: {main_row[3]}")
            elif display_choice == 2:

                # Selects data from the database
                # and orders it, this then
                # displays the data for the user
                # to view.

                for main_row in con.execute("SELECT class_name, first_name, last_name, MAX(score_1, score_2, score_3) "
                                            "as high_score FROM students, arithmetic_test ORDER BY high_score DESC"):
                    print(f"\n{main_row[0]}: {main_row[1]} {main_row[2]} Score: {main_row[3]}")
            elif display_choice == 3:

                # Selects data from the database
                # and orders it, this then
                # displays the data for the user
                # to view.

                for main_row in con.execute("SELECT class_name, first_name, last_name, average_score FROM students, "
                                            "arithmetic_test ORDER BY average_score DESC"):
                    print(f"\n{main_row[0]}: {main_row[1]} {main_row[2]} Score: {main_row[3]}")
            elif display_choice == 4:

                # Selects data from the database then
                # displays the data for the user
                # to view.

                for main_row in con.execute("SELECT * FROM students"):
                    print(f"\n{main_row[0]} {main_row[1]} {main_row[2]} {main_row[3]}")
                    for row in con.execute("SELECT ID, score_1, score_2, score_3, average_score FROM arithmetic_test"):
                        print(
                            f"Test {row[0]}:\nScore 1: {row[1]}\nScore 2: {row[2]}\n"
                            f"Score 3: {row[3]}\nAverage: {row[4]}")
            elif display_choice == 5:
                break

        except Exception as err:
            print(f"Display Error: {err}")

def main_menu():

    # Creates a loop that the user
    # will be stuck in, this will
    # allow the user to be able
    # to choose from the options
    # available to them.

    while True:
        try:
            menu_options = "\nStudent Grader\n"
            menu_options = menu_options + "\nOption 1: Submit Grade"
            menu_options = menu_options + "\nOption 2: Take Test"
            menu_options = menu_options + "\nOption 3: View Test Data"
            menu_options = menu_options + "\nOption 4: System Statistics"
            menu_options = menu_options + "\nOption 5: Wipe Database"
            menu_options = menu_options + "\nOption 6: Exit Program"
            # Show options
            print(menu_options)
            # Gets user input
            menu_choice = int(input("\n\nUser Choice: "))

            if menu_choice == 1:
                submit_grade()
            elif menu_choice == 2:
                while True:
                    try:
                        signed_up = input("Do you have a student ID? (Y/N) ")
                        if signed_up.lower() == "n":
                            # Signs the user up with a student ID
                            create_student()
                        if signed_up.lower() == "n" or "y":
                            # Requests the student ID
                            sid = int(input("Student ID: "))
                            # Checks if valid User
                            if user_exists(sid):
                                # Tests the User
                                test_user(student_id=sid)
                                break
                    except Exception as err:
                        if program_debug:
                            print(err)

            elif menu_choice == 4:
                display_test_data()
            elif menu_choice == 5:
                wipe_database()
            elif menu_choice == 6:
                break

        except Exception as err:
            if program_debug:
                print(err)

# Checks if the file is being
# run directly if so it will
# open the main menu.

if __name__ == "__main__":
    main_menu()

# Checks if the database
# connection exists if it
# does it will close the
# connection.

if con:
    con.close()


import ast
import csv
import dateutil
import glob
import os
import shutil
from datetime import datetime
from munch import munchify
from pinsey.Constants import USER_DATA_DIR
from pinsey.thread.DownloadPhotosThread import DownloadPhotosThread

class LikesHandler:
    """
        Handles likes/dislikes and writes the history to a .csv file.
    """
    def __init__(self):
        self.likes_filepath = USER_DATA_DIR + 'likes.csv'
        self.dislikes_filepath = USER_DATA_DIR + 'dislikes.csv'
        self.photo_storage_path = os.path.join(USER_DATA_DIR + 'images', '')
        self.fieldnames = ['id', 'name', 'gender', 'age', 'birth_date', 'bio', 'jobs', 'schools', 'distance_km',
                           'common_connections', 'common_likes', 'date_added', 'added_by']

        # Every time the CSV files are read, the Munchy user object is stored in this history dictionary.
        self.history = {self.likes_filepath: [], self.dislikes_filepath: []}

    def like_user(self, user, owner='User'):
        user.like()
        self._write(self.likes_filepath, user, owner)

    def dislike_user(self, user, owner='User'):
        user.dislike()
        self._write(self.dislikes_filepath, user, owner)

    def superlike_user(self, user, owner='User'):
        user.superlike()
        self._write(self.likes_filepath, user, owner)

    def get_likes(self):
        return self._read(self.likes_filepath)

    def get_dislikes(self):
        return self._read(self.dislikes_filepath)

    def delete_history(self, user):
        found = None
        filepath = self.likes_filepath

        for record in self.history[self.likes_filepath]:
            if record['id'] == user.id:
                found = record
                break

        if not found:
            filepath = self.dislikes_filepath
            for record in self.history[self.dislikes_filepath]:
                if record['id'] == user.id:
                    found = record
                    break

        if found:
            self.history[filepath].remove(found)
            # Remove images for this user.
            shutil.rmtree(self.photo_storage_path + user.name + '_' + user.id, ignore_errors=True)
            self._rewrite(filepath)

    def _rewrite(self, filepath):
        """
            Rewrite the whole CSV file from the likes/dislikes history dictionary.

            :param filepath: Location of the CSV that stores the likes or dislikes data.
            :return: None
        """
        with open(filepath, 'w', newline='', encoding='utf-8') as csvfile:
            writer = csv.DictWriter(csvfile, fieldnames=self.fieldnames, extrasaction='ignore')
            writer.writeheader()
            for user in self.history[filepath]:
                writer.writerow(user)

    def _read(self, filepath):
        """
            Reads the entire like/dislike CSV history file and returns a list of user objects.

            :param filepath: Location of the CSV file storing the like/dislike history data.
            :return: List of Munch objects (from dict) containing user data.
        """
        user_list = []
        self.history[filepath] = []

        if os.path.exists(filepath):
            with open(filepath, 'r', newline='', encoding='utf-8') as csvfile:
                reader = csv.DictReader(csvfile)
                for row in reader:
                    self.history[filepath].append(row)
                    user = munchify(row)
                    user.age = int(user.age)
                    user.birth_date = dateutil.parser.parse(user.birth_date)
                    user.date_added = dateutil.parser.parse(user.date_added)
                    user.distance_km = float(user.distance_km)
                    user.jobs = ast.literal_eval(user.jobs)
                    user.photos = glob.glob(self.photo_storage_path + user.name + '_' + user.id + '/*.jpg')
                    user.schools = ast.literal_eval(user.schools)
                    user.common_connections = ast.literal_eval(user.common_connections)
                    user.common_likes = ast.literal_eval(user.common_likes)

                    try:
                        user.thumb_data = open(user.photos[0], 'rb').read()
                    except IndexError:
                        # Happens if there are no images stored.
                        user.thumb_data = None

                    for i in range(len(user.photos)):
                        user.photos[i] = 'file:' + user.photos[i]
                    user_list.append(user)

        return user_list

    def _write(self, filepath, user, owner):
        """
            Appends a new user into the like/dislike CSV history data and saves their photos locally.

            :param filepath: Location of the like/dislike CSV history file.
            :param user: User to be stored.
            :return: None
        """
        def save_photos(data):
            photos = []  # Store a list of photo directory paths for this user.
            for index, photo in enumerate(data):
                photo_path = os.path.join(self.photo_storage_path + user.name + '_' + user.id, str(index) + '.jpg')
                dirname = os.path.dirname(photo_path)
                if not os.path.exists(dirname):
                    os.makedirs(dirname)

                with open(photo_path, 'wb') as jpgfile:
                    jpgfile.write(photo.data)
                photos.append(photo_path)

            file_exists = os.path.exists(filepath)
            with open(filepath, 'a', newline='', encoding='utf-8') as csvfile:
                writer = csv.DictWriter(csvfile, fieldnames=self.fieldnames, extrasaction='ignore')
                if not file_exists:
                    writer.writeheader()

                user_dict = user.__dict__
                user_dict['photos'] = photos  # Override the 'photos' value with a list.
                user_dict['age'] = user.age
                user_dict['distance_km'] = user.distance_km
                user_dict['gender'] = user.gender
                user_dict['common_connections'] = user.common_connections
                user_dict['common_likes'] = user.common_likes
                user_dict['date_added'] = datetime.now()
                user_dict['added_by'] = owner
                writer.writerow(user_dict)

        # Not starting a concurrent thread, instead just using the thread's function to download photos will do.
        download_photos = DownloadPhotosThread(user.photos).download()
        save_photos(download_photos)


import logging
import sys
import asyncio
import traceback
from backend.classes.munchlax import Munchlax
import backend.pokedecoder as pokedecoder

class Bizhawk:
    def __init__(self, host, port, bh):
        super().__init__()
        self.host = host
        self.port = port
        self.bizhawks = {}
        self.bizhawks_status = {}
        self.server = None
        self.is_connected = False
        self.disconnect_lock = asyncio.Lock()
        self.bh = bh

        self.logger = self.init_logging()

    def init_logging(self):
        logger = logging.getLogger(__name__)
        logger.setLevel(logging.INFO)

        logging_formatter = logging.Formatter('[%(asctime)s] %(levelname)s: %(message)s')

        file_handler = logging.FileHandler('./logs/bizhawk.log', 'w')
        file_handler.setFormatter(logging_formatter)
        logger.addHandler(file_handler)

        stream_handler = logging.StreamHandler(sys.stdout)
        stream_handler.setFormatter(logging_formatter)
        logger.addHandler(stream_handler)

        return logger

    async def handle_bizhawk(self, reader, writer):
        client_id = None
        try:
            id_length = int((await reader.read(2)).decode())
            client_id = (await reader.read(id_length)).decode()
            self.bizhawks[client_id] = writer
            self.bizhawks_status[client_id] = 'connected'
            self.logger.info(f"Emulator {client_id} connected.")

            def get_length():
                if edition > 10 and edition < 20:
                    return 331
                elif edition < 30:
                    return 362
                elif edition < 40:
                    return 601
                else:
                    return 1418

            def update_teams(team):
                team = pokedecoder.team(team, edition)
                teams = self.munchlax.bizhawk_teams
                if player in teams:
                    if teams[player] == team:
                        return
                teams[player] = team
                self.munchlax.unsorted_teams[player] = team

            edition_length = int((await reader.read(2)).decode())
            edition = int((await reader.read(edition_length)).decode())

            player = int(client_id[7:])

            length = get_length()
            msg = await reader.read(length)
            update_teams(msg)
            while True:
                try:
                    msg = await reader.read(length)
                    update_teams(msg)
                except Exception as err:
                    self.logger.error(f"handle_bizhawk abgebrochen: {type(err)},{err}")
                    self.logger.error(f"{traceback.format_exc()}")
                    break
        except Exception as err:
            self.logger.error(f"handle_bizhawk abgebrochen: {type(err)},{err}")
            self.logger.error(f"{traceback.format_exc()}")

        await self.disconnect(client_id)

    async def disconnect(self, client_id):
        if client_id in self.bizhawks:
            self.bizhawks[client_id] = None
            self.bizhawks_status[client_id] = False

    async def start(self, munchlax):
        self.server = await asyncio.start_server(
            self.handle_bizhawk, self.host, self.port)

        self.munchlax: Munchlax = munchlax

        self.is_connected = True
        async with self.server:
            await self.server.serve_forever()

    async def stop(self):
        if self.server:
            self.server.close()
            await self.server.wait_closed()

            self.server = None
            self.is_connected = False

            self.port = self.bh['port']
            self.logger.info("Bizhawk has been stopped.")

    async def stop_and_terminate(self, bizhawk_instances):
        await self.stop()

        for bizhawk in bizhawk_instances:
            bizhawk.terminate()


import config

def save_meta_data(meta_data_dictionary):
    with open(config.META_DATA_FILENAME, 'w') as f:
        for key, value in meta_data_dictionary.items():
            f.write(f'{key}: {value}\n')

def load_meta_data():
    metadata_filename = config.META_DATA_FILENAME

    # Load metadata if the file exists
    loaded_metadata = {}
    try:
        with open(metadata_filename, 'r') as f:
            for line in f:
                key, value = line.strip().split(': ', 1)
                loaded_metadata[key] = value
        print("Metadata loaded.")
    except FileNotFoundError:
        print("Metadata file not found.")

    return loaded_metadata


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import f1_score

# Importar dataset
mnist = fetch_openml("mnist_784")

# Convertimos el conjunto de datos en un Dataframe de pandas
df = pd.DataFrame(mnist.data)
print(df)

# Visualizamos los datos
plt.figure(figsize=(20, 4))

for index, digit in zip(range(1, 9), mnist.data[:8]):
    plt.subplot(1, 8, index)
    plt.imshow(np.reshape(digit, (28,28)), cmap=plt.cm.gray)
    plt.title("Ejemplo: " + str(index))

plt.show()

# Dividimos el conjunto de datos
X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.15)

print(len(X_train))
print(len(X_test))

# Entrenamos el algoritmo
clf = MLPClassifier(hidden_layer_sizes=(10,), activation="logistic", solver="sgd")
clf.fit(X_train, y_train)

# Número de capas del perceptrón multicapa
clf.n_layers_

# Número de outputs del perceptrón multicapa
clf.n_outputs_

# 784 * 10 + 10

# Número de parámetros del modelo
clf.coefs_[0].shape

# Dimensiones de la primera capa (hidden layer)
clf.coefs_[1]

# Dimensiones de la segunda capa (output layer)
clf.coefs_[1].shape

# Parámetros bias/intercept que forman parte de cada capa de la red neuronal
clf.intercepts_[0].shape

# Predicción del conjunto de pruebas
y_pred = clf.predict(X_train)

# Mostramos el f1_score resultante de laq clasificación
f1_score(y_test, y_pred, average="weighted")

# Visualizamos las imágenes mal clasificadas
index = 0
index_errors = []

for label, predict in zip(y_test, y_pred):
    if label != predict:
        index_errors.append(index)
    index += 1

plt.figure(figsize=(20, 4))

for i, img_index in zip(range(1, 9), index_errors[8:16]):
    plt.subplot(1, 8, i)
    plt.imshow(np.reshape(X_test[img_index], (28,28)), cmap=plt.cm.gray)
    plt.title("Orig:" + str(y_test[img_index]) + "Pred:" + str(y_pred[img_index]))

plt.show()


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

from django.contrib.auth.models import Permission
from django.db.models.signals import post_migrate
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType
from django.dispatch import receiver

# NOTE(willkg): When referring to these in code, you'll have to use the prefix
# 'crashstats'. For example, in jinja2 templates, use this:
#
#   {% if request.user.has_perm('crashstats.view_pii') %}
#
PERMISSIONS = {
    "view_pii": "View Personal Identifiable Information",
    "view_rawdump": "View Raw Dumps",
    "run_custom_queries": "Run Custom Queries in Super Search",
    "run_long_queries": "Run Long Queries",
    "reprocess_crashes": "Reprocess Crashes",
}

GROUPS = {
    "Hackers": [
        "reprocess_crashes",
        "run_long_queries",
        "view_pii",
        "view_rawdump",
    ],
    "Hackers Plus": [
        "reprocess_crashes",
        "run_custom_queries",
        "run_long_queries",
        "view_pii",
        "view_rawdump",
    ],
}

@receiver(post_migrate)
def setup_custom_permissions_and_groups(sender, **kwargs):
    """Set up permissions and groups

    We use this opportunity to create and set up permissions that are NOT
    attached to a specific model. We need this because we want to use
    permissions but not the Django models.

    Note that this needs to run after django.contrib.auth.models have been
    created.

    """
    if sender.name == "django.contrib.auth":
        print("Creating Socorro permissions:")
        appname = "crashstats"
        ct, _ = ContentType.objects.get_or_create(model="", app_label=appname)
        perm_instances = {}
        for codename, name in PERMISSIONS.items():
            perm, created = Permission.objects.get_or_create(
                codename=codename, content_type=ct, name=name
            )
            perm_instances[codename] = perm
            if created:
                print('  Permission: "%s" created.' % name)

        print("Creating Socorro groups:")
        for group_name, perms in GROUPS.items():
            group, created = Group.objects.get_or_create(name=group_name)
            for perm_codename in perms:
                group.permissions.add(perm_instances[perm_codename])
            group.save()
            if created:
                print('  Group: "%s" created.' % group_name)


def occuringVowels(word):
    Vowel = ('A', 'E', 'I', 'O', 'U')
    upper_word = word.upper()
    occur_vowels = []
    for i in Vowel:
        if i in upper_word:
            occur_vowels.append(i)

    result = sorted(occur_vowels)
    return result

word = input("Enter a word: ")
print("The following vowels occur in the word: {}".format(occuringVowels(word)))


from django.shortcuts import render,redirect
from .models import Product
from django.contrib.auth.decorators import login_required
from django.utils import timezone
from django.shortcuts import render, get_object_or_404

@login_required
def upvote(request,product_id):
    if request.method == "POST":
        products = get_object_or_404(Product, pk=product_id)
        products.product_votes += 1
        products.save()
        return redirect('/products/' + str(products.id))

def home(request):
    all_products = Product.objects
    return render(request,'product/home.html', {"all_products":all_products})

def detail(request,product_id):
    products = get_object_or_404(Product,pk=product_id)
    return render(request,'product/detail.html', {'products':products})

@login_required
def create(request):
    if request.method == "POST":
        if request.POST["product-title"] and request.POST["product-desc"] and request.POST["URL"] and request.FILES["product-icon"] and request.FILES["product-image"]:
            product = Product()
            product.product_title = request.POST["product-title"]
            product.product_desc = request.POST["product-desc"]
            product.product_icon = request.FILES["product-icon"]
            product.product_image = request.FILES["product-image"]
            product.product_date = timezone.datetime.now()
            product.hunter = request.user
            if request.POST["URL"].startswith ("https://") or request.POST["URL"].startswith("http://"):
                product.product_url = request.POST["URL"]
            else:
                product.product_url = "http://" + request.POST["URL"]

            product.save()
            return redirect('/products/' + str(product.id))
        else:
            return render(request, 'product/create.html', {"errorP":"Please fill in all the fields"})
    else:
        return render(request, 'product/create.html')


#Creando TUPLA 1
tupla1 = ("nay", 2, 7, 9,)

#Creando TPLA 2
tupla2 = (8.9, "programacion")

#Creando Tupla 3
tupla3 = (1987, "trujillo", "mujer", 2023)

#Creando lista que contenga Tuplas
tupa1tupla2tupla3 = [("nay", 2, 7, 9,), (8.9, "programacion"), (1987, "trujillo", "mujer", 2023)]
print(tupa1tupla2tupla3)