import argparse

import cv2  # type: ignore
import mediapipe  # type: ignore
import numpy as np  # type: ignore

from rosny import CommonState, ThreadStream, ComposeStream

parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", default=0,
                    help="Source of video. Defaults to webcam.")
args = parser.parse_args()

class State(CommonState):
    def __init__(self):
        super(State, self).__init__()
        self.image = None
        self.selfie_output = None

class VideoStream(ThreadStream):
    def __init__(self, source=0):
        self.video = cv2.VideoCapture(source)
        self.fps = self.video.get(cv2.CAP_PROP_FPS)
        super().__init__(loop_rate=self.fps, profile_interval=5)

    def work(self):
        success, image = self.video.read()
        if success:
            image = cv2.flip(image, 1)
            self.common_state.image = image
        else:
            self.common_state.set_exit()

    def on_join_end(self):
        self.video.release()

class SelfieSegmentationStream(ThreadStream):
    def __init__(self, loop_rate):
        super().__init__(loop_rate=loop_rate, profile_interval=5)
        self.selfie_segmentation = mediapipe.solutions\
            .selfie_segmentation.SelfieSegmentation(model_selection=1)

    def work(self):
        image = self.common_state.image
        if image is not None:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            image.flags.writeable = False
            output = self.selfie_segmentation.process(image)
            self.common_state.selfie_output = output

class VisualizeStream(ThreadStream):
    def __init__(self, loop_rate):
        super().__init__(loop_rate=loop_rate, profile_interval=5)

    def work(self):
        image = self.common_state.image
        output = self.common_state.selfie_output
        if image is not None and output is not None:
            condition = np.stack((output.segmentation_mask,) * 3, axis=-1) > 0.1
            bg_image = np.zeros(image.shape, dtype=np.uint8)
            bg_image[:] = (192, 192, 192)
            output_image = np.where(condition, image, bg_image)
            cv2.imshow('MediaPipe Selfie Segmentation', output_image)
            if cv2.waitKey(1) & 0xFF == 27:
                self.common_state.set_exit()

class MainStream(ComposeStream):
    def __init__(self, source):
        super().__init__()
        self.video_stream = VideoStream(source)
        self.selfie_stream = SelfieSegmentationStream(self.video_stream.fps)
        self.visualize_stream = VisualizeStream(self.video_stream.fps)
        self.compile(common_state=State())  # Share custom common_state between streams

if __name__ == "__main__":
    stream = MainStream(args.input)
    stream.start()
    stream.wait()
    stream.stop()
    stream.join()


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

"""
The use case of this script is the following:
	Add a keyword to the genre list in plex if the keyword is present in the keyword list of the media on the IMDB
Requirements (python3 -m pip install [requirement]):
	requests
Setup:
	Fill the variables below firstly, then run the script with -h to see the arguments that you need to give.
"""

plex_ip = ''
plex_port = ''
plex_api_token = ''

from os import getenv
from re import findall as re_findall
from fnmatch import filter as fnmatch_filter

# Environmental Variables
plex_ip = getenv('plex_ip', plex_ip)
plex_port = getenv('plex_port', plex_port)
plex_api_token = getenv('plex_api_token', plex_api_token)
base_url = f"http://{plex_ip}:{plex_port}"

def keywords_to_genre(ssn, keywords: list, library_names: list, movie_names: list=[], series_names: list=[], skip_locked: bool=False):
	result_json = []

	for library_name in library_names:
		#find library
		sections = ssn.get(f'{base_url}/library/sections').json()['MediaContainer']['Directory']
		lib_id, lib_type = next(iter([[lib['key'],lib['type']] for lib in sections if lib['title'] == library_name]), ['',''])
		if not lib_id: return 'Library not found'

		#check for illegal arg parsing
		if lib_type == 'movie' and series_names: return 'Library is a movie library but "series_names" is set'
		elif lib_type == 'show' and movie_names: return 'Library is a show library but "movie_names" is set'
		elif not lib_type in ('movie','show'): return 'Invalid library type'

		#go through every entry in the library
		lib_output = ssn.get(f'{base_url}/library/sections/{lib_id}/all', params={'includeGuids': '1'}).json()['MediaContainer']['Metadata']
		for media in lib_output:
			#skip if media is not selected
			if (movie_names and not media['title'] in movie_names) or (series_names and not media['title'] in series_names): continue

			media_output = ssn.get(f'{base_url}/library/metadata/{media["ratingKey"]}').json()['MediaContainer']['Metadata'][0]
			#skip if genre field is locked and skip_locked is True
			if skip_locked == True and [l for l in media_output.get('Field', []) if l['name'] == 'genre' and l['locked'] == True]: continue

			#find imdb id of media otherwise skip
			media_guid = next(iter([guid['id'].split('/')[-1] for guid in media.get('Guid',[]) if guid['id'].startswith('imdb://')]), '')
			if not media_guid: continue

			#get all genres that media has been tagged with
			media_genres = [g['tag'] for g in media_output.get('Genre', [])]

			#get all keywords that media has on imdb
			media_info = ssn.get(f'https://www.imdb.com/title/{media_guid}/keywords').text
			media_keywords = re_findall(r'(?<=data-item-keyword=").*?(?=")', media_info)

			#go through every target keyword and if it's in the list (but not already in the genre list), add it to the genres
			new_genres = []
			for k in keywords:
				if '*' in k:
					result = fnmatch_filter(media_keywords, k)
					new_genres += [r for r in result if not r in media_genres]
				else:
					if k in media_keywords and not k in media_genres:
						new_genres.append(k)

			#upload new genres
			payload = {
				'type': '2' if media['type'] == 'show' else '1',
				'id': media['ratingKey'],
				'genre.locked': '1',
				**{f'genre[{c}].tag.tag': v for c, v in enumerate(media_genres + new_genres)}
			}
			ssn.put(f'{base_url}/library/sections/{lib_id}/all', params=payload)

			result_json.append(media['ratingKey'])

	return result_json

if __name__ == '__main__':
	import requests, argparse

	#setup vars
	ssn = requests.Session()
	ssn.headers.update({'Accept': 'application/json'})
	ssn.params.update({'X-Plex-Token': plex_api_token})

	#setup arg parsing
	parser = argparse.ArgumentParser(description='Add a keyword to the genre list in plex if the keyword is present in the keyword list of the media on the IMDB')
	parser.add_argument('-k','--Keyword', type=str, help='Keyword that will be added to genre list if found in keyword list; allowed to give multiple times; supports wildcards (*)', action='append', required=True)
	parser.add_argument('-l','--LibraryName', type=str, help='Name of target library; allowed to give multiple times', action='append', required=True)
	parser.add_argument('-m','--MovieName', type=str, help='Name of target movie; allowed to give multiple times (requires -l to be a movie library)', action='append', default=[])
	parser.add_argument('-s','--SeriesName', type=str, help='Name of target series; allowed to give multiple times (requires -l to be a show library)', action='append', default=[])
	parser.add_argument('-S','--SkipLocked', help='Skip media that has it\'s genre field locked', action='store_true')

	args = parser.parse_args()
	#call function and process result
	response = keywords_to_genre(ssn=ssn, keywords=args.Keyword, library_names=args.LibraryName, movie_names=args.MovieName, series_names=args.SeriesName, skip_locked=args.SkipLocked)
	if not isinstance(response, list):
		if response == 'Library is a movie library but "series_names" is set':
			parser.error('Library is a movie library but -s/--SeriesName is set')
		elif response == 'Library is a show library but "movie_names" is set':
			parser.error('Library is a show library but -m/--MovieName is set')
		else:
			parser.error(response)


from rest_framework import generics, status
from .models import User
from .serializers import NormalUserSerializer, AdminManageUserSerializer
from rest_framework_simplejwt.authentication import JWTAuthentication
from .permissions import IsAdminUser, IsAccountOwnerOrAdminUser
from drf_spectacular.utils import extend_schema
from rest_framework.views import Response
from django.db import IntegrityError

class NormalUserView(generics.CreateAPIView):
    """
    Registro de usuários
    """
    queryset = User.objects.all()
    serializer_class = NormalUserSerializer

    @extend_schema(
        operation_id="users_post",
        description="Rota de criação de usuário. Não requer autenticação.",
        summary="Criar usuário",
    )
    def post(self, request, *args, **kwargs):
        return super().create(request, *args, **kwargs)

class AdminUserView(generics.CreateAPIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAdminUser]

    queryset = User.objects.all()
    serializer_class = AdminManageUserSerializer

    @extend_schema(
        operation_id="users_post_admin",
        description="Rota de criação de usuário administrador. Requer autenticação de administrador.",
        summary="Criar usuário administrador",
    )
    def post(self, request, *args, **kwargs):
        return super().post(request, *args, **kwargs)

class UserDetailView(generics.RetrieveUpdateDestroyAPIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAccountOwnerOrAdminUser]

    queryset = User.objects.all()
    serializer_class = NormalUserSerializer

    @extend_schema(
        operation_id="users_get_id",
        description="Rota de listagem de usuário. Requer autenticação do próprio usuário ou um administrador.",
        summary="Listar usuário",
    )
    def get(self, request, *args, **kwargs):
        return super().get(request, *args, **kwargs)

    @extend_schema(operation_id="users_put_id", exclude=True)
    def put(self, request, *args, **kwargs):
        return super().put(request, *args, **kwargs)

    @extend_schema(
        operation_id="users_patch_id",
        description="Rota de atualização de usuário. Requer autenticação do próprio usuário ou um administrador.",
        summary="Atualizar usuário",
    )
    def patch(self, request, *args, **kwargs):
        instance = self.get_object()

        data = request.data
        for key, value in data.items():
            setattr(instance, key, value)
        try:
            instance.save()
        except IntegrityError as e:
            if 'unique constraint' in str(e):
                return Response({'error': 'Email already exists.'}, status=status.HTTP_400_BAD_REQUEST)
            else:
                return Response({'error': 'An error occurred while saving data.'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        serializer = self.get_serializer(instance)
        return Response (serializer.data)

    @extend_schema(
        operation_id="users_delete_id",
        description="Rota de deleção de usuário. Requer autenticação do próprio usuário ou um administrador.",
        summary="Deletar usuário",
    )
    def delete(self, request, *args, **kwargs):
        return super().delete(request, *args, **kwargs)


import unittest
import json
import requests

class TestGUIDHandler(unittest.TestCase):
    base_url = 'http://localhost:8888/guid/'

    def test_post_guid(self):
        data = {'user': 'New User', 'expire': '1654070400'}
        headers = {'Content-Type': 'application/json'}
        response = requests.post(self.base_url, data=json.dumps(data), headers=headers)
        self.assertEqual(response.status_code, 200)
        document = response.json()
        self.assertIn('guid', document)
        self.assertEqual(document['user'], 'New User')
        self.assertEqual(document['expire'], 1654070400)

    def test_get_guid(self):
        response = requests.get(self.base_url + '9094E4C980C74043A4B586B420E69DDF')
        self.assertEqual(response.status_code, 200)
        document = response.json()
        self.assertIn('guid', document)
        self.assertIn('user', document)
        self.assertIn('expire', document)

    def test_put_guid(self):
        data = {'user': 'Updated User', 'expire': '1654070400'}
        headers = {'Content-Type': 'application/json'}
        response = requests.put(self.base_url + '9094E4C980C74043A4B586B420E69DDF', data=json.dumps(data), headers=headers)
        self.assertEqual(response.status_code, 200)
        document = response.json()
        self.assertIn('guid', document)
        self.assertEqual(document['user'], 'Updated User')
        self.assertEqual(document['expire'], 1654070400)

    def test_delete_guid(self):
        response = requests.delete(self.base_url + '9094E4C980C74043A4B586B420E69DDF')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.text, 'successfully deleted')

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


def unique(list1):
    unique_list = []
    for x in list1:
        if x not in unique_list:
            unique_list.append(x)
    return unique_list

def convert_coordinates(a):
    a=np.array(a)
    x,y=[],[]
    for b in a:
        x.append(b[0])
        y.append(b[1])
    return x,y

def get_grid_size(a):
    x,y = convert_coordinates(a)
    return len(unique(x)), len(unique(y))

def get_zigzag_path(grid):
    X_DIM, Y_DIM =get_grid_size(grid)

    x,y=convert_coordinates(grid)

    min_x=min(x)
    max_x=max(x)

    min_y=min(y)
    max_y=max(y)

    nx=np.linspace(min_x,max_x,X_DIM)
    ny=np.linspace(min_y,max_y,Y_DIM)
    zr=np.meshgrid(nx,ny)

    new_coords=[]
    coord=()
    counter=0

    for i in range(Y_DIM):
        for j in range(X_DIM):

            for g in range(len(grid)):
                if i%2==0:
                    nj=j
                else:
                    nj=X_DIM-j-1

                if (grid[g][0] == int(zr[0][i][nj])) and (grid[g][1] == int(zr[1][i][nj])):
                    coord=[int(zr[0][i][nj]),int(zr[1][i][nj])]
                    #coord=[a[g][0],a[g][1]]
                    new_coords.append(coord)
                    coord=[]
                counter+=1

    print(get_grid_size(grid))
    return new_coords

def get_waypoints(field, grid, drones_inits,step):
    #print(grid)
    z=get_zigzag_path(grid)
    #print(grid)
    a=z[len(z)//2:]
    b=z[:len(z)//2]
    print(a)
    print(b)
    a = [drones_inits[0]]*40+find_way_to(drones_inits[0],a[0],grid,step)+a[:-1]+find_way_to(a[-1],drones_inits[0],grid,step)
    b = find_way_to(drones_inits[1],b[0],grid,step)+b[:-1]+find_way_to(b[-1],drones_inits[1],grid,step)
    print(a)
    print(b)
    print(grid)
    return [
        a,b
    ]

def check_waypoints(a,b):
    for i in range(len(a)):
        for b in range(len(b)):
            pass
            print()

def distance(x,y):
    return (x**2+y**2)**0.5

def find_way_to(cur_p, des_p, grid, step):
    new_a=[cur_p]
    temp=[]
    tempi=[]
    i=0

    while True:
        for z in grid:
            if (abs(z[0]-new_a[-1][0])<=step) and (abs(z[1]-new_a[-1][1])<=step) and (distance(des_p[0]-z[0],des_p[1]-z[1]) < distance(des_p[0]-new_a[-1][0],des_p[1]-new_a[-1][1])):
                #print(z)
                temp.append(z)
                tempi.append(distance(des_p[0]-z[0],des_p[1]-z[1]))
        #print(temp)
        #print(tempi)
        #print('*'*5)

        if temp==[]:
            break
        new_a.append(temp[tempi.index(min(tempi))])
        temp=[]
        tempi=[]
        i+=1
        if i>len(grid):
            break

    #print(i)
    if new_a[-1]!=des_p:
        new_a+=[des_p]
    return new_a


#!/home/vlt-os/env/bin/python
"""This file is part of Vulture OS.

Vulture OS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Vulture OS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Vulture OS.  If not, see http://www.gnu.org/licenses/.
"""
__author__ = "Jérémie JOURDIN"
__credits__ = []
__license__ = "GPLv3"
__version__ = "4.0.0"
__maintainer__ = "Vulture OS"
__email__ = "contact@vultureproject.org"
__doc__ = 'LogForwarder main models'

from django.utils.translation import ugettext as _
from django.conf import settings

import logging
import logging.config

logging.config.dictConfig(settings.LOG_SETTINGS)

class Workflows:

    def __init__(self):
        self.logger = logging.getLogger('gui')

    @property
    def menu(self):
        MENU = {
            'link': 'workflow',
            'icon': 'fab fa-connectdevelop',
            'text': _('Workflow'),
            'url': "/workflow/"
        }

        return MENU


import random
import time

a = 30
o = 30

shape_x = a // 4
shape_y = o // 4
shape_width = a // 2
shape_height = o // 2
x = random.randint(shape_x, shape_x + shape_width - 1)
y = shape_y

direction = "down"

while True:
    for i in range(a):
        for j in range(o):
            if i == 0 or i == a - 1:
                print('-', end='')
            elif j == 0 or j == o - 1:
                print('|', end='')
            elif (shape_x <= i < shape_x + shape_width) and (shape_y <= j < shape_y + shape_height):
                if i == y and j == x:
                    print('&', end='')
                else:
                    print(' ', end='')
            else:
                print(' ', end='')
        print()

    time.sleep(0.15)

    if direction == "down":
        y += 1
        if y == shape_y + shape_height:
            direction = "exit"
    elif direction == "exit":
        if x < shape_x + shape_width - 1:
            x += 1
        else:
            direction = "random"
    elif direction == "random":
        x = random.randint(shape_x, shape_x + shape_width - 1)
        y = shape_y
        direction = "down"
    print("\033c")


from flask import Blueprint, render_template
from flask_user import login_required
from sqlalchemy.orm.exc import NoResultFound

from ..models import User, Nickname

user_blueprint = Blueprint('users', __name__, template_folder='templates')

@user_blueprint.route('/')
def index():
    users = User.query.all()
    return render_template('user/index.html', users=list(users))

@user_blueprint.route('/<int:user_id>')
def index_one(user_id):
    try:
        user = User.query.filter(User.id == user_id).one()
    except NoResultFound:
        abort(404)

    nicknames = Nickname.query.filter(Nickname.user == user).all()
    return render_template('user/index_one.html', user=user, nicknames=nicknames)


from pprint import pprint

def longestSubstring(substr1: str, substr2: str) -> str:
    table = []
    for _ in substr1:
        table_row = []
        for __ in substr2:
            table_row.append(0)
        table.append(table_row)
        table_row = []

    for i in range(len(substr1)):
        for j in range(len(substr2)):
            if substr1[i] == substr2[j]:
                if i == 0:
                    table[i][j] = 1
                elif j == 0:
                    table[i][j] = 1
                else:
                    table[i][j] = table[i - 1][j - 1] + 1

    coords = []
    max_value = 0
    for eachrow in table:
        max_value = max(max_value, max(eachrow))

    for i in range(len(table)):
        for j in range(len(table[i])):
            if table[i][j] == max_value:
                coords.append((i, j))

    substrs = []
    for eachcoord in coords:
        x_ = eachcoord[1]
        y_ = eachcoord[0]
        substr = ''
        while table[y_][x_] != 0 and x_ >= 0 and y_ >= 0:
            substr += substr1[x_]
            x_ -= 1
            y_ -= 1
        substrs.append(substr)
    print(substrs)

if __name__ == '__main__':
    s1 = 'abab'
    s2 = 'baba'
    longestSubstring(s1, s2)


#https://programmers.co.kr/learn/courses/30/lessons/86051?language=python3

def solution(numbers):
    answer = -1
    num_list = [1,2,3,4,5,6,7,8,9,0]
    res_list = []
    for i in num_list:
        if i not in numbers:
           res_list.append(i)
    answer = sum(res_list)
    return answer


import glob
import os
import socket
from typing import Callable, Union

from stable_baselines3.common.monitor import Monitor

from indago.algos.her_wrapper import HERWrapper
from indago.algos.sac_wrapper import SACWrapper
from indago.algos.tqc_wrapper import TQCWrapper
from indago.avf.avf import Avf
from indago.config import BASE_PORT, DONKEY_ENV_NAME, HUMANOID_ENV_NAME, PARK_ENV_NAME
from indago.envs.donkey.donkey_env_wrapper import DonkeyEnvWrapper
from indago.envs.donkey.scenes.simulator_scenes import SimulatorScene
from indago.envs.donkey.vae.vae import VAE
from indago.envs.humanoid.humanoid_env_wrapper import HumanoidEnvWrapper
from indago.envs.park.parking_env_wrapper import ParkingEnvWrapper
from indago.utils.torch_utils import DEVICE

ALGOS = {
    "her": HERWrapper,
    "sac": SACWrapper,
    "tqc": TQCWrapper,
}

def check_port_in_use(port: int) -> bool:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        return s.connect_ex(("localhost", port)) == 0

def linear_schedule(initial_value: Union[float, str]) -> Callable[[float], float]:
    """
    Linear learning rate schedule.
    :param initial_value: (float or str)
    :return: (function)
    """
    if isinstance(initial_value, str):
        initial_value = float(initial_value)

    def func(progress_remaining: float) -> float:
        """
        Progress will decrease from 1 (beginning) to 0
        :param progress_remaining: (float)
        :return: (float)
        """
        return progress_remaining * initial_value

    return func

def constfn(val):
    """
    Create a function that returns a constant
    It is useful for learning rate schedule (to avoid code duplication)

    :param val: (float)
    :return: (function)
    """

    def func(_):
        return val

    return func

def get_latest_run_id(log_path: str, env_id: str) -> int:
    """
    Returns the latest run number for the given log name and log path,
    by finding the greatest number in the directories.
    :param log_path: path to log folder
    :param env_id:
    :return: latest run number
    """
    max_run_id = 0
    for path in glob.glob(log_path + os.sep + f"{env_id}_[0-9]*"):
        file_name = path.split(os.sep)[-1]
        ext = file_name.split("_")[-1]
        # to take into account files with extension
        if "." in ext:
            ext = ext[: ext.rindex(".")]
        if env_id == "_".join(file_name.split("_")[:-1]) and ext.isdigit() and int(ext) > max_run_id:
            max_run_id = int(ext)
    return max_run_id

def make_env_fn(
    env_name: str,
    seed: int,
    avf: Avf,
    record_video: bool = False,
    save_path: str = None,
    vae_path: str = None,
    add_to_port: int = 0,
    simulation_mul: int = 1,
    z_size: int = 64,
    n_stack: int = 1,
    exe_path: str = None,
    simulator_scene: SimulatorScene = None,
    headless: bool = False,
) -> Callable:
    def _park_env_init():
        env_ = ParkingEnvWrapper(avf=avf)
        env_.seed(seed)
        env_.action_space.seed(seed)
        info_keywords = ("is_success",)

        if not record_video:
            env_.unwrap().config["offscreen_rendering"] = True
        else:
            env_.unwrap().config["show_trajectories"] = True

        if save_path is not None:
            return Monitor(env_, save_path, allow_early_resets=True, info_keywords=info_keywords)
        return env_

    def _humanoid_env_init():
        env_ = HumanoidEnvWrapper(avf=avf)
        env_.seed(seed)
        env_.action_space.seed(seed)
        info_keywords = ("is_success",)
        if save_path is not None:
            return Monitor(env_, save_path, allow_early_resets=True, info_keywords=info_keywords)
        return env_

    def _donkey_env_init():
        # not a very nice solution since some simulator instances may have been already started and
        # there is no way to stop them from this point
        assert not check_port_in_use(port=BASE_PORT + add_to_port - 1), "Port {} is in use".format(BASE_PORT + add_to_port - 1)
        assert not check_port_in_use(port=BASE_PORT + add_to_port), "Port {} is in use".format(BASE_PORT + add_to_port)
        assert not check_port_in_use(port=BASE_PORT + add_to_port + 1), "Port {} is in use".format(BASE_PORT + add_to_port + 1)

        vae = VAE(in_channels=3, latent_dim=z_size).to(DEVICE)
        vae.load(vae_path)

        env_ = DonkeyEnvWrapper(
            vae=vae,
            n_stack=n_stack,
            seed=seed,
            exe_path=exe_path,
            add_to_port=add_to_port,
            avf=avf,
            simulation_mul=simulation_mul,
            simulator_scene=simulator_scene,
            headless=headless,
        )

        env_.seed(seed)
        env_.action_space.seed(seed)

        info_keywords = ("is_success",)
        if save_path is not None:
            return Monitor(env_, save_path, allow_early_resets=True, info_keywords=info_keywords)

        return env_

    if env_name == PARK_ENV_NAME:
        return _park_env_init
    if env_name == HUMANOID_ENV_NAME:
        return _humanoid_env_init
    if env_name == DONKEY_ENV_NAME:
        assert vae_path is not None, "Vae path is not set"
        assert exe_path is not None, "Exe path is not set"

        return _donkey_env_init

    raise NotImplementedError("Unknown env name: {}".format(env_name))


"""

 * [문제] Log Parsing
 * access.log 파일을 파싱하여 URL 호출 성공 횟수와 이미지 파일 호출 횟수를 세는
   프로그램을 작성한다.
 * <요구사항>
 * 1. access.log 파일을 읽어 들여 문자열을 파싱한다.
 * 2. HTTP 상태 값이 200(성공)인 라인의 수를 센다.
 * 3. 이미지 파일이 호출된 라인 수를 센다. (HTTP 상태와는 상관 없음)
 *  - 그림 파일은 대소문자 구분 없이 jpg, gif, png 확장자로 끝난다. 단, 디렉토리가 /png/와 같이 포함된 경우도 있다.
 *  - 파일명 뒤에 ?가 붙는 경우도 고려한다.
 * 4. access.log 파일은 아래와 같은 형태로 구성되어 있다.

 * [실행결과]
 * Result Status 200 count : 1274
 * Image file count : 500
 *

"""
from logParsing_sub import logParser

inFp = None
inList = ""

inFp = open("access.log", "r")

inList = inFp.readlines()

success, image = logParser(inList)

print("Result Status 200 count : {}".format(success))
print("Image file count : {}".format(image))

inFp.close()


import sys
import os
import time
from random import randint, randrange

stderr = sys.stdout
parent_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(1, parent_dir)

num_vid = 0
num_endpoints = 0
num_req = 0
num_server = 0
capacity = 0

videos = []
endpoints = []
servers = []

def read_data(input):
    global videos
    global endpoints
    global servers
    global num_vid
    global num_endpoints
    global num_req
    global num_server
    global capacity
    num_vid, num_endpoints, num_req, num_server, capacity = map(int, input.readline().split())

    videos = list(map(int, input.readline().split()))

    for i in range(num_server):
        servers.append({
            "videos": {},
            "endpoints": []
        })

    for i in range(num_endpoints):
        lat, nr = map(int, input.readline().split())

        # conn = []
        # for j in range(nr):
        #     point, lat_point = map(int, input.readline().split())
        #     conn.append({
        #         "latency": lat_point,
        #         "id_server": point
        #     })
        conn = {}
        lat_min = lat
        id_min = -1
        for j in range(nr):
            id_server, lat_server = map(int, input.readline().split())
            if lat_server < lat_min:
                lat_min = lat_server
                id_min = id_server
            conn[id_server] = lat_server
            servers[id_server]["endpoints"].append(i)
        endpoints.append({
            "latency": lat,
            "servers": conn,
            "best_server": id_min,
            "req": {},
            "attrib": {}
        })

    max_nr = 0
    for i in range(num_req):
        video, point, nr = map(int, input.readline().split())
        endpoint = endpoints[point]
        if video not in endpoint["req"]:
            endpoint["req"][video] = 0
        endpoint["req"][video] += nr

        if nr * 1.1 < max_nr:
            continue
        if nr > max_nr:
            max_nr = nr
        id_server = endpoint["best_server"]
        if id_server == -1:
            continue
        if len(servers[id_server]["videos"]) < 6:
            servers[id_server]["videos"][video] = {}
        # for serv in endpoints[point]["servers"]:
        #     reducere[serv][video] +=

def initialize():
    viz = [0 for j in range(num_vid)]
    for id_server in range(num_server):
        serv = servers[id_server]
        vid_data = [{"count": 0, "reducere": 0} for j in range(num_vid)]
        for id_point in serv["endpoints"]:
            for id_video in endpoints[id_point]["req"]:
                vid_data[id_video]["id"] = id_video
                vid_data[id_video]["count"] += endpoints[id_point]["req"][id_video]
                latency_diff = (endpoints[id_point]["latency"] - endpoints[id_point]["servers"][id_server])
                vid_data[id_video]["reducere"] += latency_diff * endpoints[id_point]["req"][id_video]

        vid_touples = []
        for data in vid_data:
            if data["count"] == 0:
                continue
            vid_touples.append((data["id"], data["count"], data["reducere"]))

        vid_touples.sort(key=lambda chestie: chestie[2] / (videos[chestie[0]] ** 0.7), reverse=True)

        used = 0
        for chestie in vid_touples:
            # if chestie[2] == 0:
            #     break
            if viz[chestie[0]] > 1:
                continue
            used += videos[chestie[0]]
            if used <= capacity:
                servers[id_server]["videos"][chestie[0]] = vid_data[chestie[0]]
                viz[chestie[0]] += 1
        # for id_video in range(num_vid):
        #     vid_touples.append((id_video, vid_data[id_video]))

max_score = 0
best_conf = {}

def save_sol():
    global best_conf
    best_conf = {}
    for id_server in range(num_server):
        best_conf[id_server] = list(servers[id_server]["videos"])

def load_best():
    for id_server in best_conf:
        servers[id_server]["videos"] = {}
        for id_video in best_conf[id_server]:
            servers[id_server]["videos"][id_video] = {}

def calc_score(stderr):
    global max_score
    total = 0
    nr = 0
    for id_endpoint in range(num_endpoints):
        for id_video in endpoints[id_endpoint]["req"]:
            id_min_server = -1
            lat_min = endpoints[id_endpoint]["latency"]
            for id_server in endpoints[id_endpoint]["servers"]:
                if id_video in servers[id_server]["videos"]:
                    if endpoints[id_endpoint]["servers"][id_server] < lat_min:
                        lat_min = endpoints[id_endpoint]["servers"][id_server]
                        id_min_server = id_server

            lat_video = endpoints[id_endpoint]["latency"]
            nr += endpoints[id_endpoint]["req"][id_video]
            latency_diff = (lat_video - lat_min)
            total += latency_diff * endpoints[id_endpoint]["req"][id_video]
    score = 1000 * total / nr;
    print(score, file=stderr);
    if score > max_score:
        max_score = score
        save_sol()
    else:
        load_best()

retain_number = 10
def redo():
    t1 = time.perf_counter()
    for id_endpoint in range(num_endpoints):
        for id_video in endpoints[id_endpoint]["req"]:
            id_min_server = -1
            lat_min = 99999999
            for id_server in endpoints[id_endpoint]["servers"]:
                if id_video in servers[id_server]["videos"]:
                    if endpoints[id_endpoint]["servers"][id_server] < lat_min:
                        lat_min = endpoints[id_endpoint]["servers"][id_server]
                        id_min_server = id_server
            endpoints[id_endpoint]["attrib"][id_video] = id_min_server
    t2 = time.perf_counter()
    print("vid_data", t2 - t1, file=stderr)

    viz = [0 for j in range(num_vid)]

    global retain_number
    retain_number += 1
    for id_server in range(num_server):
        id_server = randint(0, num_server - 1)
        # print("server", id_server, file=stderr)
        serv = servers[id_server]
        # t1 = time.perf_counter()
        vid_data = [{"count": 0, "reducere": 0} for j in range(num_vid)]
        t2 = time.perf_counter()
        # print("vid_data", t2 - t1, file=stderr)
        iter = 0
        for id_point in serv["endpoints"]:
            endpoint = endpoints[id_point]
            for id_video in endpoint["req"]:
                # iter += 1
                if endpoint["servers"][id_server] > 700:
                    continue
                id_min_server = endpoint["attrib"][id_video]
                req = endpoint["req"][id_video]
                data = vid_data[id_video]
                lat_video = endpoint["latency"]

                if id_min_server == id_server:
                    data["id"] = id_video
                    data["count"] += req
                    latency_diff = (lat_video - endpoint["servers"][id_server])
                    data["reducere"] += latency_diff * req
                    continue

                if id_min_server != -1:
                    lat_video = endpoint["servers"][id_min_server]
                if endpoint["servers"][id_server] > lat_video:
                    continue
                # if id_min_server != -1 and endpoint["servers"][id_min_server] endpoint["servers"][id_min_server]:
                #     continue
                # if id_min_server != -1:
                #     lat_video =
                data["id"] = id_video
                data["count"] += req
                latency_diff = (lat_video - endpoint["servers"][id_server])
                data["reducere"] += latency_diff * req
        t3 = time.perf_counter()
        print("iter", iter, "in", t3 - t2, file=stderr)
        vid_touples = []
        for data in vid_data:
            if data["count"] == 0:
                continue
            vid_touples.append((data["id"], data["count"], data["reducere"]))

        # vid_touples.sort(key=lambda chestie: chestie[2], reverse=True)
        vid_touples.sort(key=lambda chestie: chestie[2] / (videos[chestie[0]] ** 0.6), reverse=True)

        servers[id_server]["videos"] = {}
        used = 0
        for i, chestie in enumerate(vid_touples):
            # if chestie[2] == 0:
            #     break
            # if viz[chestie[0]] > 3:
            #     continue
            # if i > 10 and randint(0, 10) < 2:
            #    continue

            # if len(vid_touples) > 4 and i == 0 and randint(0, 4) == 0:
            #     continue
            # if i > max(2, retain_number / 2) and randint(0, 1) == 0:
            #     continue
            used += videos[chestie[0]]
            if used <= capacity:
                servers[id_server]["videos"][chestie[0]] = vid_data[chestie[0]]
                viz[chestie[0]] += 1
        # for id_video in range(num_vid):
        #     vid_touples.append((id_video, vid_data[id_video]))

        # t4 = time.perf_counter()
        # print("gata", t4 - t3, file=stderr)
        if id_server % 50 == 0:
            break

def write_data():
    load_best()
    with open("data.out", "w") as output:
        sys.stdout = output
        print("best", max_score, file=stderr)
        print(num_server)
        for id_server in range(num_server):
            print(id_server, *servers[id_server]["videos"])

def load_data():
    for i in range(num_server):
        servers[i]["videos"] = {}
    with open("kittens-826.out", "r") as input:
        nr = int(input.readline())
        for _ in range(nr):
            data = list(map(int, input.readline().split()))
            id_server = data[0]
            for id_video in data[1:]:
                servers[id_server]["videos"][id_video] = {}

def main():
    with open("data.in", "r") as input:
        tmp = sys.stdout
        read_data(input)
        # initialize()
        load_data()
        for i in range(1500):
            redo()
            calc_score(tmp)
            if i % 20 == 0:
                global retain_number
                retain_number = 10
            write_data()
        sys.stdout = tmp

if __name__ == "__main__":
    main()


import os, sys,re, locale, codecs
import shutil
from optparse import OptionParser
from xml.dom.minidom import parse

##
# Copy file to tmp file
def default_pre_compil():
    name = os.path.basename(file_name).replace('.mo', '-tmp.mo')
    dirname = os.path.dirname(file_name)
    tmp_file_name = ""
    if( dirname != ""):
        tmp_file_name = os.path.join (dirname, name)
    else:
        tmp_file_name = name
    shutil.copy (file_name, tmp_file_name)

##
# Extract external variables from an external variables file
# (for fictitious equations)
def list_external_variables (external_variables_file_path):
    if (not os.path.isfile (external_variables_file_path)):
        print("Failed to extract external variables : missing file")
        sys.exit(1)

    liste_var_ext_continuous = []
    liste_var_ext_discrete = []
    liste_var_optional_ext_continuous = []
    liste_var_ext_boolean = []

    doc = parse (external_variables_file_path)
    for node in doc.getElementsByTagName("external_variables"):
        for variable in node.getElementsByTagName("variable"):
            default_value = "0"
            default_value_bool = "true"
            size = 1
            optional = False
            if ( variable.hasAttribute("defaultValue") ):
                default_value = variable.getAttribute("defaultValue")
            if ( variable.hasAttribute("size") ):
                size = int(variable.getAttribute("size"))
            if ( variable.hasAttribute("optional") ):
                optional = (variable.getAttribute("optional") == "true")

            if (variable.getAttribute("type") == "continuous"):
                if not optional:
                    liste_var_ext_continuous.append((variable.getAttribute("id"), default_value))
                else:
                    liste_var_optional_ext_continuous.append((variable.getAttribute("id"), default_value))
            elif (variable.getAttribute("type") == "discrete"):
                liste_var_ext_discrete.append((variable.getAttribute("id"), default_value))
            elif (variable.getAttribute("type") == "boolean"):
                liste_var_ext_boolean.append((variable.getAttribute("id"), default_value_bool))
            elif (variable.getAttribute("type") == "continuousArray"):
              for i in range(1,size+1):
                if not optional:
                  liste_var_ext_continuous.append((variable.getAttribute("id")+"["+str(i)+"]", default_value))
                else:
                  liste_var_optional_ext_continuous.append((variable.getAttribute("id")+"["+str(i)+"]", default_value))
            elif (variable.getAttribute("type") == "discreteArray"):
              for i in range(1,size+1):
                liste_var_ext_discrete.append((variable.getAttribute("id")+"["+str(i)+"]", default_value))

    return (liste_var_ext_continuous, liste_var_optional_ext_continuous, liste_var_ext_discrete, liste_var_ext_boolean)

##
# Add fictitious equation read in xml file
def pre_compil():

    liste_var_ext_continuous, liste_var_optional_ext_continuous, liste_var_ext_discrete, liste_var_ext_boolean = list_external_variables (file_var_ext_name)

    model_name = os.path.basename(file_name).replace(".mo", "")
    # modification of the .mo file
    f = open(file_name, "r")
    lines = f.readlines()
    f.close()

    for il in lines:
        line = il.rstrip('\n\r\t') # delete end of line characters
        line_save = ""

        if( line.find("end " + str(model_name)) != -1):
            line_save = il
            lines.remove(il)

            for var, default_value in liste_var_ext_continuous:
                value = 'der(' + str(var) + ') =' + default_value + ';\n'
                lines.append(value)

            for var, default_value in liste_var_optional_ext_continuous:
                value = 'der(' + str(var) + ') =' + default_value + ';\n'
                lines.append(value)

            if len(liste_var_ext_discrete) > 0 or len(liste_var_ext_boolean) > 0:
                value = " when(time > 999999) then \n"
                lines.append(value)
                for (var, val) in liste_var_ext_discrete:
                    value = "    " + str(var) + ' = ' + val + ';\n'
                    lines.append(value)
                for (var, val) in liste_var_ext_boolean:
                    value = "    " + str(var) + ' = ' + val + ';\n'
                    lines.append(value)
                value = " end when;\n"
                lines.append(value)

            lines.append(line_save)

            break

    name = os.path.basename(file_name).replace('.mo','-tmp.mo')
    dirname = os.path.dirname(file_name)
    tmp_file = ""
    file_path = name
    if( dirname != ""):
        file_path = os.path.join(dirname, name)

    tmp_file = open(file_path, 'w')

    for il in lines:
        tmp_file.write(il)
    tmp_file.close()

##
# Script adding fictitious equations in file thanks to description made in xml file
def main():

    usage=""" Usage: %prog [options]

    Script to make the variables listed in the .conf file fictitious

    """

     # In/out files
    parser = OptionParser(usage)
    parser.add_option( '--file',     dest = "file",     default="",    metavar="<file>",
                       help="file")
    parser.add_option( '--fileVarExt', dest = "fileVarExt", default="",    metavar="<fileVarExt>",
                       help="fichierVarExt")
    parser.add_option( '--pre', action="store_true", dest="preCompil",
                       help="Launch script precompilation mode")

    (options, args) = parser.parse_args()

    global file_var_ext_name
    global file_name

    file_var_ext_name = options.fileVarExt
    file_name = options.file

    if( os.path.isfile(file_var_ext_name) ):
        if( options.preCompil):
            pre_compil()
    else:
        if( options.preCompil):
            default_pre_compil()

if __name__ == "__main__":
    main()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
This code testing the segmenting images using GrabCut method.

This code testing the segmenting images using GrabCut method.
Author: Neil Han

! This sample code is a copy from https://github.com/Itseez/opencv/blob/master/samples/python2/grabcut.py
@ 2013-11-29
The original code was created by abidrahmank, and SpecLad

"""

from __future__ import absolute_import, division, \
    print_function, unicode_literals

# import ipdb; ipdb.set_trace() ; # debugging-------
import sys
import logging
import os

import numpy as np
import scipy.sparse as sp
import cv2
cv2.namedWindow('GetArroundASegmentationFailure', 0)
cv2.destroyWindow('GetArroundASegmentationFailure')
import matplotlib.pyplot as plt

import ava.utl
import ava.cv.utl

# this is the model object, carring the state, image etc
model = None

class GrabcutModel(object):
    RED = [0, 0, 255]
    GREEN = [0, 255, 0]
    BLUE = [255, 0, 0]
    WHITE = [255, 255, 255]
    BLACK = [0, 0, 0]

    DRAW_BG = {'color': BLACK, 'val': 0}
    DRAW_FG = {'color': WHITE, 'val': 1}
    DRAW_PR_BG = {'color': RED, 'val': 2}
    DRAW_PR_FG = {'color': GREEN, 'val': 3}

    def reset(self):
        self.rectangle = False
        self.rect = (0, 0, 1, 1)
        self.drawing = False
        self.rect_over = False
        self.rect_or_mask = 100
        self.value = GrabcutModel.DRAW_FG  # drawing brush init to FG
        self.thickness = 3
        self.img = self.img_backup.copy()
        self.mask = np.zeros(self.img.shape[:2], dtype=np.uint8)
        self.output = np.zeros(self.img.shape, dtype=np.uint8)
        self.ix = 0
        self.iy = 0

    def __init__(self, img):
        super(GrabcutModel, self).__init__()
        self.img_backup = img
        # self.reset()
        self.rectangle = False
        self.rect = (0, 0, 1, 1)
        self.drawing = False
        self.rect_over = False
        self.rect_or_mask = 100
        self.value = GrabcutModel.DRAW_FG  # drawing brush init to FG
        self.thickness = 3
        self.img = self.img_backup.copy()
        self.mask = np.zeros(self.img.shape[:2], dtype=np.uint8)
        self.output = np.zeros(self.img.shape, dtype=np.uint8)
        self.ix = 0
        self.iy = 0

    def get_output_img(self):
        bar = np.zeros((self.img.shape[0], 5, 3), np.uint8)
        result = np.hstack((self.img_backup, bar, self.img, bar, self.img_result))
        return result

def onmouse(event, x, y, flags, param):
    global model

    # Draw rectangle
    if event == cv2.EVENT_RBUTTONDOWN:
        model.rectangle = True
        model.ix, model.iy = x, y
    elif event == cv2.EVENT_MOUSEMOVE:  # draw a new rectangle
        if model.rectangle == True:
            model.img = model.img_backup.copy()
            cv2.rectangle(model.img, (model.ix, model.iy), (x, y), model.BLUE, 2)
            model.rect_or_mask = 0
    elif event == cv2.EVENT_RBUTTONUP:
        model.rectangle = False
        model.rect_over = True
        cv2.rectangle(model.img, (model.ix, model.iy), (x, y), model.BLUE, 2)
        model.rect = (model.ix, model.iy, abs(model.ix - x), abs(model.iy - y))
        model.rect_or_mask = 0
        print('Press "n" a few times until no further change.')

    # draw touchup curves
    if event == cv2.EVENT_LBUTTONDOWN:
        if model.rect_over == False:
            print('Please use your mouse right button to draw a rectangle.')
        else:
            model.drawing = True
            # draw a dot
            cv2.circle(model.img, (x, y), model.thickness, model.value['color'], -1)
            cv2.circle(model.mask, (x, y), model.thickness, model.value['val'], -1)
    elif event == cv2.EVENT_MOUSEMOVE:
        if model.drawing == True:
            # draw a dot
            cv2.circle(model.img, (x, y), model.thickness, model.value['color'], -1)
            cv2.circle(model.mask, (x, y), model.thickness, model.value['val'], -1)
    elif event == cv2.EVENT_LBUTTONUP:
        if model.drawing == True:
            model.drawing = False
            # draw a dot
            cv2.circle(model.img, (x, y), model.thickness, model.value['color'], -1)
            cv2.circle(model.mask, (x, y), model.thickness, model.value['val'], -1)
    # /// end onmouse

@ava.utl.time_this
def main(argv=None):
    global model

    if argv is None:
        argv = sys.argv
    # logger
    ava.utl.setup_logging()
    logger = logging.getLogger(__name__).getChild('main')

    logger.debug('starting main.')

    print('''Keys:
    'ESC' to exit
    0 to mark sure background with mouse button
    1 to mark sure backgroud
    2 to do PR_BG drawing, probable background
    3 to do PR_FG drawing, probable foreground
    n to update the segmentation
    r to reset the setup
    s to save the results to ./test_output.png''')

    img_root_path = '../images'

    if len(argv) >= 2:
        img_file = argv[1]  # use provided file
    else:
        print('Use default image.')
        img_file = os.path.join(img_root_path, 'dog2.jpg')  # 'tiger.jpg')

    img = cv2.imread(img_file, cv2.CV_LOAD_IMAGE_COLOR)

    cv2.namedWindow('output')
    cv2.namedWindow('input')
    # cv2.namedWindow('mask')
    # cv2.namedWindow('mask2')
    cv2.setMouseCallback('input', onmouse)
    cv2.moveWindow('input', img.shape[1] + 10, 90)

    model = GrabcutModel(img)  # init the model

    # start the main loop
    while(1):
        cv2.imshow('output', model.output)
        cv2.imshow('input', model.img)
        k = 0xFF & cv2.waitKey(10)

        if k == 27:  # esc exit
            break
        elif k == ord('0'):  # draw with BG
            print('Mark background regions with left mouse button.')
            model.value = GrabcutModel.DRAW_BG
        elif k == ord('1'):  # draw with FG
            print('Mark foreground regions with left mouse button.')
            model.value = GrabcutModel.DRAW_FG
        elif k == ord('2'):  # draw with PR_BG
            print('Mark probable background regions with left mouse button.')
            model.value = GrabcutModel.DRAW_PR_BG
        elif k == ord('3'):  # draw with PR_FG
            print('Mark probable foreground regions with left mouse button.')
            model.value = GrabcutModel.DRAW_PR_FG
        elif k == ord('r'):  # reset model
            print('Rest segments.')
            model.reset()
        elif k == ord('s'):  # save
            result = model.get_output_img()
            cv2.imwrite('grabcut_output.png', result)
        elif k == ord('n'):  # segment the image
            print('For finer touchups, mark foreground and background \
                  after pressing keys 0-3 and press "n"')

            if model.rect_or_mask == 0:  # grabcut with rect
                bgdmodel = np.zeros((1, 65), np.float64)
                fgdmodel = np.zeros((1, 65), np.float64)
                cv2.grabCut(model.img_backup, model.mask, model.rect,
                            bgdmodel, fgdmodel, 1, cv2.GC_INIT_WITH_RECT)
                model.rect_or_mask = 1
            elif model.rect_or_mask == 1:  # grabcut with mask
                bgdmodel = np.zeros((1, 65), np.float64)
                fgdmodel = np.zeros((1, 65), np.float64)
                cv2.grabCut(model.img_backup, model.mask, model.rect,
                            bgdmodel, fgdmodel, 1, cv2.GC_INIT_WITH_MASK)

        model.mask2 = np.where((model.mask == 1) + (model.mask == 3), 255, 0).astype('uint8')
        # cv2.imshow('mask2', model.mask2)
        # cv2.imshow('mask', model.mask)
        model.output = cv2.bitwise_and(model.img_backup, model.img_backup, mask=model.mask2)
    # /// while loop ends

    cv2.destroyAllWindows()

    exit()  # ===================

if __name__ == "__main__":
    main()


def printOddEven(a):
    if a%2==0:
        print("Even")
    else:
        print("Odd")

#printOddEven(1)

def print_element_pos(x):
    for pos, temp in enumerate(x):
        print(temp, pos)

def print_element(x):
    for temp in x:
        print(temp)

def print_odd_element(x):
    for temp in x:
        if temp%2==1:
            print(temp)

def print_even_element(x):
    for temp in x:
        if temp%2==0:
            print(temp)

def print_oddth_element(x):
    for pos, value in enumerate(x):
        if pos%2==1:
            print(value)

def elem_in_list(x, y):
    for value in x:
        if value==y:
            return True
    return False

# [0,1,2,3,4,5,6,...,size-1]

def get_num_from_user(prompt, can_be_negative):
    value = None if can_be_negative else -1
    while (not isinstance(value, int)) if can_be_negative else value < 0:
        try:
            value = int(input(prompt))
            if not can_be_negative and value < 0:
                print("Please only specify positive integers.")
        except ValueError:
            print("Please enter only a postive integer value.")
    return value

#size = -1
#while size < 0 :
#    try:
#        size = int(input("Enter size of list: "))
#    except ValueError as e:
#        print("Please enter only a number value.")

size = get_num_from_user("Enter size of list: ", False)

new_list=[]
for idx in range(0, size):
    enter_element = get_num_from_user("Enter element: ", True)
    new_list.append(enter_element)

#check_list = input("Enter elements of the list: ")  # user to enter 1,3,4,5

check_num = get_num_from_user("Enter a number: ", True)

if elem_in_list(new_list, check_num):
    print("Exists")
else:
    print("Does Not Exist")

def is_dup(x):
    cache = {}
    for value in x:
        if value in cache:
            return True
        else:
            cache[value] = "exists"
    return False

#print("Has Duplicates" if is_dup ([1,0,2,3]) else "No Duplicates")

#print_even_element([1,2,3,4,666666,6,6,6,6,6])
#print_element_pos([3,4])
#print_oddth_element([1,4,6,7,3,2,9])

#hashtable / map
# a = {"foo":1, "bar":2, "bbq": [2,3,4]}
# print(a["foo"])  ----> prints 1
# print(a["bar"])  ---- prints 2
# print(a["bbq"])  ---- prints [2,3,4]
# for num in a["bbq"]:
#     print(num)  ---- prints 2 then 3 then 4
# for k, v in a.items():
#     print(toupper(k))
#     print(v)
# a.keys() returns a list of keys -----> ["foo", "bar", "bbq"]
# a.values() returns a list of values ------> [1,2,[2,3,4]]


import cherrypy
import boto3
import json
import sys

profileStream = "dd-kf-profile"
aliasStream = "dd-kf-alias"
trackStream = "dd-kf-track"
kinesis_client = boto3.client('firehose')
cherrypy.config.update({'server.socket_host': '0.0.0.0'})
cherrypy.config.update({'server.socket_port': 1028})

class UserActivity(object):

    def postKinesisFirehose(self, stream, data):
        return kinesis_client.put_record(DeliveryStreamName=stream, Record={'Data': data})

    @cherrypy.expose
    def index(self):
        return "Tracking now..."

    @cherrypy.expose
    def profile(self, userId, attributes, timeStampUTC):
        data = json.dumps({'userId': userId, 'attributes': attributes, 'timeStampUTC': timeStampUTC})
        self.postKinesisFirehose(profileStream, data)

    @cherrypy.expose
    def track(self, userId, events):
        data = json.dumps({'userId': userId, 'events': events})
        self.postKinesisFirehose(trackStream, data)

    @cherrypy.expose
    def alias(self, newUserId, originalUserId, timeStampUTC):
        data = json.dumps({'newUserId': newUserId, 'originalUserId': originalUserId, 'timeStampUTC': timeStampUTC})
        self.postKinesisFirehose(aliasStream, data)

    @cherrypy.expose
    def test(self, userID):
        data = json.dumps({"UserID": userID})
        self.postKinesisFirehose(profileStream, data)

if __name__ == '__main__':
    cherrypy.quickstart(UserActivity())


"""
QUIC Server which consumes UDP traffic (such as LwM2M/CoAP) over QUIC
Traffic is then forwarded further to remote UDP Server
Designed originally for application protocol with its own re-try mechanism - CoAP (LwM2M).
QUIC tunnel uses unreliable QUIC Datagram (https://www.rfc-editor.org/rfc/rfc9221.html)
"""

import argparse
import asyncio
import binascii
import logging
import queue
import ssl
import struct
from threading import Thread
from typing import Dict, Optional

from aioquic.asyncio.protocol import QuicConnectionProtocol
from aioquic.asyncio.server import serve
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.connection import QuicConnection
from aioquic.quic.events import (
    ConnectionTerminated,
    DatagramFrameReceived,
    ProtocolNegotiated,
    QuicEvent,
)
from aioquic.quic.logger import QuicFileLogger
from aioquic.tls import SessionTicket

class NotRegisterMessage(Exception):
    """
    Exception to be raised when non Register message is parsed as Register
    """

class QuicServerProtocol(QuicConnectionProtocol):
    """
    Main Class to handle incoming QUIC traffic (which enapsulated UDP)
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.first_message = False
        self.cid = ""
        self.endpoint_name = ""

    def get_cid_str(self, cid: bytes):
        return binascii.hexlify(cid).decode("ascii")

    def quic_event_received(self, event: QuicEvent) -> None:
        """
        Logic Executed upon Receiving QUIC event
        """

        if isinstance(event, DatagramFrameReceived):
            length = struct.unpack("!H", bytes(event.data[:2]))[0]
            query = event.data[2 : 2 + length]
            quic_event_logger.info("Received QUIC data:\n%s...", query[:15])
            if self.first_message:
                quic_event_logger.info(
                    "First message retrieved after establishing connection"
                )

                self.cid = self.get_cid_str(self._quic.original_destination_connection_id)
                quic_event_logger.info("CID retrieved: %s", self.cid)

                quic_event_logger.debug(
                    "Saving QUIC connection details for client %s", self.cid
                )
                quic_connections[self.cid] = self

                self.first_message = False

            quic_event_logger.info(
                "Adding data to the queue to be forwarded via UDP, identified by cid: %s",
                self.cid,
            )

            quic_to_udp_queue.put((self.cid, query))

        if isinstance(event, ProtocolNegotiated):
            logger.info("QUIC Connection established, protocol negotiated: %s", event.alpn_protocol)
            self.first_message = True

        if isinstance(event, ConnectionTerminated):
            logger.info("QUIC Connection termination reason: %s", {event.reason_phrase})
            logger.info("Deleting the QUIC connection entry")
            try:
                del quic_connections[self.cid]
            except (KeyError, NameError):
                logger.error("Deleting failed")

class SessionTicketStore:
    """
    Simple in-memory store for session tickets.
    """
    def __init__(self) -> None:
        self.tickets: Dict[bytes, SessionTicket] = {}

    def add(self, ticket: SessionTicket) -> None:
        "Function to add session ticket."
        self.tickets[ticket.ticket] = ticket

    def pop(self, label: bytes) -> Optional[SessionTicket]:
        "Function to delete session ticket."
        return self.tickets.pop(label, None)

def get_quic_connection(cid: str) -> Optional[QuicServerProtocol]:
    """
    Return QUIC Connection for cid. If does not exist - return None
    """
    quic_forwarder_logger = logging.getLogger("[QUIC forwarder]")
    try:
        quic_connection: QuicServerProtocol = quic_connections[cid]
        return quic_connection
    except (KeyError, NameError):
        quic_forwarder_logger.error(
            "QUIC Connection for CID %s not found", cid
        )
        return None

class UdpClientProtocol(asyncio.DatagramProtocol):
    def __init__(self, cid):
        self.transport = None
        self.cid = cid

    def connection_made(self, transport):
        self.transport = transport
        udp_forwarder_logger.debug("UDP Connection for cid %s made, saving it globally", self.cid)
        udp_transports[self.cid] = transport

    def datagram_received(self, data: bytes, addr: tuple):
        udp_connections[self.cid] = addr
        udp_forwarder_logger.debug("Retrievied data %s from UDP", data)
        try:
            # try to parse the payload as str
            str_data = data.decode().strip()
            logger.debug("Looks like input data is string: %s", {str_data})
        except UnicodeDecodeError:
            logger.debug("Looks like input data are bytes already: %s", {data})
        data = struct.pack("!H", len(data)) + data
        logger.debug("Attempting to forward over existing QUIC connection: %s", {data})
        active_connection = get_quic_connection(self.cid)
        udp_to_quic_queue.put((active_connection, data))
        pass

async def establish_udp_connection(address, port, cid):
    ## TODO: where to call it?
    loop = asyncio.get_running_loop()
    udp_forwarder_logger.debug("Establishing UDP 'connection' towards %s:%s", address, port)
    transport, protocol = await loop.create_datagram_endpoint(
        lambda: UdpClientProtocol(cid),
        remote_addr=(address, port))

async def udp_forwarder(address: str, port: int) -> None:
    """
    Check if there are data waiting to be forwarded in 'quic_to_http_queue'.
    If yes - forward them via HTTP to UDP {{address}}
    """
    while True:
        try:
            cid, data = quic_to_udp_queue.get_nowait()
            if cid is None and data is None:
                break
            if cid not in udp_transports.keys():
                udp_forwarder_logger.error("cid %s not found in UDP connection")
                await establish_udp_connection(address = address, port = port, cid = cid)
            udp_forwarder_logger.debug("Attempting data (%s) to 'forward via UDP queue'", data)
            transport: asyncio.DatagramTransport = udp_transports[cid]
            transport.sendto(data=data)
            quic_to_udp_queue.task_done()
        except queue.Empty:
            # sleeping inside a loop is required to "unblock" handling the events if received UDP datagrams
            await asyncio.sleep(0.1)

async def quic_forwarder() -> None:
    """
    Constantly read the "http_to_quic_queue" and if there are any data to be forwarded -
    sends them via appropriate QUIC connection
    """
    while True:
        active_connection: QuicConnectionProtocol
        data: bytes
        active_connection, data = udp_to_quic_queue.get()
        if active_connection is None and data is None:
            break
        quic_forwarder_logger.info("Attempting to forward data via QUIC")
        quic_forwarder_logger.debug("Full data to be forwarded via QUIC:\n%s", data)
        QuicConnection.send_datagram_frame(
            active_connection._quic, data  # pylint: disable=protected-access
        )
        QuicConnectionProtocol.transmit(active_connection)
        quic_forwarder_logger.info("Forwarding done")
        udp_to_quic_queue.task_done()

async def start_quic_server(
    host: str,
    port: int,
    config: QuicConfiguration,
    session_ticket_store: SessionTicketStore,
    retry: bool,
) -> None:
    """
    Start the async QUIC and HTTP Servers.
    """
    # QUIC Server Start
    await serve(
        host,
        port,
        configuration=config,
        create_protocol=QuicServerProtocol,
        session_ticket_fetcher=session_ticket_store.pop,
        session_ticket_handler=session_ticket_store.add,
        retry=retry,
    )

    # Waiting infinitely
    await asyncio.Future()

def parse_args() -> argparse.Namespace:
    """
    Parse the startup arguments.
    """
    parser = argparse.ArgumentParser(description="UDP over QUIC tunneling server")
    parser.add_argument(
        "--host",
        type=str,
        default="127.0.0.1",
        help="QUIC Server listens on the specified address (defaults to 127.0.0.1)",
    )
    parser.add_argument(
        "--port",
        type=int,
        default=4784,
        help="QUIC Server listens on the specified port (defaults to 4784)",
    )
    parser.add_argument(
        "-k",
        "--private-key",
        type=str,
        help="load the TLS private key from the specified file (for the QUIC Endpoint)",
    )
    parser.add_argument(
        "-c",
        "--certificate",
        type=str,
        required=True,
        help="load the TLS certificate from the specified file (for the QUIC Endpoint)",
    )
    parser.add_argument(
        "--retry",
        action="store_true",
        help="send a retry for new connections",
    )
    parser.add_argument(
        "-q",
        "--quic-log",
        type=str,
        help="log QUIC events to QLOG files in the specified directory",
    )
    parser.add_argument(
        "--remoteUdpServerHost",
        type=str,
        default="127.0.0.1",
        help="LwM2M Server API address to which the data will be forwarded by HTTP",
    )
    parser.add_argument(
        "--remoteUdpServerPort",
        type=str,
        default="9999",
        help="LwM2M Server API address to which the data will be forwarded by HTTP",
    )
    parser.add_argument(
        "-v", "--verbose", action="store_true", help="increase logging verbosity"
    )

    return parser.parse_args()

# Declaring Globals
logger = logging.getLogger("[Main]")
quic_forwarder_logger = logging.getLogger("[QUIC Forwarder]")
http_server_logger = logging.getLogger("[HTTP Server]")
quic_event_logger = logging.getLogger("[QUIC event]")
udp_forwarder_logger = logging.getLogger("[UDP Forwarder]")

udp_connections = {}
udp_transports = {}
quic_connections = {}

allowed_alpns = ["http/0.9", "http/1.0", "http/1.1", "spdy/1", "spdy/2", "spdy/3",
"stun.turn", "stun.nat-discovery", "h2", "h2c", "webrtc", "c-webrtc", "ftp", "imap",
"pop3", "managesieve", "coap", "xmpp-client", "xmpp-server", "acme-tls/1",
"mqtt", "dot", "ntske/1", "sunrpc", "h3", "smb", "irc", "nntp", "nnsp", "doq", "sip/2", "tds/8.0"]

## populated by quic_event_received() and handled by http_forwarder()
quic_to_udp_queue = queue.Queue()

## populated by http_listener() and handled by quic_forwarder()
udp_to_quic_queue = queue.Queue()

if __name__ == "__main__":
    startArgs = parse_args()

    logging.basicConfig(
        format="%(asctime)s %(levelname)s %(name)s %(message)s",
        level=logging.DEBUG if startArgs.verbose else logging.INFO,
    )

    # QUIC part
    # create QUIC logger
    if startArgs.quic_log:
        QUIC_LOGGER = QuicFileLogger(startArgs.quic_log)
    else:
        QUIC_LOGGER = None

    # Starting Quic forwarder
    quic_forwarder_thread = Thread(target=asyncio.run, args=(quic_forwarder(),))
    quic_forwarder_thread.start()

    # Starting UDP forwarder
    # TODO: update the IP and the port from args
    udp_forwarder_thread = Thread(target=asyncio.run, args=(udp_forwarder(startArgs.remoteUdpServerHost, startArgs.remoteUdpServerPort),))
    udp_forwarder_thread.start()

    # preparing QUIC Server configuration
    configuration = QuicConfiguration(
        alpn_protocols=allowed_alpns,
        is_client=False,
        quic_logger=QUIC_LOGGER,
        max_datagram_frame_size=65535,
        idle_timeout=86400,
        verify_mode=ssl.CERT_REQUIRED,
    )

    configuration.load_cert_chain(startArgs.certificate, startArgs.private_key)

    # launching async QUIC and HTTP server
    try:
        logger.info("Starting QUIC and HTTP Server")
        asyncio.run(
            start_quic_server(
                host=startArgs.host,
                port=startArgs.port,
                config=configuration,
                session_ticket_store=SessionTicketStore(),
                retry=startArgs.retry,
            )
        )
    except KeyboardInterrupt:
        print("Graceful shutdown")

        # putting emtpy event to stop the quic_forwarder_thread
        udp_to_quic_queue.put((None, None))
        # putting emtpy event to stop the http_client_thread
        quic_to_udp_queue.put((None, None))

        quic_forwarder_thread.join()
        udp_forwarder_thread.join()


import os
import subprocess
import shlex

from SimEx.Calculators.AbstractPhotonPropagator import AbstractPhotonPropagator
from SimEx.Parameters.WavePropagatorParameters import WavePropagatorParameters
from SimEx.Utilities import EntityChecks
from SimEx.Utilities import IOUtilities
from SimEx.Utilities import ParallelUtilities
from SimEx.Utilities import wpg_to_opmd
from prop import propagate_s2e

class WavePropagator(AbstractPhotonPropagator):
    """
    :class WavePropagator: Represents coherent wavefront propagation using the WPG wrapper for SWR.
    """
    def __init__(self, parameters=None, input_path=None, output_path=None):
        """

        :param parameters: Parameters for the photon propagation.
        :type parameters: WavePropagatorParameters instance.

        :param  input_path: Location of input data for photon propagation.
        :type input_path:   str, default 'FELsource/'

        :param output_path: Location of propagation output data.
        :type output_path:  str, default 'prop/'
        """

        # Handle default parameters if None.
        parameters = EntityChecks.checkAndSetInstance(
            WavePropagatorParameters, parameters, WavePropagatorParameters())

        # Initialize base class.
        super(WavePropagator, self).__init__(parameters, input_path,
                                             output_path)

    def computeNTasks(self):
        resources = ParallelUtilities.getParallelResourceInfo()
        nnodes = resources['NNodes']
        ncores = resources['NCores']

        cpusPerTask = self.parameters.cpus_per_task

        if cpusPerTask == "MAX":
            np = nnodes
            ncores = 0
        else:
            np = max(1, int(ncores / int(cpusPerTask)))
            ncores = int(cpusPerTask)

        return (np, ncores)

    def backengine(self):
        """ Starts WPG simulations in parallel in a subprocess """

        fname = IOUtilities.getTmpFileName()
        self.dumpToFile(fname)

        forcedMPIcommand = self.parameters.forced_mpi_command

        if forcedMPIcommand == "":
            (np, ncores) = self.computeNTasks()
            mpicommand = ParallelUtilities.prepareMPICommandArguments(
                np, ncores)
        else:
            mpicommand = forcedMPIcommand

        if 'SIMEX_VERBOSE' in os.environ:
            if 'MPI' in os.environ['SIMEX_VERBOSE']:
                print(("WavePropagator backengine mpicommand: " + mpicommand))
            if 'PYTHON' in os.environ['SIMEX_VERBOSE']:
                import platform
                print("Running python %s." % (platform.python_version()))

        mpicommand += " python " + __file__ + " " + fname

        args = shlex.split(mpicommand)

        proc = subprocess.Popen(args, universal_newlines=True)
        proc.wait()
        os.remove(fname)

        return proc.returncode

    def _run(self):
        """ This method drives the WPG backengine.

        :return: 0 if WPG returns successfully, 1 if not.

        """

        # import should be here, not in header as it calls MPI_Init when
        # imported. We want MPI to be initialized at this stage only.
        from mpi4py import MPI

        # MPI info
        comm = MPI.COMM_WORLD
        thisProcess = comm.rank
        numProcesses = comm.size

        # Check if input path is a directory.
        if os.path.isdir(self.input_path):
            input_files = [os.path.join(self.input_path, input_file) for \
                            input_file in os.listdir(self.input_path)]
            input_files.sort(
            )  # Assuming the filenames have some kind of ordering scheme.
        else:
            if thisProcess == 0:  # other MPI processes (if any) have nothing to do
                propagate_s2e.propagate(self.input_path, self.output_path,
                                        self.parameters.beamline.get_beamline)
            return 0

        # If we have more than one input file, we should also have more than
        # one output file, i.e. output_path should be a directory.
        if os.path.isfile(self.output_path):
            raise IOError(
                "The given output path is a file but a directory is needed. Cowardly refusing to overwrite."
            )

        # Check if output dir exists, create if not.
        if not os.path.isdir(self.output_path):
            os.mkdir(self.output_path)

        # Loop over all input files and generate one run per source file.
        for i, input_file in enumerate(input_files):
            # TODO: Transmit number of cpus.
            # process file on a corresponding process (round-robin)
            if i % numProcesses == thisProcess:
                output_file = os.path.join(self.output_path,
                                           'prop_out_%07d.h5' % (i))
                propagate_s2e.propagate(input_file, output_file,
                                        self.parameters.beamline.get_beamline)

                # Rewrite in openpmd conformant way.
                # wpg_to_opmd.convertToOPMD( output_file )

        return 0

    @property
    def data(self):
        """ Query for the field data. """
        return self.__data

    def _readH5(self):
        """ """
        """ Private method for reading the hdf5 input and extracting the parameters and data relevant to initialize the object. """
        pass  # Nothing to be done since IO happens in backengine.

    def saveH5(self):
        """ """
        """
        :param output_path: Path to propagation output.
        :type output_path: string
        """
        pass  # No action required since output is written in backengine.

if __name__ == '__main__':
    WavePropagator.runFromCLI()


def truncate(text, limit=120, suffix="..."):
    """
    Truncates the given text up to `limit` and fill its ending with `suffix`.

    Tries to find the latest space before the `limit` which is located in the second half of the
    text. If no space is found, truncates at the limit. Searching for a space in the second-half
    of the text avoids cases where the word going over the limit is very long, e.g.:

    ```python
    # Without:
    truncate("I spectrophotofluorometrically assessed this sample", limit=25)
    #=> "I..."

    # With:
    truncate("I spectrophotofluorometrically assessed this sample", limit=25)
    #=> "I spectrophotofluorom..."
    ```

    Adapted from https://github.com/reddit/reddit/blob/master/r2/r2/lib/utils/utils.py#L407.

    Examples:
        ```python
        from flashback.formatting import truncate

        truncate("This helper is very useful for preview of descriptions", limit=50)
        #=> "This helper is very useful for preview of..."

        truncate("Wonderful tool to use in any projects!", limit=35, suffix=", bla bla bla")
        #=> "Wonderful tool to use, bla bla bla"

        truncate("Hi there", limit=3, suffix="")
        #=> "Hi"
        ```

    Params:
        text (str): the text to truncate
        limit (int): the maximum length of the text
        suffix (str): the suffix to append at the truncated text

    Returns
        str: the truncated text
    """
    if len(text) <= limit:
        return text

    truncated_text = text[:(limit - len(suffix))]
    try:
        space_index = truncated_text.rindex(" ")
    except ValueError:
        space_index = -1

    if space_index < limit // 2:
        space_index = -1

    return truncated_text[:space_index] + suffix