from channels.generic.websocket import AsyncWebsocketConsumer
import json
from django.forms.models import model_to_dict
from server.serializers.chatroom_serializer import ChatroomSerializer
from server.models import Chatroom, Organization, User, AbstractMessage, chatroom_model
from server.utils.json_util import jsonify
from channels.db import database_sync_to_async
from bson import ObjectId
from copy import deepcopy as deepcopy
import datetime
import time

@database_sync_to_async
def save_to_database(group_name, sender, messageType, message):
    try:
        chatroom = Chatroom.objects.get(room_name=group_name)
    except:
        user = group_name.split("_")[1]
        org = group_name.split("_")[2]

        print(user, org)
        user = model_to_dict(User.objects.get(_id=ObjectId(user)))
        org = model_to_dict(Organization.objects.get(_id=ObjectId(org)))
        data = jsonify({"room_name": group_name, "user":user, "organization":org, "message":[]})
        serializer = ChatroomSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            chatroom = Chatroom.objects.get(room_name=group_name)
        else:
            print(serializer.errors)

    new_message = {"sender":sender, "messageType":messageType, "message":message, "createAt":datetime.datetime.fromtimestamp(time.time())}

    chatroom.message.append(new_message)

    chatroom.save()

    # data = model_to_dict(chatroom)

    # serializer = ChatroomSerializer(data=data)
    # if serializer.is_valid():
    #     serializer.save()
    # else:
    #     serializer.errors()

"""
Route 를 통하여 Consumer에 접근

urls -> views
routing -> consumers
"""

class ChatRoomConsumer(AsyncWebsocketConsumer):
    # Start connection
    async def connect(self):  # calling it will return coroutine(?) object
        """
        enabling web socket activity
        """

        # extract room name
        self.room_name = self.scope["url_route"]["kwargs"]["room_name"]

        # setup group room name
        self.room_group_name = "chat_%s" % self.room_name

        # Construct group
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name,  # contains pointer to the channel layer isntance & name to reach the consumer
        )

        # Accept socket connection
        await self.accept()

        # need a broker --> config.settings CHANNEL_LAYERS

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name,
        )

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json["message"]
        username = text_data_json["username"]

        await self.channel_layer.group_send(
            self.room_group_name,
            {"type": "chatroom_message", "message": message, "username": username},
        )

    async def chatroom_message(self, event):
        message = event["message"]
        username = event["username"]
        messageType = event["type"]

        await self.send(
            text_data=json.dumps({"username": username, "message": message})
        )
        await save_to_database(self.room_group_name, username, messageType, message)


# Created on December, 2020
# @author: Fábio Araújo de Sá

def which_are_in(l1, l2):

    result = []

    for item1 in l1:
        for item2 in l2:
            if item1 in item2:
                if item1 not in result:
                    result.append(item1)

    return sorted(result)


from __future__ import absolute_import, division, print_function

__metaclass__ = type

DOCUMENTATION = r"""
---
module: droplet_action_snapshot

short_description: Take a snapshot of a Droplet

version_added: 0.3.0

description:
  - Take a snapshot of a Droplet.
  - View the API documentation at U(https://docs.digitalocean.com/reference/api/api-reference/#tag/Droplet-Actions).

author: Mark Mercado (@mamercad)

requirements:
  - pydo >= 0.1.3
  - azure-core >= 1.26.1

options:
  droplet_id:
    description:
      - A unique identifier for a Droplet instance.
      - If provided, C(name) and C(region) are ignore.
    type: int
    required: false
  name:
    description:
      - The name of the Droplet to act on.
      - If provided, must be unique and given with C(region).
    type: str
    required: false
  region:
    description:
      - The name of the Droplet to act on.
      - Required with C(name).
    type: str
    required: false
  snapshot_name:
    description:
      - The name to give the new snapshot of the Droplet.
    type: str
    required: false

extends_documentation_fragment:
  - digitalocean.cloud.common.documentation
"""

EXAMPLES = r"""
- name: Snapshot a Droplet
  digitalocean.cloud.droplet_action_snapshot:
    token: "{{ token }}"
    state: present
    name: my-droplet
    region: nyc3
    snapshot_name: my-droplet-snapshot
"""

RETURN = r"""
action:
  description: DigitalOcean snapshot action information.
  returned: always
  type: dict
  sample:
    id: 36804636
    status: completed
    type: create
    started_at: '2020-11-14T16:29:21Z'
    completed_at: '2020-11-14T16:30:06Z'
    resource_id: 3164444
    resource_type: droplet
    region:
      name: New York 3
      slug: nyc3
      features:
        - private_networking
        - backups
        - ipv6
        - metadata
        - install_agent
        - storage
        - image_transfer
      available: true
      sizes:
        - s-1vcpu-1gb
        - s-1vcpu-2gb
        - s-1vcpu-3gb
        - s-2vcpu-2gb
        - s-3vcpu-1gb
        - s-2vcpu-4gb
        - s-4vcpu-8gb
        - s-6vcpu-16gb
        - s-8vcpu-32gb
        - s-12vcpu-48gb
        - s-16vcpu-64gb
        - s-20vcpu-96gb
        - s-24vcpu-128gb
        - s-32vcpu-192g
    region_slug: string
error:
  description: DigitalOcean API error.
  returned: failure
  type: dict
  sample:
    Message: Informational error message.
    Reason: Unauthorized
    Status Code: 401
msg:
  description: DigitalOcean action information.
  returned: always
  type: str
  sample:
    - No Droplet with ID 336851565
    - No Droplet with name test-droplet-1 in nyc3
    - Droplet test-droplet-1 (336851565) in nyc3 would be sent action 'snapshot'
    - Droplet test-droplet-1 (336851565) in nyc3 sent action 'snapshot'
    - Droplet test-droplet-1 (336851565) in nyc3 sent action 'snapshot' and it has not completed, status is 'in-progress'
"""

import time
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.digitalocean.cloud.plugins.module_utils.common import (
    DigitalOceanCommonModule,
    DigitalOceanOptions,
    DigitalOceanFunctions,
    DigitalOceanConstants,
)

class DropletActionSnapshot(DigitalOceanCommonModule):
    def __init__(self, module):
        super().__init__(module)
        self.timeout = module.params.get("timeout")
        self.droplet_id = module.params.get("droplet_id")
        self.name = module.params.get("name")
        self.region = module.params.get("region")
        self.type = "snapshot"
        self.snapshot_name = module.params.get("snapshot_name")
        self.droplet = self.find_droplet()
        if self.state == "present":
            self.present()

    def find_droplet(self):
        if self.droplet_id:
            try:
                droplet = self.client.droplets.get(droplet_id=self.droplet_id)[
                    "droplet"
                ]
                if droplet:
                    return droplet
                self.module.fail_json(
                    changed=False,
                    msg=f"No Droplet with ID {self.droplet_id}",
                    action=[],
                )
            except DigitalOceanCommonModule.HttpResponseError as err:
                error = {
                    "Message": err.error.message,
                    "Status Code": err.status_code,
                    "Reason": err.reason,
                }
                self.module.fail_json(
                    changed=False, msg=error.get("Message"), error=error, action=[]
                )
        elif self.name and self.region:
            droplets = DigitalOceanFunctions.get_droplet_by_name_in_region(
                module=self.module,
                client=self.client,
                region=self.region,
                name=self.name,
            )
            if len(droplets) == 0:
                self.module.fail_json(
                    changed=False,
                    msg=f"No Droplet named {self.name} in {self.region}",
                    action=[],
                )
            elif len(droplets) > 1:
                self.module.fail_json(
                    changed=False,
                    msg=f"Multiple Droplets ({len(droplets)}) named {self.name} found in {self.region}",
                    action=[],
                )
            return droplets[0]

        self.module.fail_json(
            changed=False,
            msg="Should not reach this",
            action=[],
        )

    def get_action_by_id(self, action_id):
        try:
            action = self.client.actions.get(action_id=action_id)["action"]
            return action
        except DigitalOceanCommonModule.HttpResponseError as err:
            error = {
                "Message": err.error.message,
                "Status Code": err.status_code,
                "Reason": err.reason,
            }
            self.module.fail_json(
                changed=False, msg=error.get("Message"), error=error, action=[]
            )

    def snapshot(self):
        try:
            body = {
                "type": self.type,
                "name": self.snapshot_name,
            }
            action = self.client.droplet_actions.post(
                droplet_id=self.droplet["id"], body=body
            )["action"]

            end_time = time.monotonic() + self.timeout
            while time.monotonic() < end_time and action["status"] != "completed":
                time.sleep(DigitalOceanConstants.SLEEP)
                action = self.get_action_by_id(action_id=action["id"])

            if action["status"] != "completed":
                self.module.fail_json(
                    changed=True,
                    msg=(
                        f"Droplet {self.droplet['name']} ({self.droplet['id']}) in {self.droplet['region']['slug']}"
                        f" sent action '{self.type}' and it has not completed, status is '{action['status']}'"
                    ),
                    action=action,
                )

            self.module.exit_json(
                changed=True,
                msg=f"Droplet {self.droplet['name']} ({self.droplet['id']}) in {self.droplet['region']['slug']} sent action '{self.type}'",
                action=action,
            )
        except DigitalOceanCommonModule.HttpResponseError as err:
            error = {
                "Message": err.error.message,
                "Status Code": err.status_code,
                "Reason": err.reason,
            }
            self.module.fail_json(
                changed=False, msg=error.get("Message"), error=error, action=[]
            )

    def present(self):
        if self.module.check_mode:
            self.module.exit_json(
                changed=True,
                msg=f"Droplet {self.droplet['name']} ({self.droplet['id']}) in {self.droplet['region']['slug']} would be sent action '{self.type}'",
            )

        self.snapshot()

def main():
    argument_spec = DigitalOceanOptions.argument_spec()
    argument_spec.update(
        droplet_id=dict(type="int", required=False),
        name=dict(type="str", required=False),
        region=dict(type="str", required=False),
        snapshot_name=dict(type="str", required=False),
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_one_of=[("droplet_id", "name")],
        mutually_exclusive=[("droplet_id", "name")],
        required_together=[("name", "region")],
    )
    DropletActionSnapshot(module)

if __name__ == "__main__":
    main()


from django.test import TestCase
from django.contrib.auth.models import User
from account.models import Lab
from resource_inventory.models import (
    Scenario,
    Installer,
    Opsys,
    ConfigBundle,
    OPNFVConfig,
    OPNFVRole,
    Image,
    HostProfile,
    GenericResourceBundle,
    GenericResource,
    GenericHost,
    HostConfiguration
)

class ConfigUtil():
    count = 0

    @staticmethod
    def makeScenario():
        return Scenario.objects.create(name="testScenario")

    @staticmethod
    def makeInstaller():
        inst = Installer.objects.create(name="testInstaller")
        inst.sup_scenarios = [ConfigUtil.makeScenario()]
        return inst

    @staticmethod
    def makeOpsys():
        os = Opsys.objects.create(name="test Operating System")
        os.sup_installers = [ConfigUtil.makeInstaller()]
        return os

    @staticmethod
    def makeConfigBundle():
        user = User.objects.create(username="test_user" + str(ConfigUtil.count))
        ConfigUtil.count += 1
        return ConfigBundle.objects.create(owner=user)

    @staticmethod
    def makeOPNFVConfig():
        installer = ConfigUtil.makeInstaller()
        scenario = ConfigUtil.makeScenario()
        bundle = ConfigUtil.makeConfigBundle()
        return OPNFVConfig.objects.create(
            installer=installer,
            scenario=scenario,
            bundle=bundle
        )

    @staticmethod
    def makeOPNFVRole():
        return OPNFVRole.objects.create(
            name="Test role",
            description="This is a test role"
        )

    @staticmethod
    def makeImage():
        owner = User.objects.create(username="another test user")
        lab_user = User.objects.create(username="labUserForTests")
        lab = Lab.objects.create(
            lab_user=lab_user,
            name="this is lab for testing",
            contact_email="email@mail.com",
            contact_phone="123-4567"
        )

        return Image.objects.create(
            cobbler_id="profile1",
            from_lab=lab,
            name="an image for testing",
            owner=owner
        )

    @staticmethod
    def makeGenericHost():
        profile = HostProfile.objects.create(
            host_type=0,
            name="test lab for config bundle",
            description="this is a test profile"
        )
        user = User.objects.create(username="test sample user 12")
        bundle = GenericResourceBundle.objects.create(
            name="Generic bundle for config tests",
            xml="",
            owner=user,
            description=""
        )

        resource = GenericResource.objects.create(
            bundle=bundle,
            name="a test generic resource"
        )

        return GenericHost.objects.create(
            profile=profile,
            resource=resource
        )

    @staticmethod
    def makeHostConfiguration():
        host = ConfigUtil.makeGenericHost()
        image = ConfigUtil.makeImage()
        bundle = ConfigUtil.makeConfigBundle()
        opnfvRole = ConfigUtil.makeOPNFVRole()
        return HostConfiguration.objects.create(
            host=host,
            image=image,
            bundle=bundle,
            opnfvRole=opnfvRole
        )

class ScenarioTestCase(TestCase):

    def test_save(self):
        self.assertTrue(ConfigUtil.makeScenario())

class InstallerTestCase(TestCase):

    def test_save(self):
        self.assertTrue(ConfigUtil.makeInstaller())

class OperatingSystemTestCase(TestCase):

    def test_save(self):
        self.assertTrue(ConfigUtil.makeOpsys())

class ConfigBundleTestCase(TestCase):

    def test_save(self):
        self.assertTrue(ConfigUtil.makeConfigBundle())

class OPNFVConfigTestCase(TestCase):

    def test_save(self):
        self.assertTrue(ConfigUtil.makeOPNFVConfig())

class OPNFVRoleTestCase(TestCase):

    def test_save(self):
        self.assertTrue(ConfigUtil.makeOPNFVRole())

class HostConfigurationTestCase(TestCase):

    def test_save(self):
        self.assertTrue(ConfigUtil.makeHostConfiguration())

class ImageTestCase(TestCase):

    def test_save(self):
        self.assertTrue(ConfigUtil.makeImage())


from typing import List
import shlex
from emoji import EMOJI_DATA
from io import BytesIO

import discord
from discord.ext import commands

from pie import check, i18n, logger, utils

from . import utils as helper_utils
from .database import ReactionChannel, ReactionChannelType

_ = i18n.Translator("modules/mgmt").translate
guild_log = logger.Guild.logger()

class React2Role(commands.Cog):
    def __init__(self, bot: commands.Bot):
        self.bot = bot

    @commands.guild_only()
    @check.acl2(check.ACLevel.MOD)
    @commands.group(name="reaction-channel")
    async def reaction_channel(self, ctx):
        """Manage react2role channels."""
        await utils.discord.send_help(ctx)

    @commands.guild_only()
    @check.acl2(check.ACLevel.MOD)
    @reaction_channel.command(name="list")
    async def reaction_channel_list(self, ctx):
        """List react2role channels."""
        db_channels: List[ReactionChannel] = ReactionChannel.get_all(ctx.guild.id)
        if not db_channels:
            await ctx.reply(
                _(ctx, "React2role functionality is not enabled on this server.")
            )
            return

        class Item:
            def __init__(self, db_channel: ReactionChannel):
                dc_channel = ctx.guild.get_channel(db_channel.channel_id)
                top_role = ctx.guild.get_role(db_channel.top_role)
                bottom_role = ctx.guild.get_role(db_channel.bottom_role)

                self.name = (
                    f"#{dc_channel.name}" if dc_channel else str(db_channel.channel_id)
                )
                self.type = db_channel.channel_type.name

                if db_channel.channel_type == ReactionChannelType.ROLE:
                    self.max_roles = (
                        db_channel.max_roles if db_channel.max_roles > 0 else "-"
                    )
                    if db_channel.top_role:
                        self.top = getattr(
                            top_role,
                            "name",
                            str(db_channel.top_role),
                        )
                    else:
                        self.top = "-"

                    if db_channel.bottom_role:
                        self.bottom = getattr(
                            bottom_role,
                            "name",
                            str(db_channel.bottom_role),
                        )
                    else:
                        self.bottom = "-"
                else:
                    self.max_roles = ""
                    self.top = ""
                    self.bottom = ""

        channels = [Item(db_channel) for db_channel in db_channels]
        table: List[str] = utils.text.create_table(
            channels,
            header={
                "name": _(ctx, "Channel"),
                "type": _(ctx, "Type"),
                "max_roles": _(ctx, "Role limit"),
                "top": _(ctx, "Top role"),
                "bottom": _(ctx, "Bottom role"),
            },
        )

        for page in table:
            await ctx.send("```" + page + "```")

    @commands.guild_only()
    @check.acl2(check.ACLevel.MOD)
    @reaction_channel.command(name="add")
    async def reaction_channel_add(
        self, ctx, channel: discord.TextChannel, channel_type: str
    ):
        """Add new react2role channel.

        Args:
            channel: A text channel.
            channel_type: 'role' or 'channel' string.
        """
        if ReactionChannel.get(ctx.guild.id, channel.id) is not None:
            await ctx.reply(
                _(ctx, "Channel **#{channel}** is already react2role channel.").format(
                    channel=channel.name
                )
            )
            return
        types: List[str] = [m.value for m in ReactionChannelType.__members__.values()]
        if channel_type not in types:
            await ctx.reply(
                _(ctx, "Channel type can only be one of {types}.").format(
                    types=", ".join(types)
                )
            )
            return
        channel_type = ReactionChannelType(channel_type)

        reaction_channel = ReactionChannel.add(
            guild_id=ctx.guild.id,
            channel_id=channel.id,
            channel_type=channel_type,
        )
        await ctx.reply(
            _(ctx, "**#{channel}** has been set as {type} channel.").format(
                channel=channel.name,
                type=reaction_channel.React2name,
            )
        )
        await guild_log.info(
            ctx.author,
            ctx.channel,
            f"{reaction_channel.React2name} #{channel.name} set up.",
        )

    @commands.guild_only()
    @check.acl2(check.ACLevel.MOD)
    @reaction_channel.command(name="unlimit")
    async def reaction_channel_unlimit(self, ctx, channel: discord.TextChannel):
        """Remove limits on 'role' channel."""
        reaction_channel = ReactionChannel.get(ctx.guild.id, channel.id)
        if reaction_channel is None:
            await ctx.reply(
                _(ctx, "Channel **#{channel}** is not react2role channel.").format(
                    channel=channel.name
                )
            )
            return
        if reaction_channel.channel_type != ReactionChannelType.ROLE:
            await ctx.reply(_(ctx, "Limiting is only available for 'role' channels."))
            return

        reaction_channel.max_roles = 0
        reaction_channel.top_role = None
        reaction_channel.bottom_role = None
        reaction_channel.save()

        await ctx.reply(
            _(ctx, "Role limits for #{channel} were unset.").format(
                channel=channel.name
            )
        )
        await guild_log.info(
            ctx.author,
            ctx.channel,
            f"{reaction_channel.React2name} #{channel.name}'s role limits unset.",
        )

    @commands.guild_only()
    @check.acl2(check.ACLevel.MOD)
    @reaction_channel.command(name="limits", aliases=["set-limits"])
    async def reaction_channel_limits(
        self,
        ctx,
        channel: discord.TextChannel,
        top: discord.Role,
        bottom: discord.Role,
    ):
        """Set top and bottom limits for 'role' channel."""
        reaction_channel = ReactionChannel.get(ctx.guild.id, channel.id)
        if reaction_channel is None:
            await ctx.reply(
                _(ctx, "Channel **#{channel}** is not react2role channel.").format(
                    channel=channel.name
                )
            )
            return
        if reaction_channel.channel_type != ReactionChannelType.ROLE:
            await ctx.reply(_(ctx, "Limiting is only available for 'role' channels."))
            return
        if bottom > top:
            top, bottom = bottom, top

        reaction_channel.top_role = top.id
        reaction_channel.bottom_role = bottom.id
        reaction_channel.save()

        await ctx.reply(
            _(
                ctx, "Role limits for #{channel} were set to **<{top}, {bottom}>**."
            ).format(channel=channel.name, top=top.name, bottom=bottom.name)
        )
        await guild_log.info(
            ctx.author,
            ctx.channel,
            f"{reaction_channel.React2name} #{channel.name}'s "
            f"role limits set to <{top.name}, {bottom.name}>.",
        )

    @commands.guild_only()
    @check.acl2(check.ACLevel.MOD)
    @reaction_channel.command(name="limit", aliases=["set-limit"])
    async def reaction_channel_limit(
        self, ctx, channel: discord.TextChannel, maximum: int
    ):
        """Set role count limit for 'role' channel."""
        reaction_channel = ReactionChannel.get(ctx.guild.id, channel.id)
        if reaction_channel is None:
            await ctx.reply(
                _(ctx, "Channel **#{channel}** is not react2role channel.").format(
                    channel=channel.name
                )
            )
            return
        if reaction_channel.channel_type != ReactionChannelType.ROLE:
            await ctx.reply(_(ctx, "Limiting is only available for 'role' channels."))
            return
        if not reaction_channel.top_role or not reaction_channel.bottom_role:
            await ctx.reply(_(ctx, "You have to set top and bottom roles first."))
            return

        if maximum < 0:
            maximum = 0
        reaction_channel.max_roles = maximum
        reaction_channel.save()

        await ctx.reply(
            _(ctx, "Role limit for #{channel} was set to **{limit}**.").format(
                channel=channel.name, limit=maximum
            )
        )
        await guild_log.info(
            ctx.author,
            ctx.channel,
            f"{reaction_channel.React2name} #{channel.name}'s "
            f"role limit set to {maximum}.",
        )

    @commands.guild_only()
    @check.acl2(check.ACLevel.MOD)
    @reaction_channel.command(name="remove")
    async def reaction_channel_remove(self, ctx, channel: discord.TextChannel):
        """Remove react2role functionality from a channel."""
        reaction_channel = ReactionChannel.get(ctx.guild.id, channel.id)
        if reaction_channel is None:
            await ctx.reply(
                _(ctx, "Channel **#{channel}** is not react2role channel.").format(
                    channel=channel.name
                )
            )
            return

        channel_type: str = reaction_channel.React2name
        ReactionChannel.remove(guild_id=ctx.guild.id, channel_id=channel.id)
        await ctx.reply(
            _(
                ctx,
                "{type} functionality has been removed from **#{channel}**.",
            ).format(type=channel_type, channel=channel.name)
        )
        await guild_log.info(
            ctx.author,
            ctx.channel,
            f"{channel_type} #{channel.name} unset.",
        )

    @commands.guild_only()
    @check.acl2(check.ACLevel.MOD)
    @reaction_channel.command(name="init-channels")
    async def reaction_channel_init_channels(
        self,
        ctx,
        target: discord.TextChannel,
        *,
        channel_groups: str,
    ):
        """Initialise links for react2role functionality.

        Args:
            target: Target text channel that will act as react2role hub.
            channel_groups: Space separated list of channel groups.
        """
        categories: List[discord.CategoryChannel] = []
        channel_count: int = 0
        for name in shlex.split(channel_groups):
            category = discord.utils.get(ctx.guild.categories, name=name)
            if category is None:
                await ctx.reply(
                    _(ctx, "Category **{category}** could not be found.").format(
                        category=utils.text.sanitise(name)
                    )
                )
                return
            categories.append(category)

        for category in categories:
            channel_count += len(category.text_channels)
            # send header
            header_file = BytesIO()
            header_image = helper_utils.generate_header(category.name)
            header_image.save(header_file, "png")
            header_file.seek(0)
            file = discord.File(fp=header_file, filename="category.png")
            await target.send(file=file)

            # send list of channels
            message: List[str] = []
            for i, channel in enumerate(
                sorted(category.text_channels, key=lambda ch: ch.name)
            ):
                if i > 9 and i % 10 == 0:
                    await target.send("\n".join(message))
                    message = []

                num: str = helper_utils.get_digit_emoji(i % 10)
                line = f"{num} **{channel.name}**" + (
                    f" {channel.topic}" if channel.topic else ""
                )
                message.append(line)
            await target.send("\n".join(message))

        await guild_log.info(
            ctx.author,
            ctx.channel,
            f"Initiated react2channel links in #{target.name}",
        )
        await ctx.reply(
            _(ctx, "Processed {channels} channels in {groups} channel groups.").format(
                channels=channel_count, groups=len(categories)
            )
        )

    #

    @commands.Cog.listener()
    async def on_message(self, message):
        """Listen for react2role message."""
        if not isinstance(message.channel, discord.TextChannel):
            return
        reaction_channel = ReactionChannel.get(message.guild.id, message.channel.id)
        if reaction_channel is None:
            return

        await self._handle_react2role_message_update(message, reaction_channel)

    @commands.Cog.listener()
    async def on_raw_message_edit(self, payload: discord.RawMessageUpdateEvent):
        """Listen for react2role message."""
        reaction_channel = ReactionChannel.get(payload.guild_id, payload.channel_id)
        if reaction_channel is None:
            return

        message = await utils.discord.get_message(
            self.bot,
            payload.guild_id or payload.user_id,
            payload.channel_id,
            payload.message_id,
        )
        await self._handle_react2role_message_update(message, reaction_channel)

    async def _handle_react2role_message_update(
        self, message: discord.Message, reaction_channel: ReactionChannel
    ):
        """Check react2role message for emoji changes."""
        # get react2xxx mapping
        mapping = await self._get_react2role_message_mapping(
            message, reaction_channel, announce_warnings=True
        )
        if mapping is None:
            return

        message_emojis = [r.emoji for r in message.reactions]

        mapping_diff: dict = {}
        for emoji in mapping.keys():
            if emoji not in message_emojis:
                await message.add_reaction(emoji)
                mapping_diff[emoji] = mapping[emoji]

        removed_emojis: list = []
        for emoji in message_emojis:
            if emoji not in mapping.keys():
                removed_emojis.append(emoji)

        if mapping_diff:
            diff_str = ", ".join(f"{k} => {v.name}" for k, v in mapping_diff.items())
            await guild_log.info(
                message.author,
                message.channel,
                (
                    f"react2{reaction_channel.channel_type.name.lower()} "
                    f"message updated: added {diff_str}."
                ),
            )

        if removed_emojis:
            diff_str = ", ".join(removed_emojis)
            await guild_log.info(
                message.author,
                message.channel,
                (
                    f"react2{reaction_channel.channel_type.name.lower()} "
                    f"message updated: removed {diff_str}."
                ),
            )

    async def _get_react2role_message_mapping(
        self,
        message: discord.Message,
        reaction_channel: ReactionChannel,
        *,
        announce_warnings: bool,
    ):
        """Get emoji-role or emoji-channel mapping from message."""
        content: List[str] = (
            message.content.replace("*", "")
            .replace("_", "")
            .replace("#", "")
            .split("\n")
        )
        content = [line.strip() for line in content]

        log_messages: List[str] = []

        mapping: dict = {}

        # Because we're converting stuff _here_, we rely on internal functions.
        # The first argument of .convert() is supposed to be 'commands.Context',
        # but as long as we supply all attributes, we should be fine.
        ctx = lambda: None  # noqa: E731
        ctx.bot = self.bot
        ctx.guild = message.guild

        for i, line in enumerate(content, 1):
            line_tokens = line.split(" ")
            if len(line_tokens) < 2:
                log_messages.append(
                    f"Line {i} of message {message.id} does not contain any mapping."
                )
                continue

            emoji_name: str = line_tokens[0]
            name: str = line_tokens[1]

            emoji = None
            try:
                emoji = await commands.EmojiConverter().convert(ctx, emoji_name)
            except commands.EmojiNotFound:
                # try to check if the string is emoji
                if emoji_name in EMOJI_DATA:
                    emoji = emoji_name

            if emoji is None:
                log_messages.append(
                    f"Line {i} of message {message.id} does not start with emoji."
                )
                continue

            if reaction_channel.channel_type == ReactionChannelType.ROLE:
                try:
                    target = await commands.RoleConverter().convert(ctx, name)
                except commands.BadArgument:
                    target = None
            else:
                try:
                    target = await commands.GuildChannelConverter().convert(ctx, name)
                except commands.BadArgument:
                    target = None

            if target is None:
                target_name: str = reaction_channel.channel_type.value
                await guild_log.error(
                    None,
                    message.channel,
                    (
                        f"React2Role error, line {i} of message {message.id} "
                        f"does does not have valid {target_name} "
                        f"after the emoji '{emoji}': '{name}' not found."
                    ),
                )
                return

            if emoji in mapping:
                await guild_log.error(
                    None,
                    message.channel,
                    f"React2Role error, line {i} of message {message.id}"
                    f" contains duplicate emoji {emoji}.",
                )
                return

            mapping[emoji] = target

        if log_messages and announce_warnings:
            await guild_log.warning(
                None,
                message.channel,
                "React2Role encountred unexpected lines: " + " ".join(log_messages),
            )

        return mapping

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent):
        reaction_channel = ReactionChannel.get(payload.guild_id, payload.channel_id)
        if reaction_channel is None:
            return

        message = await utils.discord.get_message(
            self.bot,
            payload.guild_id or payload.user_id,
            payload.channel_id,
            payload.message_id,
        )

        mapping = await self._get_react2role_message_mapping(
            message, reaction_channel, announce_warnings=False
        )
        if mapping is None:
            return

        member = message.guild.get_member(payload.user_id)
        if member.bot:
            return

        if payload.emoji.is_custom_emoji():
            emoji = self.bot.get_emoji(payload.emoji.id) or payload.emoji
        else:
            emoji = payload.emoji.name

        if reaction_channel.channel_type == ReactionChannelType.CHANNEL:
            channel = mapping[emoji]
            await channel.set_permissions(member, view_channel=True)
            await guild_log.debug(
                member,
                message.channel,
                f"Adding permission to view {channel.name} ({channel.id}).",
            )
            return

        utx = i18n.TranslationContext(member.guild.id, member.id)

        role = mapping[emoji]
        # TODO Allow escalation under some conditions?
        if role >= member.top_role:
            await member.send(
                _(
                    utx,
                    (
                        "You cannot ask for role that's higher "
                        "than your current highest role."
                    ),
                )
            )
            await utils.discord.remove_reaction(message, emoji, member)
            return

        if reaction_channel.top_role is None or reaction_channel.bottom_role is None:
            # The channel does not have any limits
            await member.add_roles(role)
            return

        top_role = message.guild.get_role(reaction_channel.top_role)
        if top_role is None:
            await guild_log.error(
                member,
                message.channel,
                f"react2role top role {reaction_channel.top_role} is unavailable.",
            )
            await utils.discord.remove_reaction(message, emoji, member)
            return
        if role >= top_role:
            await member.send(_(utx, "This role can't be currently assigned."))
            await guild_log.debug(
                member,
                message.channel,
                (
                    f"react2role '{role}' cannot be assigned becase "
                    "it's higher than configured top role for the channel."
                ),
            )
            await utils.discord.remove_reaction(message, emoji, member)
            return

        bottom_role = message.guild.get_role(reaction_channel.bottom_role)
        if bottom_role is None:
            await guild_log.error(
                member,
                message.channel,
                f"react2role bottom role {reaction_channel.bottom_role} is unavailable.",
            )
            await utils.discord.remove_reaction(message, emoji, member)
            return
        if role <= bottom_role:
            await member.send(_(utx, "This role can't be currently assigned."))
            await utils.discord.remove_reaction(message, emoji, member)
            await guild_log.debug(
                member,
                message.channel,
                (
                    f"react2role '{role}' cannot be assigned becase "
                    "it's lower than configured bottom role for the channel."
                ),
            )
            await utils.discord.remove_reaction(message, emoji, member)
            return

        inbetween_roles: list = [r for r in member.roles if bottom_role < r < top_role]
        if len(inbetween_roles) >= reaction_channel.max_roles:
            await member.send(
                _(
                    utx,
                    (
                        "This role category has a limit of **{limit} roles**. "
                        "Remove some of your roles before adding new ones."
                    ),
                ).format(limit=reaction_channel.max_roles)
            )
            await utils.discord.remove_reaction(message, emoji, member)
            return

        await member.add_roles(role)
        await guild_log.debug(
            member,
            message.channel,
            f"Adding role {role.name} ({role.id}).",
        )

    @commands.Cog.listener()
    async def on_raw_reaction_remove(self, payload: discord.RawReactionActionEvent):
        reaction_channel = ReactionChannel.get(payload.guild_id, payload.channel_id)
        if reaction_channel is None:
            return

        message = await utils.discord.get_message(
            self.bot,
            payload.guild_id or payload.user_id,
            payload.channel_id,
            payload.message_id,
        )

        mapping = await self._get_react2role_message_mapping(
            message, reaction_channel, announce_warnings=False
        )
        if mapping is None:
            return

        member = message.guild.get_member(payload.user_id)
        if member.bot:
            return

        if payload.emoji.is_custom_emoji():
            emoji = self.bot.get_emoji(payload.emoji.id) or payload.emoji
        else:
            emoji = payload.emoji.name

        if reaction_channel.channel_type == ReactionChannelType.CHANNEL:
            channel = mapping[emoji]
            await channel.set_permissions(member, overwrite=None)
            await guild_log.debug(
                member,
                message.channel,
                f"Removing permission to view {channel.name} ({channel.id}).",
            )
            return

        utx = i18n.TranslationContext(member.guild.id, member.id)

        role = mapping[emoji]
        if member.top_role == role:
            await member.send(_(utx, "You cannot remove your top role."))
            return

        if reaction_channel.top_role is None or reaction_channel.bottom_role is None:
            # The channel does not have any limits
            await member.remove_roles(role)
            return

        top_role = message.guild.get_role(reaction_channel.top_role)
        if top_role is None:
            await guild_log.error(
                member,
                message.channel,
                f"react2role top role {reaction_channel.top_role} is unavailable.",
            )
            return

        bottom_role = message.guild.get_role(reaction_channel.bottom_role)
        if bottom_role is None:
            await guild_log.error(
                member,
                message.channel,
                f"react2role bottom role {reaction_channel.bottom_role} is unavailable.",
            )
            return

        await member.remove_roles(role)
        await guild_log.debug(
            member,
            message.channel,
            f"Removing role {role.name} ({role.id}).",
        )

async def setup(bot) -> None:
    await bot.add_cog(React2Role(bot))


## Calculate how long it will take to save for a
# down payment given the following assumptions:

## User input
annual_salary = int(input("Enter your annual salary: ")) # Annual salary

## Given assumptions
total_cost =  1000000 # Cost of your dream home
semi_annual_raise = 0.07 # Raise every 6 months (e.g 0.03 = 3%)
portion_down_payment = 0.25 # Down payment (e.g. 0.25 = 25%)
r = 0.04 # 4% rate of return on the current savings
current_savings = 0

## Bisection Search
epsilon = 100 # Within $100 of required down payment
low = 0
high = 10000
portion_saved = (high+low)/2.0
numSteps = 0
notPossible = False
while abs(current_savings - total_cost*portion_down_payment) >= epsilon:
    current_savings = 0
    monthly_salary = annual_salary/12
    monthly_savings = monthly_salary*portion_saved/10000
    for month in range(36):
        if month % 6 == 0 and month != 0:
            monthly_salary *= 1+semi_annual_raise
            monthly_savings = monthly_salary*portion_saved/10000
        current_savings += current_savings*r/12 + monthly_savings
    if current_savings > total_cost*portion_down_payment:
        high = portion_saved
    else:
        low = portion_saved
    portion_saved = int(high+low)/2.0
    if portion_saved == 9999:
        notPossible = True
        break
    numSteps += 1

if notPossible:
    print("It is not possible to pay the down payment in three years.")
else:
    print("Best savings rate:", portion_saved/10000)
    print("Steps in bisection search:", numSteps)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 20 08:29:40 2017

@author: brendontucker

practice for upwork postings on data mining
"""

import bs4 as bs
import urllib.request

sauce = urllib.request.urlopen('http://georgia.bizhwy.com/businesses.php?c=349').read()

soup = bs.BeautifulSoup(sauce, 'lxml')

#print(soup.find_all('b'))

NameList = list()
for bold in soup.find_all('b'):
    NameList.append(bold.string)

print(NameList)


import re

def get_terms(query):
    """Return a list of search terms from a query.

    If there is a set of " chars, then we will treat the contents as one term
    """
    if isinstance(query, str):
        query = query.encode('utf-8')
    terms = []
    pos = 0
    def add_unquoted_term(t):
        terms.extend(t.split())
    while pos < len(query):
        try:
            quote_start = query.index(u'"', pos)
        except ValueError:
            add_unquoted_term(query[pos:])
            break
        if quote_start > pos:
            add_unquoted_term(query[pos:quote_start])
        pos = quote_start + 1
        try:
            quote_end = query.index(u'"', pos)
        except ValueError:
            add_unquoted_term(query[pos:])
            break
        terms.append(query[pos:quote_end])
        pos = quote_end + 1
    terms = apply_term_filter(terms)
    return [t for t in terms if t]

# regex to remove chars that cause issues in queries
term_filter = re.compile(r'[<>@]', re.UNICODE)

def apply_term_filter(terms):
    return [term_filter.sub('', t) for t in terms]


import albumentations as A

def get_augmentation(version):
    if version == 1:
        # for details see: /utils/image_normalization.py
        normalization = A.Normalize(mean=0.499, std=0.198, p=1)
        augmentation = {
            "train": A.Compose([
                A.HorizontalFlip(p=0.5),
                A.RandomBrightnessContrast(brightness_limit=0.3, contrast_limit=0.3, p=0.25),
                A.Blur(blur_limit=4, always_apply=False, p=0.25),
                normalization
            ]),
            "valid": normalization
        }
    elif version == 2:
        # for details see: /utils/image_normalization.py
        normalization = A.Normalize(mean=0.499, std=0.198, p=1)
        augmentation = {
            "train": A.Compose([
                A.HorizontalFlip(p=0.5),
                A.RandomBrightnessContrast(brightness_limit=0.5, contrast_limit=0.5, p=0.25),
                A.Blur(blur_limit=5, always_apply=False, p=0.25),

                A.OneOf([
                    A.ElasticTransform(p=1, alpha=120, sigma=120 * 0.05, alpha_affine=120 * 0.03,),
                    A.GridDistortion(p=1),
                ], p=0.25),

                normalization
            ]),
            "valid": normalization
        }
    else:
        raise Exception(f"Augmentation version '{version}' is unknown!")
    return augmentation


#
# Author: Satoru SATOH <ssato redhat.com>
# License: GPLv3+
#
"""/etc/ssh/sshd_config format:

#Port 22
#Protocol 2,1
Protocol 2
#AddressFamily any
...
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
...

# override default of no subsystems
Subsystem       sftp    /usr/libexec/openssh/sftp-server
"""
import sos_analyzer.scanner.base

class Scanner(sos_analyzer.scanner.base.SinglePatternScanner):

    name = input_name = "etc/ssh/sshd_config"
    pattern = r"^(?P<config>[A-Z]\S+)\s+(?P<value>\S.*)$"

# vim:sw=4:ts=4:et:


import random

NUMBER_OF_ITERATIONS = 20
SIZE_OF_KEYS_IN_BITS = 20

def order(p, f, a):
    """
    Practical 1:
    order(p, f, a) will  return  the  order of a in  the  group Z∗p
    where: f is  a  list  of  the  prime  factors of p - 1
    Ensure  that  your  method  works  when f contains  duplicates. Consider where p = 17
    """
    t = p - 1
    for factor in f:
        t_tilda = t // factor
        a_raised = pow(a, t_tilda) % p
        if not a_raised == 1 % p:
            return t
        else:
            t = t_tilda

def findg(p, f):
    """
    Practical 2:
    find(p, f) will return a generator of Z*p where p is a prime and f is a list of the prime factors of p - 1
    """
    while True:
        candidate = random.randint(1, p - 1)
        if order(p, f, candidate) == p - 1:
            return candidate

def pair(d):
    """
    Practical 3:
    pair(d) will return (p, a) containing a safe prime p with d bits and a generator a for Z*p
    A safe prime is a prime q where 2q + 1 is also a prime
    """
    # Half the size of the prime being generated
    length = d // 2
    while True:
        q = gen_d_bit_prime(length)
        if fermat(q, NUMBER_OF_ITERATIONS):
            p = 2 * q + 1
            if fermat(p, NUMBER_OF_ITERATIONS):
                return p, findg(p, [2, q])

def log(p, a, x):
    """
    Practical 4:
    log(p, a, x) will return log a x in the cyclic group Z*p where p is a prime and a is a generator
    """

def egKey(s):
    """
    Practical 5:
    egKey(s) will return a tuple (p, a, x, y) where p is a safe prime, a is a generator, and x & y are the public
    and private components of the Elgamal Key
    """
    prime, generator = pair(s)
    x = random.randint(1, prime)
    y = pow(generator, x) % prime
    return prime, generator, x, y

def egEnc(p, a, y, m):
    """
    Practical 5:
    egEnc(p, a, y, m) will return the tuple (c1, c2)
    """
    k = random.randint(1, p - 1)
    c1 = pow(a, k) % p
    c2 = m * pow(y, k) % p
    return c1, c2

def egDec(p, x, c1, c2):
    """
    Practical 5:
    egDec(p, x, c1, c2) wil return the original message m
    """
    exponent = p - 1 - x
    return pow(c1, exponent) * c2 % p

def main():
    p, a, x, y = egKey(SIZE_OF_KEYS_IN_BITS)
    m = ""
    c1, c2 = egEnc(p, a, y, m)
    mDec = egDec(p, x, c1, c2)
    print(mDec)

##############################################################################################################
############################################## Helper Functions ##############################################
##############################################################################################################

def prime_factors(n):
    i = 2
    factors = []
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n = n // i
            factors.append(i)
    if n > 1:
        factors.append(n)
    return factors

def fermat(x, t):
    if x == 2:
        return True
    if x % 2 == 0:
        return False
    for _ in range(t):
        try:
            candidate = random.randint(1, x - 1)
        except ValueError:
            continue
        if pow(candidate, x - 1) % x != 1:
            return False
    return True

def gen_d_bit_prime(d):
    while True:
        candidate = random.getrandbits(d)
        if fermat(candidate, NUMBER_OF_ITERATIONS):
            return candidate


# Scrivi una funzione "file_backup" che sia in grado di effettuare copie di backup di determinati tipi di file, con le seguenti caratteristiche:
#
# Percorso da scansionare, di backup e tipologia di file da copiare dovranno essere passati dall'utente tramite input
# Il programma dovrà verificare la presenza o meno di una cartella di backup al percorso fornito, e qualora questa non fosse presente dovrà crearla
# La funzione dovrà anche gestire l'eventuale scelta da parte dell'utente, di un percorso da scansionare che non esiste
import os
import shutil

folder = input('inserisci il percorso da copiare (' + os.getcwd() + '\\immagini) :')
extension = input('inserisci il tipo di file (default: jpg):')
folder_backup = input('inserisci il percorso di backup' + os.getcwd() + '\\backup' + ':')
if folder == '':
    folder = os.getcwd() + '\\immagini'
if extension == '':
    extension = 'jpg'
if folder_backup == '':
    folder_backup = os.getcwd() + '\\backup'

if not os.path.exists(folder):
    print(f'path non esiste {folder}')
    exit(404)
if not os.path.exists(folder_backup):
    print('path non esiste (folder_backup)')
    exit(404)
# giving file extension
ext = (extension,)

# iterating over all files
for file in os.listdir(folder):
    if file.endswith(ext):
        shutil.copyfile(folder + '\\' + file, folder_backup + '\\' + file)
    else:
        continue
else:
    print('copia terminata')


import itertools

# 括弧列が正しいかどうかの必要十分条件は以下
# ・'('と')'の数が等しい
# ・すべてのi (1 <= i <= N)に対して左からi番目までの時点で'('の数が')'よりも多い

def check_pair(i):
    if i[0] != '(':
        return False
    right = 0
    left = 0
    for x in i:
        if x == '(':
            left += 1
        else:
            right += 1
        if left < right:
            return False
    return True

N = int(input())
P = itertools.product('()', repeat = N)
for i in P:
    if check_pair(i) and i.count('(') == i.count(')'):
        print(*i, sep='')


import inspect
import logging
import csv
from openpyxl import Workbook, load_workbook

class Utils():
    def __init__(self):
        self.log_level = logging.DEBUG

    def set_log_level(self, log_level):
        self.log_level = log_level

    # Return logger object for logging test information
    def custom_logger(self):
        # Set to class name, helps with troubleshooting when looking at automation log
        logger_name = inspect.stack()[1][3]
        # logger creation
        logger = logging.getLogger(logger_name)
        logger.setLevel(self.log_level)
        # create handler
        file_handler = logging.FileHandler("..\\Reports\\automation.log", mode="a")
        # create formatter and add to handler
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s : %(message)s',
                                      datefmt="%m/%d/%Y %I:%M:%S %p")
        file_handler.setFormatter(formatter)
        # add console handler to logger
        logger.addHandler(file_handler)
        return logger

    @staticmethod
    def read_data_from_excel(file_name, sheet):
        data_list = []
        work_book = load_workbook(filename=file_name)
        sheet = work_book[sheet]
        row_ct = sheet.max_row
        col_ct = sheet.max_column

        for i in range(2, row_ct + 1):
            row = []
            for j in range(1, col_ct + 1):
                row.append(sheet.cell(row=i, column=j).value)
            data_list.append(row)
        print(data_list)
        return data_list

    @staticmethod
    def read_data_from_csv(file_name):
        data_list = []
        # Open CSV file
        csv_data = open(file_name, "r")
        # Create CSV reader
        reader = csv.reader(csv_data)
        # Skip first line
        next(reader)
        # Add CSV data to data_list
        for row in reader:
            data_list.append(row)
        return data_list


import re
import logging
import itertools
import math
import typing
from typing import (Union, Optional, Callable, TypeVar, cast, )

ExtInt = Union[int, float]
Variable = typing.NewType('Variable', str)
Placeholder = typing.NewType('Placeholder', str)
Normalization = tuple[Variable, Optional[Placeholder], int]

TConstraint = TypeVar("TConstraint", bound="Constraint")
TComparison = TypeVar("TComparison", bound="Comparison")

class Constraint:

    def __init__(self) -> None:
        self.lower_bound: ExtInt = -math.inf
        self.upper_bound: ExtInt = math.inf
        self.inequal_values: set[int] = set()

    def update_upper_bound(
        self: TConstraint,
        upper_bound: ExtInt,
        inclusive: bool = True
    ) -> TConstraint:
        if not inclusive:
            upper_bound -= 1
        self.upper_bound = min(self.upper_bound, upper_bound)
        return self

    def update_lower_bound(
        self: TConstraint,
        lower_bound: ExtInt,
        inclusive: bool = True
    ) -> TConstraint:
        if not inclusive:
            lower_bound += 1
        self.lower_bound = max(self.lower_bound, lower_bound)
        return self

    def add_inequal_value(
        self: TConstraint,
        not_equal: int
    ) -> TConstraint:
        self.inequal_values.add(not_equal)
        return self

    def update(
        self: TConstraint, comparator: int, number: int
    ) -> TConstraint:
        inclusive = (abs(comparator) == 1)

        if comparator == 0:
            self.add_inequal_value(number)
        elif comparator == 3:
            self.update_upper_bound(number, True)
            self.update_lower_bound(number, True)
        elif comparator < 0:
            self.update_upper_bound(number, inclusive)
        else:
            self.update_lower_bound(number, inclusive)
        return self

    def update_constraint(
        self: TConstraint, constraint: TConstraint
    ) -> TConstraint:
        self.update_upper_bound(constraint.upper_bound)
        self.update_lower_bound(constraint.lower_bound)
        for inequal in constraint.inequal_values:
            self.add_inequal_value(inequal)
        return self

    def __str__(self) -> str:
        return f"{self.lower_bound} <= ... <= {self.upper_bound}"

class Comparison:

    def __init__(self) -> None:
        self.lower_variables: set[tuple[Variable, bool]] = set()
        self.upper_variables: set[tuple[Variable, bool]] = set()
        self.inequal_variables: set[Variable] = set()

    def add_lower_variable(
        self: TComparison,
        lower_bound: Variable,
        inclusive: bool
    ) -> TComparison:
        self.lower_variables.add((lower_bound, inclusive))
        return self

    def add_upper_variable(
        self: TComparison,
        upper_bound: Variable,
        inclusive: bool
    ) -> TComparison:
        self.upper_variables.add((upper_bound, inclusive))
        return self

    def add_inequal_variable(
        self: TComparison,
        inequal: Variable
    ) -> TComparison:
        self.inequal_variables.add(inequal)
        return self

    def update(
        self: TComparison,
        comparator: int,
        target: Variable
    ) -> TComparison:

        # update compare dict
        inclusive = (abs(comparator) == 1)

        if comparator == 3:
            self.add_upper_variable(target, True)
            self.add_lower_variable(target, True)
        elif comparator < 0:
            self.add_upper_variable(target, inclusive)
        elif comparator > 0:
            self.add_lower_variable(target, inclusive)
        else:
            self.add_inequal_variable(target)
        return self

    def update_comparison(
        self: TComparison,
        comparison: TComparison
    ) -> TComparison:
        for lower_variable, inclusive in self.lower_variables:
            comparison.add_lower_variable(lower_variable, inclusive)
        for upper_variable, inclusive in self.upper_variables:
            comparison.add_upper_variable(upper_variable, inclusive)
        for inequal_variable in self.inequal_variables:
            comparison.add_inequal_variable(inequal_variable)
        return self

    def __str__(self) -> str:
        return " ".join([
            f"{self.lower_variables}",
            f"<= {{}} (!= {self.inequal_variables})",
            f"<= {self.upper_variables}",
        ])

Parsed = tuple[
    dict[Variable, Constraint],
    dict[Variable, Comparison],
    set[Placeholder]
]

def parse_comparand(text: str) -> Union[Variable, int]:
    number_cbe_match = _RE_NUMBER_CBE.fullmatch(text)

    if not number_cbe_match:
        return Variable(text)

    coefficient, base, exponent = number_cbe_match.group(1, 2, 3)

    if coefficient is None:
        coefficient = "1"
    if exponent is None:
        exponent = "1"

    return int(coefficient) * (int(base) ** int(exponent))

def _update_constraints_and_comparisons(
    text: str,
    constraints: dict[Variable, Constraint],
    comparisons: dict[Variable, Comparison],
    term_constraints: list[tuple[str, str, str]],
) -> None:

    text = text.replace(" ", "")

    comparators = list(map(_parse_comparator, _RE_COMPARATOR.findall(text)))
    comparandss = [
        _parse_comparands(piece) for piece in _RE_COMPARATOR.split(text)
    ]

    term_indicators = ['min', 'max', '^', '*', '+', '-']

    for i, comparator in enumerate(comparators):
        lefts = comparandss[i]
        rights = comparandss[i+1]

        comparator_str = _comparator_to_str(comparator)

        for left, right in itertools.product(lefts, rights):

            is_left_number = (type(left) is int)
            is_right_number = (type(right) is int)

            # XXX: Hard-coded
            if not is_right_number:
                if right[-2:] == '-1' and comparator_str == '<=':
                    right = right[:-2]
                    comparator = _parse_comparator('<')
                elif right[-2:] == '+1' and comparator_str == '>=':
                    right = right[:-2]
                    comparator = _parse_comparator('>')
            elif not is_left_number:
                if left[-2:] == '+1' and comparator_str == '<=':
                    left = left[:-2]
                    comparator = _parse_comparator('<')
                elif left[-2:] == '-1' and comparator_str == '>=':
                    left = left[:-2]
                    comparator = _parse_comparator('>')

            # update term constraint
            def is_term(term: Union[str, int]):
                if type(term) is int:
                    return False
                return any(indicator in term for indicator in term_indicators)

            if is_term(left) or is_term(right):
                term_constraints.append(
                    (left, _comparator_to_str(comparator), right))
                continue

            if not is_left_number and not is_right_number:

                left_variable = cast(Variable, left)
                right_variable = cast(Variable, right)

                comparison = (
                    comparisons.setdefault(left_variable, Comparison()))
                comparison.update(comparator, right_variable)

                comparison = (
                    comparisons.setdefault(right_variable, Comparison()))
                comparison.update(-comparator, left_variable)

            elif is_left_number != is_right_number:
                # update constraint dict
                _comparator = comparator
                if is_left_number:
                    left, right = right, left
                    _comparator *= -1

                variable = cast(Variable, left)
                number = cast(int, right)

                constraints.setdefault(variable, Constraint())
                constraints[variable].update(_comparator, number)

            else:  # E.g., 1 < 3
                continue

def _to_transitive_bound(
    variable: Variable,
    constraints: dict[Variable, Constraint],
    comparisons: dict[Variable, Comparison],
    visited: Optional[set[Variable]],
    reverse: bool = False
) -> tuple[ExtInt, set[tuple[Variable, bool]]]:
    """Make ``comparisons`` be transitive closure and update ``constraints``

    Args:
        variable: A variable
        comparisons: Constraints
        comparisons: Comparisons
        reverse: The function is called for upper bounds
        visited: Visited variables

    Returns:
        Updated lower (upper) bound and lower (upper) variables of ``variable``
    """
    if visited is None:
        visited = set()

    constraint = constraints[variable]
    comparison = comparisons[variable]
    if variable in visited:
        if not reverse:
            return constraint.lower_bound, comparison.lower_variables
        else:
            return constraint.upper_bound, comparison.upper_variables

    visited.add(variable)

    get_bound: Callable[[Constraint], ExtInt]
    update_bound: Callable[[ExtInt, bool], Constraint]
    bound_variables = None
    add_bound_variable: Callable[[Variable, bool], Comparison]
    if not reverse:
        def get_bound(constraint: Constraint): return constraint.lower_bound
        update_bound = constraint.update_lower_bound
        bound_variables = comparison.lower_variables
        add_bound_variable = comparison.add_lower_variable
    else:
        def get_bound(constraint: Constraint): return constraint.upper_bound
        update_bound = constraint.update_upper_bound
        bound_variables = comparison.upper_variables
        add_bound_variable = comparison.add_upper_variable

    bound = get_bound(constraint)
    for bound_variable, inclusive1 in bound_variables.copy():
        updated_bound, updated_variables = _to_transitive_bound(
            bound_variable, constraints, comparisons, visited, reverse)
        bound = get_bound(update_bound(updated_bound, inclusive1))

        for next_variable, inclusive2 in updated_variables:
            inclusive = inclusive1 and inclusive2
            add_bound_variable(next_variable, inclusive)

    return bound, bound_variables

def _split(variable: Variable) -> tuple[str, Optional[str]]:
    tmp = variable.rsplit('_', 1)
    if len(tmp) != 2:
        return tmp[0], None
    return tmp[0], tmp[1]

def _normalize_comparison(
    placeholder: Placeholder,
    comparison: Comparison,
    decrease: bool,
) -> Comparison:

    normalized_comparison = Comparison()

    modify_subscript: Callable[[str], str]
    if decrease:
        def modify_subscript(subscript: str):
            if subscript == f'{placeholder}+1':
                return f'{placeholder}'
            elif subscript == f'{placeholder}':
                return f'{placeholder}-1'
            else:
                return subscript
    else:
        def modify_subscript(subscript: str):
            if subscript == f'{placeholder}-1':
                return f'{placeholder}'
            elif subscript == f'{placeholder}':
                return f'{placeholder}+1'
            else:
                return subscript

    def modify(variable: Variable):
        fragment, subscript = _split(variable)
        if subscript is None:
            return variable
        subscript = modify_subscript(subscript)
        return Variable(f"{fragment}_{subscript}")

    for lower_variable, inclusive in comparison.lower_variables:
        lower_variable = modify(lower_variable)
        normalized_comparison.add_lower_variable(lower_variable, inclusive)

    for upper_variable, inclusive in comparison.upper_variables:
        upper_variable = modify(upper_variable)
        normalized_comparison.add_upper_variable(upper_variable, inclusive)

    for inequal_variable in comparison.inequal_variables:
        inequal_variable = modify(inequal_variable)
        normalized_comparison.add_inequal_variable(inequal_variable)

    return normalized_comparison

def normalize_variable(
    variable: Variable
) -> Normalization:
    fragment, subscript = _split(variable)
    if subscript is None or len(subscript) < 3:
        return variable, None, 0

    # XXX: Hard-coded
    if not subscript[-2:] in {"-1", "+1"}:
        return variable, None, 0

    delta = int(subscript[-2:])
    placeholder = Placeholder(subscript[:-2])

    return Variable(f"{fragment}_{placeholder}"), placeholder, delta

def parse(
    constraint_strings: list[str]
) -> Parsed:
    constraints: dict[Variable, Constraint] = {}
    comparisons: dict[Variable, Comparison] = {}
    term_constraints: list[tuple[str, str, str]] = []
    placeholders: set[Placeholder] = set()

    for constraint_string in constraint_strings:
        _update_constraints_and_comparisons(
            constraint_string, constraints, comparisons, term_constraints)

    variables = set(constraints.keys()) | set(comparisons.keys())
    for variable in variables:
        comparisons.setdefault(variable, Comparison())
        constraints.setdefault(variable, Constraint())

    lower_visited: set[Variable] = set()
    upper_visited: set[Variable] = set()
    for variable in variables:
        _to_transitive_bound(
            variable, constraints, comparisons, lower_visited)
        _to_transitive_bound(
            variable, constraints, comparisons, upper_visited, reverse=True)

    subscripts: set[str] = set()
    for variable in variables:
        _, subscript = _split(variable)
        if subscript is not None and subscript not in variables:
            subscripts.add(subscript)

    for subscript in subscripts:
        def proper_substring(a, b): return a != b and a in b
        if all(map(lambda e: not proper_substring(e, subscript), subscripts)):
            placeholders.add(Placeholder(subscript))

    for variable in variables:
        variable_normalization = normalize_variable(variable)
        normalized_variable, placeholder, delta = variable_normalization

        if placeholder is None or delta == 0:
            continue

        if delta not in [-1, 0, 1]:
            raise NotImplementedError("Placeholder delta must be -1, 0, or 1")

        placeholders.add(placeholder)

        if delta == 0:
            continue

        decrease = (delta == 1)

        constraint = constraints[variable]
        constraint.update_constraint(
            constraints.setdefault(normalized_variable, Constraint()))

        comparison = _normalize_comparison(
            placeholder, comparisons[variable], decrease)
        comparison.update_comparison(
            comparisons.setdefault(normalized_variable, Comparison()))

        constraints.pop(variable, None)
        comparisons.pop(variable, None)

    return constraints, comparisons, term_constraints, placeholders

_RE_COMPARATOR = re.compile(r'<=|>=|<|>|!=')
_RE_NUMBER_CBE = re.compile(r'(?:(-?\d+)\*)?(-?\d+)(?:\^(-?\d+))?')
_RE_MIN_OR_MAX = re.compile(r'(?:min|max)\((\w+(,\w+)*)\)')

def _comparator_to_str(comparator: int) -> str:
    return {-2: "<", -1: "<=", 0: "!=", 1: ">=", 2: ">", 3: "="}[comparator]

def _parse_comparator(text: str) -> int:
    return {"<": -2, "<=": -1, "!=": 0, ">=": 1, ">": 2, "=": 3}[text]

def _parse_comparands(text: str) -> list[Union[int, Variable]]:
    pieces: list[str] = []
    # FIXME: Currently, we do not consider minimum or maximum.
    match = _RE_MIN_OR_MAX.fullmatch(text)
    if match:
        pieces = match.group(1).split(',')
    else:
        pieces = text.split(',')
    return [parse_comparand(e) for e in pieces]

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)

    # constraint_strings = ['0 <= a_i < 100', 'a_i < a_i+1']
    constraint_strings = ['0 <= A < B < C < D < 4']
    constraints, comparisons, _, placeholders = parse(constraint_strings)

    print({k: str(v) for k, v in constraints.items()})
    print({k: str(v) for k, v in comparisons.items()})
    print(placeholders)


from __future__ import print_function
import sys
import time
from random import random
from operator import add

from pyspark import SparkContext

if __name__ == "__main__":
    sc = SparkContext(appName="PythonPi")
    partitions = int(sys.argv[1]) if len(sys.argv) > 1 else 2
    n = 100000 * partitions

    def f(_):
        x = random() * 2 - 1
        y = random() * 2 - 1
        return 1 if x ** 2 + y ** 2 < 1 else 0

    start = time.time()
    print("iterations: %d" % n)
    count = sc.parallelize(range(1, n + 1), partitions).map(f).reduce(add)
    print("exec time %f" % (time.time()-start))
    print("Pi is roughly %f" % (4.0 * count / n))

    sc.stop()


import crypto
import os
import random
import struct
import sys
import argparse
from Crypto.Cipher import AES

def encrypt(key, filename, chunksize=64*1024):
    if filename.endswith('.aes'):
        print('[-] File already encrypted. Aborting...')

    if not os.path.exists(filename):
        print('[-] File: ' + filename + ' does not exist.')
        exit(-1)

    out_filename = filename + '.aes'
    print(out_filename)

    iv = ''.join([chr(random.randint(0, 0xFF)) for i in range(16)])
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    filesize = os.path.getsize(filename)

    with open(filename, 'rb') as infile:
        with open(out_filename, 'wb') as outfile:
            outfile.write(struct.pack('<Q', filesize))
            outfile.write(iv)

            while True:
                chunk = infile.read(chunksize)
                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                    chunk += (' ' * (16 - len(chunk) % 16))

                outfile.write(encryptor.encrypt(chunk))

    os.remove(filename)

def decrypt(key, filename, chunksize=24*1024):
    if not filename.endswith('.aes'):
        print("[-] Must have a file with extension '.aes' to decrypt.")
        exit(-1)

    if not os.path.exists(filename):
        print('[-] File: ' + filename + ' does not exist.')
        exit(-1)

    out_filename = filename.replace('.aes', '')

    with open(filename, 'rb') as infile:
        origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
        iv = infile.read(16)
        decryptor = AES.new(key, AES.MODE_CBC, iv)

        with open(out_filename, 'wb') as outfile:
            while True:
                chunk = infile.read(chunksize)
                if len(chunk) == 0:
                    break
                outfile.write(decryptor.decrypt(chunk))

            outfile.truncate(origsize)

    os.remove(filename)

def main(argv):

    parser = argparse.ArgumentParser()
    parser.add_argument("-a", "--action", help="ENCRYPT/DECRYPT")
    parser.add_argument("-i", "--input", help="input file required")
    parser.add_argument("-k", "--key", help="minimum 16 char key required")

    args = parser.parse_args()

    if args.action is None:
        print('[-] Must supply -a ENCRYPT/DECRYPT action.')
        exit(-1)

    if args.input is None:
        print('[-] Input file required.')
        exit(-1)

    if args.key is None or len(args.key) < 16:
        print('[-] Minimum 16 character encryption key required".')
        exit(-1)

    if args.action.upper() == 'ENCRYPT':
        encrypt(args.key, args.input)
    elif args.action.upper() == 'DECRYPT':
        decrypt(args.key, args.input)
    else:
        print('[-] Must supply -a ENCRYPT/DECRYPT action.')

if __name__ == "__main__":
    main(sys.argv[1:])


from __future__ import annotations

import os
from dataclasses import dataclass

import tornado.web

from marimo import _loggers
from marimo._server import sessions
from marimo._server.api import status
from marimo._server.api.validated_handler import ValidatedHandler
from marimo._server.utils import canonicalize_filename
from marimo._utils.parse_dataclass import parse_raw

LOGGER = _loggers.marimo_logger()

@dataclass
class Rename:
    filename: str

class RenameHandler(ValidatedHandler):
    """Rename the current app."""

    @sessions.requires_edit
    def post(self) -> None:
        mgr = sessions.get_manager()
        args = parse_raw(self.request.body, Rename)
        filename = args.filename
        LOGGER.debug("Renaming from %s to %s", mgr.filename, filename)
        if filename is not None:
            filename = canonicalize_filename(filename)

        if filename == mgr.filename:
            # no-op
            pass
        elif filename is None:
            mgr.rename(filename)
        elif os.path.exists(filename):
            raise tornado.web.HTTPError(
                status.HTTPStatus.METHOD_NOT_ALLOWED,
                reason="File {0} already exists".format(filename),
            )
        elif mgr.filename is None:
            try:
                # create a file named `filename`
                with open(filename, "w") as _:
                    pass
            except Exception as err:
                raise tornado.web.HTTPError(
                    status.HTTPStatus.SERVER_ERROR,
                    reason="Failed to create file {0}".format(filename),
                ) from err
            mgr.rename(filename)
        else:
            try:
                os.rename(mgr.filename, filename)
            except Exception as err:
                raise tornado.web.HTTPError(
                    status.HTTPStatus.SERVER_ERROR,
                    reason="Failed to rename from {0} to {1}".format(
                        mgr.filename, filename
                    ),
                ) from err
            mgr.rename(filename)


# coding=utf-8
from __future__ import absolute_import

import torch
from torch import nn
from torch.autograd import Variable
# import numpy as np

class AHardPair(nn.Module):
    def __init__(self, alpha=40, beta=20):
        super(AHardPair, self).__init__()
        self.alpha = alpha
        self.beta = beta

    def forward(self, inputs, targets):
        n = inputs.size(0)
        # Compute pairwise distance
        dist_mat = euclidean_dist(inputs)
        targets = targets.cuda()
        # split the positive and negative pairs
        eyes_ = Variable(torch.eye(n, n)).cuda()
        # eyes_ = Variable(torch.eye(n, n))
        pos_mask = targets.expand(n, n).eq(targets.expand(n, n).t())
        neg_mask = eyes_.eq(eyes_) - pos_mask
        pos_mask = pos_mask - eyes_.eq(1)

        pos_dist = torch.masked_select(dist_mat, pos_mask)
        neg_dist = torch.masked_select(dist_mat, neg_mask)

        num_instances = len(pos_dist)//n + 1
        num_neg_instances = n - num_instances

        pos_dist = pos_dist.resize(len(pos_dist)//(num_instances-1), num_instances-1)
        neg_dist = neg_dist.resize(
            len(neg_dist) // num_neg_instances, num_neg_instances)

        loss = list()
        acc_num = 0

        for i, pos_pair in enumerate(pos_dist):
            pos_pair = pos_dist[i]
            neg_pair = neg_dist[i]

            pos_logit = torch.sum(torch.exp(self.alpha*(1 - pos_pair)))
            neg_logit = torch.sum(torch.exp(self.alpha*(1 - neg_pair)))
            a_lr = 1 - (pos_logit/(pos_logit + neg_logit)).data[0]

            if i % 37 == 0:
                print(3 * '#', '%.2f' % a_lr)

            pos_loss = torch.log(torch.sum(torch.exp(self.beta * (pos_pair - 0.8))))
            neg_loss = torch.log(torch.sum(torch.exp(self.beta * (1.1 - neg_pair))))

            loss_ = a_lr*(pos_loss + neg_loss)
            loss.append(loss_)

        # transverse all the valid triplets then average
        loss = torch.mean(torch.cat(loss))

        accuracy = float(acc_num)/n
        neg_d = torch.mean(neg_dist).data[0]
        pos_d = torch.mean(pos_dist).data[0]

        return loss, accuracy, pos_d, neg_d

def euclidean_dist(inputs_):
    n = inputs_.size(0)
    dist = torch.pow(inputs_, 2).sum(dim=1, keepdim=True).expand(n, n)
    dist = dist + dist.t()
    dist.addmm_(1, -2, inputs_, inputs_.t())
    # for numerical stability
    dist = dist.clamp(min=1e-12).sqrt()
    return dist

def main():
    data_size = 32
    input_dim = 3
    output_dim = 2
    num_class = 4
    # margin = 0.5
    x = Variable(torch.rand(data_size, input_dim), requires_grad=False)
    w = Variable(torch.rand(input_dim, output_dim), requires_grad=True)
    inputs = x.mm(w)
    y_ = 8*list(range(num_class))
    targets = Variable(torch.IntTensor(y_))

    print(AHardPair(alpha=40, beta=10)(inputs, targets))

if __name__ == '__main__':
    main()
    print('Congratulations to you!')


# -*- coding: utf-8 -*-
# Code adapted from the main `TextBlob`_ library.
#
# :repo: `https://github.com/sloria/TextBlob`_
# :source: tests/test_parsers.py
# :version: 2013-10-21 (a88e86a76a)
#
# :modified: 2014-08-29 <m.killer@langui.ch>
#
"""Test cases for parsers."""
from __future__ import unicode_literals

import unittest
from nose.tools import *  # PEP8 asserts

from textblob_de import NLTKPunktTokenizer
from textblob_de import PatternParser
from textblob_de import PatternTokenizer

from textblob_de.packages import pattern_de

pattern_parse = pattern_de.parse

class TestPatternParser(unittest.TestCase):

    def setUp(self):
        self.text = "Das Auto ist sehr schön."

        self.expected = "Das/DT/B-NP/O Auto/NN/I-NP/O ist/VB/B-VP/O " \
                        "sehr/RB/B-ADJP/O schön/JJ/I-ADJP/O ././O/O"

        self.expected_with_lemmata = \
            'Das/DT/B-NP/O/das Auto/NN/I-NP/O/auto ' \
            'ist/VB/B-VP/O/sein sehr/RB/B-ADJP/O/sehr ' \
            'schön/JJ/I-ADJP/O/schön ././O/O/.'

    def test_parse(self):
        parser = parser = PatternParser()
        assert_equal(parser.parse(self.text),
                     pattern_parse(self.text))

    def test_parse_nltk_tok_result_string(self):
        parser = PatternParser(tokenizer=NLTKPunktTokenizer(), lemmata=False)
        assert_equal(parser.parse(self.text), self.expected)

    def test_parse_nltk_tok_show_lemmata(self):
        parser = PatternParser(tokenizer=NLTKPunktTokenizer(), lemmata=True)
        assert_equal(parser.parse(self.text), self.expected_with_lemmata)

    def test_parse_pattern_tok_result_string(self):
        parser = PatternParser(tokenizer=PatternTokenizer(), lemmata=False)
        assert_equal(parser.parse(self.text), self.expected)

    def test_parse_pattern_tok_show_lemmata(self):
        parser = PatternParser(tokenizer=PatternTokenizer(), lemmata=True)
        assert_equal(parser.parse(self.text), self.expected_with_lemmata)

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


from math import sqrt
from numpy import concatenate
import numpy as np
from matplotlib import pyplot
from pandas import concat, DataFrame, read_excel
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense, LSTM
from keras.layers.noise import GaussianNoise
from keras.callbacks import TensorBoard

def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
	n_vars = 1 if type(data) is list else data.shape[1]
	df = DataFrame(data)
	cols, names = list(), list()
	# input sequence (t-n, ... t-1)
	for i in range(n_in, 0, -1):
		cols.append(df.shift(i))
		names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
	# forecast sequence (t, t+1, ... t+n)
	for i in range(0, n_out):
		cols.append(df.shift(-i))
		if i == 0:
			names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
		else:
			names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
	# put it all together
	agg = concat(cols, axis=1)
	agg.columns = names
	# drop rows with NaN values
	if dropnan:
		agg.dropna(inplace=True)
	return agg

dataset = read_excel('1v_cosd_turb_a.xlsx', header=0)
dataset = dataset.dropna(axis=0, how='all')
values = dataset.values
values = values.astype('float32')
# normalize features
scaler = MinMaxScaler(feature_range=(0, 1))
scaled = scaler.fit_transform(values)
n_lookback = 20
n_features = 3
n_pre_min = 1
reframed = series_to_supervised(scaled, n_lookback, n_pre_min)
print(reframed.shape)

values = reframed.values
n_train_terms = int(reframed.shape[0]/2)
train = values[:n_train_terms, :]
test = values[n_train_terms:, :]

train_X = np.zeros((train.shape[0], 1))
test_X = np.zeros((test.shape[0], 1))
for i in range(n_lookback+1):
	train_X = concatenate((train_X, train[:, 4*i:4*i+3]), axis=1)
	test_X = concatenate((test_X, test[:, 4*i:4*i+3]), axis=1)
train_X = train_X[:, 1:]
test_X = test_X[:, 1:]

train_y = train[:, -1]
train_y = np.matrix(train_y)
train_y = np.transpose(train_y)
test_y = test[:, -1]
test_y = np.matrix(test_y)
test_y = np.transpose(test_y)

train_X = train_X.reshape((train_X.shape[0], n_lookback+1, n_features))
test_X = test_X.reshape((test_X.shape[0], n_lookback+1, n_features))
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)

# design network
model = Sequential()
model.add(GaussianNoise(stddev=0.005, input_shape=(train_X.shape[1], train_X.shape[2])))
model.add(LSTM(128, input_shape=(train_X.shape[1], train_X.shape[2])))
model.add(Dense(64))
model.add(Dense(16))
model.add(Dense(8))
model.add(Dense(4))
model.add(Dense(1))
model.summary()
model.compile(loss='mse', optimizer='Adam')

history = model.fit(train_X, train_y, validation_data=(test_X, test_y),
					epochs=100, verbose=2, shuffle=False, callbacks=[TensorBoard(log_dir='./graph')])
# plot history
los1 = np.divide(history.history['loss'], np.square(np.mean(train_y)))
los2 = np.divide(history.history['val_loss'], np.square(np.mean(test_y)))
pyplot.plot(los1, label='train')
pyplot.plot(los2, label='test')
pyplot.xlabel('epochs')
pyplot.ylabel('loss')
pyplot.legend()
pyplot.show()

# y0 = model.predict(train_X)
# # invert scaling for training set
# temp = np.zeros((train.shape[0], 3))
# y0 = concatenate((temp, y0), axis=1)
# y0 = scaler.inverse_transform(y0)
# y0 = y0[:, -1:]
# inv_ty = concatenate((temp, train_y), axis=1)
# inv_ty = scaler.inverse_transform(inv_ty)
# inv_ty = inv_ty[:, -1:]
#
# yhat = model.predict(test_X)
# # invert scaling for forecast
# temp = np.zeros((test.shape[0], 3))
# inv_yhat = concatenate((temp, yhat), axis=1)
# inv_yhat = scaler.inverse_transform(inv_yhat)
# inv_yhat = inv_yhat[:, -1]
# # invert scaling for actual
# inv_y = concatenate((temp, test_y), axis=1)
# inv_y = scaler.inverse_transform(inv_y)
# inv_y = inv_y[:, -1]
# # calculate RMSE
# rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
# print('Test RMSE: %.3f' % rmse)
#
#
# pyplot.figure('result')
# pyplot.subplot(211)
# pyplot.plot(inv_ty, 'r', label='train_a')
# pyplot.plot(y0[:, 0], 'b', label='trained_pre_a')
# pyplot.xlabel('time/10s')
# pyplot.ylabel('acceleration/(m/s²)')
# pyplot.legend()
# pyplot.subplot(212)
# pyplot.plot(inv_y, 'r', label='a')
# pyplot.plot(inv_yhat, 'b', label='pre_a')
# pyplot.xlabel('time/10s')
# pyplot.ylabel('acceleration/(m/s²)')
# pyplot.legend()
# pyplot.show()


import socket, sys
from threading import Thread
from pickle import loads, dumps

running = False
ports = [25001, 25002, 25003, 25004]
addr = "127.0.0.1"

def insertion(data, hash_table):
    _hash = data["hash"]
    key = _hash % len(hash_table)
    done = False
    for i in range(0, len(hash_table) - 1):
        if hash_table[(key + i) % len(hash_table)] == None:
            hash_table[(key + i) % len(hash_table)] = (_hash, data)
            done = True
            break
    if done:
        ans = {"inserted": True, "hash": data["hash"]}
    else:
        ans = {"inserted": False}
    return ans

def search(data, hash_table):
    _hash = data["hash"]
    key = _hash % len(hash_table)
    found = False
    for i in range(0, len(hash_table) - 1):
        if hash_table[(key + i) % len(hash_table)] == None:
            continue
        if (
            hash_table[(key + i) % len(hash_table)][1]["hash"] == data["hash"]
            and hash_table[(key + i) % len(hash_table)][0] == _hash
        ):
            ans = {"found": True, "data": hash_table[(key + i) % len(hash_table)][1]["data"]}
            found = True
            break
    if not found:
        ans = {"found": False}
    return ans

def remove(data, hash_table):
    _hash = data["hash"]
    key = _hash % len(hash_table)
    removed = False
    for i in range(0, len(hash_table) - 1):
        if hash_table[(key + i) % len(hash_table)] == None:
            continue
        if (
            hash_table[(key + i) % len(hash_table)][1]["hash"] == data["hash"]
            and hash_table[(key + i) % len(hash_table)][0] == _hash
        ):
            hash_table[key + i] = None
            removed = True
            break
    if removed:
        ans = {"removed": True}
    else:
        ans = {"removed": False}
    return ans

def server(_id, port):
    hash_table = [None] * 8
    hashs = set([_id * 8 + i for i in range(8)])
    sock = socket.socket()
    sock.bind(("127.0.0.1", port))
    sock.settimeout(5)
    sock.listen(10)
    while running:
        try:
            conn, _ = sock.accept()
        except socket.timeout:
            continue
        data = loads(conn.recv(1024))
        print("server id {} receive {} mod 32 = {}".format(
            _id, data, data["hash"] % 32))
        try:
            print(loads(data["data"]))
        except:
            pass
        if (data["hash"] % 32) not in hashs:
            sender = socket.socket()
            sender.connect((addr, ports[_id + 1]))
            sender.send(dumps(data))
            data = sender.recv(1024)
            conn.send(data)
            conn.shutdown(socket.SHUT_RDWR)
            conn.close()
            continue
        else:
            print("It\'s my")

        if data["op"] == 'search':
            ans = search(data, hash_table)
        elif data["op"] == 'insert':
            ans = insertion(data, hash_table)
        else:
            ans = remove(data, hash_table)
        ans["id"] = _id
        conn.send(dumps(ans))
        conn.shutdown(socket.SHUT_RDWR)
        conn.close()

if __name__ == "__main__":
    servers = []
    running = True
    for _id, port in zip(range(0, 4), ports):
        servers.append(Thread(target=server, name=f"server_{port}", args=(_id, port)))
        servers[-1].start()
    try:
        for s in servers:
            s.join()
    except KeyboardInterrupt:
        print("\r\rExiting...")
        running = False


'''
CSV(Comma Separator Value):逗号分隔符
CSV文件是有任意的数据记录组成,记录检以某种换行符分隔,每行记录有换行符组合
ID, Username, Age, Country
1001, dana, 18, China
1002, huanglaoban, 28, China
'''

import csv

headers = ['ID', 'Userename', 'Age', 'Country']
rows = [
    (1001, 'Liudana', 18, 'BeiJing'),
    (1002, 'huanglaoban', 28, 'ChengDu'),
    (1003, 'yitengjun', 'Nan', 'Jinan')
]

with open('../datas/tables/test.csv', 'w') as f:
    f_csv = csv.writer(f)
    f_csv.writerow(headers)
    f_csv.writerows(rows)


# -*- coding: utf-8 -*-
from pynes.tests import HexTestCase
from pynes.compiler import lexical, syntax, semantic
from pynes.cartridge import Cartridge

class BackgroundTest(HexTestCase):

    def __init__(self, testname):
        HexTestCase.__init__(self, testname)

    def assertAsmResults(self, source_file, bin_file):
        path = 'fixtures/nerdynights/background/'
        f = open(path + source_file)
        code = f.read()
        f.close()
        tokens = lexical(code)
        ast = syntax(tokens)

        cart = Cartridge()
        cart.path = 'fixtures/nerdynights/background/'

        opcodes = semantic(ast, True, cart=cart)

        self.assertIsNotNone(opcodes)
        bin = ''.join([chr(opcode) for opcode in opcodes])
        f = open(path + bin_file, 'rb')
        content = f.read()
        f.close()
        self.assertHexEquals(content, bin)

    def test_asm_compiler_background(self):
        self.assertAsmResults('background.asm', 'background.nes')

    def test_asm_compiler_background3(self):
        self.assertAsmResults('background3.asm', 'background3.nes')


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    # Time Complexity: O(n)
    # Space Complexity: O(logN)
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0

        else:
            leftHeight = self.maxDepth(root.left)
            rightHeight = self.maxDepth(root.right)

            return max(leftHeight, rightHeight) + 1

# hyebin's solution
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:

        if root is None: return 0

        queue = collections.deque([root])
        depth = 0

        while queue:
            depth += 1

            for _ in range(len(queue)):
                current_node = queue.popleft()

                if current_node.left:
                    queue.append(current_node.left)
                if current_node.right:
                    queue.append(current_node.right)

        return depth


import json
a={
 "shopping_list":
        {
            "chaco":"15",
            "Biscuits":"50",
            "Diary_milk":"30",
            "ice_cream":"20",
        }
}
user=input("enter the name"":")
user1=int(input("enter the number"))
for i in a:
    if a[i][user]==a[i][user]:
        c=a[i][user]
        e=int(c)
        s=e-user1
        d={}
        dic={}
    for key in a :
        for value in a[key]:
            d[value]=a[key][value]
            if value==user:
                d[value]=s
                dic[key]=d
# print(dic)
with open("pavani.json","w")as f:
    json.dump(dic,f,indent=4)
# file = open("pavani.json", "w")
# json.dump(dic, file, indent = 6)
# file.close()