import os
import random
import re
import sqlite3
import time
import importlib
import sys
import asyncio
import demoji

import discord
from discord.ext import tasks, commands

import checks
import texts
from common import clamp, idPattern, emojiPattern, customEmojiPattern, send_message, print_error, escuchameUrl, pokeballUrl, TYPE_COLORS, DBL_BREAK, EMOJI, ICON_CLOSE, enquote
from trainers import ign_as_text, fc_as_text

from .config import RAID_EMOJI, LOCKED_EMOJI, CLOSED_EMOJI, \
                    DEFAULT, LOCKED, CLOSED, \
                    BALANCED, FFA, QUEUE

from .raid import Raid, RaidRecord

class Cog(commands.Cog):
    def __init__(self, bot):
        # self.db = db
        self.bot = bot
        self.cache = {}
        self.db = sqlite3.connect('raid.db')

        self.category = None
        self.archive = None
        self.guild = None
        self.listing_channel = None
        self.thanks_channel = None
        self.log_channel = None
        self.announce_channels = []
        self.admin_roles = []
        self.creating_enabled = True
        self.loaded = False
        self.max_raids = 10

        self.raids = {}

        # debug
        self.task_n = 0

        if self.bot.is_ready():
            self.bot.loop.create_task(self.on_load())

    def cog_unload(self):
        print('[Unload] Raid Cog Teardown')
        self.bot.loop.create_task(self.save_raids_to_db())

    async def on_load(self):
        self.loaded = False

        configured = self.configure()
        while not configured:
            await asyncio.sleep(5)
            configured = self.configure()

        print('[DB] Init')
        self.make_db()
        await self.load_raids_from_db()
        try:
            self.save_interval.start()
        except Exception as e:
            print('Attempting to restart, save Interval Exception: {type(e).__name__}, {e}')
            await self.bot.misc.execute_restart(by_command=False)
        self.loaded = True

    def reload_deps(self):
        if self.bot.config.get('disable_hot_reload', False):
            return

        importlib.reload(sys.modules['raid.pool'])
        importlib.reload(sys.modules['raid.raid'])

    def make_db(self):
        c = self.db.cursor()
        c.execute('''create table if not exists raids (
            host_id integer not null,
            guild_id integer not null,
            raid_name text not null,
            mode integer not null,
            private integer not null,
            allow_mb integer not null,
            channel_id integer not null,
            raid_emoji text,
            desc text,
            listing_msg_id integer not null,
            last_round_msg_id integer,
            round integer not null,
            max_joins integer not null,
            pool text,
            ups text,
            start_time integer not null,
            time_saved integer,
            code text,
            locked integer not null,
            closed integer not null,
            primary key(host_id)
        )''')
        self.db.commit()
        c.close()

    def remake_db(self):
        self.db.close()
        try:
            os.remove('raid.db')
        except:
            pass
        self.db = sqlite3.connect('raid.db')
        self.make_db()

    async def load_raids_from_db(self):
        # print(f'[DB] Attempting to load raids...')
        if self.raids:
            print('[DB ERROR] `self.raids` already exists, should be empty')
            await self.bot.misc.execute_restart(by_command=False)

        t = time.time()
        c = self.db.cursor()
        c.execute('select host_id, guild_id, raid_name, mode, private, allow_mb, channel_id, raid_emoji, desc, listing_msg_id, last_round_msg_id, round, max_joins, pool, ups, start_time, time_saved, code, locked, closed from raids')
        for r in map(RaidRecord._make, c.fetchall()):
            raid = Raid(self.bot, self, self.guild, r.host_id)
            loaded, err = await raid.load_from_record(r)
            print('raid:', raid)
            print(await raid.as_record())
            if not loaded:
                print(f'Did not succesfully load {r.raid_name}, error: {err}')
                if raid.channel and not raid.closed:
                    await raid.channel.send(f'❌ During a botte restart, this raid failed to load and will have to be remade. This is likely a Discord issue, but let <@232650437617123328> know. The following error occured:\n\n```{err}```')
            else:
                self.raids[raid.host_id] = raid
                print(f'Succesfully loaded {r.raid_name}')
                if raid.closed:
                    await raid.archive()
                    print('...and immediately archived it!')
                else:
                    t = int(time.time())
                    delta = t - raid.time_saved
                    if delta < 60:
                        ago = f'{delta} second(s)'
                    else:
                        ago = f'{delta//60} minute(s)'

                    await raid.channel.send(f'🔄 Botte Reloaded! Restored raid data from ~{ago} ago.')

        c.close()
        print(f'[DB] Loaded {len(self.raids)} raids from database. Took {time.time() - t:.3f} seconds')

    async def save_raids_to_db(self):
        # print(f'[DB] Attempting to save raids...')
        # t = time.time()
        print('[DB] Starting saving raids to DB.')
        c = self.db.cursor()
        c.execute('delete from raids')
        for raid in self.raids.values():
            try:
                record, can_save = await raid.as_record()
            except Exception as e:
                print(f'[Raid Serialize] Could not serialize raid {raid.raid_name}; this will be lost! Error: {type(e).__name__}, {e}')
                continue

            if not can_save:
                print(f'[DB] Skipped saving record {record}')
                continue

            print(f'[DB] Saving record {record} to database')
            try:
                c.execute('insert into raids values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', record)
            except sqlite3.Error as e:
                print(f'[SQL Insert Error] Could not insert raid {record.raid_name}! Error: {type(e).__name__}, {e}')

        self.db.commit()
        c.close()
        print('[DB] Save complete.')

    @commands.Cog.listener()
    async def on_ready(self):
        await self.on_load()

    @tasks.loop(minutes=3.0)
    async def save_interval(self):
        print('[Task] Periodic Save')
        await self.save_raids_to_db()

    # @commands.Cog.listener()
    # async def on_reaction_add(self, reaction, user):
    #     await self.reaction_action('add', reaction, user)
    #
    # @commands.Cog.listener()
    # async def on_reaction_remove(self, reaction, user):
    #     await self.reaction_action('remove', reaction, user)

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, payload):
        if self.loaded:
            await self.reaction_action('add', payload)

    @commands.Cog.listener()
    async def on_raw_reaction_remove(self, payload):
        if self.loaded:
            await self.reaction_action('remove', payload)

    async def reaction_action(self, action, payload):

        if not self.listing_channel:
            return

        if payload.user_id == self.bot.user.id:
            return

        if payload.channel_id != self.listing_channel.id:
            return

        user = self.bot.get_user(payload.user_id)
        if not user:
            return

        if str(payload.emoji) not in [EMOJI['pokeball'], EMOJI['masterball']]:
            await self.bot.misc.remove_raw_reaction(payload, user)
            return

        target_raid = None
        for host_id, raid in self.raids.items():
            if raid and raid.listing_message and raid.listing_message.id == payload.message_id:
                target_raid = raid
                break

        if not target_raid:
            return

        if not target_raid.allow_mb and str(payload.emoji) == EMOJI['masterball']:
            return

        if action == 'add':
            join_type = 'mb' if str(payload.emoji) == EMOJI['masterball'] else 'pb'
            return await target_raid.user_join(user, join_type, payload)

        if action == 'remove':
            return await target_raid.user_leave(user)

    # @commands.group(invoke_without_command=True)
    # async def raid(self, ctx, arg=None):
    #     pass
    #     # message = await send_message(ctx, 'Top Level Raid')

    '''
    host
    '''

    # @commands.has_role('raider')
    @commands.command()
    async def host(self, ctx, *, arg=None):

        if not self.creating_enabled and ctx.author.id not in self.bot.config['creator_ids']:
            return await send_message(ctx, 'Creating new raids is temporarily paused (probably pending a botte update, check the botte status channel).', error=True)

        if arg is None or 'help' in arg:
            msg = f'''{texts.CREATE_HELP}

_Managing a Raid_
{texts.HOST_COMMANDS}
'''
            return await send_message(ctx, msg)

        if len(self.raids) >= self.max_raids:
            return await send_message(ctx,
                                      f'Unfortunately, we already have the maximum number of **{self.max_raids}** raids being hosted.',
                                      error=True)

        uid = ctx.author.id
        if uid in self.raids:
            if self.raids[uid].confirmed:
                return await send_message(ctx, 'You are already configuring or hosting a raid.', error=True)
            self.raids[uid].clear_wait_fors()
            del self.raids[uid]

        can_host, err = await self.bot.trainers.can_host(ctx.author, ctx)
        if not can_host:
            msg = texts.make_error_msg(err, uid)
            return await send_message(ctx, msg, error=True)

        # todo BALANCED
        options = {
            'mode': FFA,
            'max_joins': 30,
            'private': False,
            'locked': False,
            'emoji': None
        }

        # try:
        #     mode_arg, arg = arg.split(' ', 1)
        #     try:
        #         mode = {
        #             # 'balanced': BALANCED,
        #             'ffa': FFA,
        #             'queue': QUEUE,
        #         }[mode_arg.lower()]
        #     except KeyError:
        #         pass
        # except ValueError:
        #     pass

        # m = re.search(customEmojiPattern, arg)

        m = re.search(r' max[\s=](\d*)', arg)
        if m:
            try:
                options['max_joins'] = int(m.group(1))
            except ValueError:
                return await send_message(ctx, 'Invalid value for max raiders. Include `max n` or leave it out for `max 30`', error=True)
            arg = arg.replace(m.group(0), '')

        m = re.search(r'[\"“‟”’❝❞＂‘‛❛❜\'](.*)[\"“‟”’❝❞＂‘‛❛❜\']', arg, flags=re.DOTALL)
        if m:
            options['desc'] = m.group(1)
            arg = arg.replace(m.group(0), '')

        # if 'private' in arg:
        #     options['private'] = True
        #     arg = arg.replace('private', '')
        #
        # if 'locked' in arg:
        #     options['locked'] = True
        #     arg = arg.replace('locked', '')

        m = re.search(customEmojiPattern, arg)
        if m:
            return await send_message(ctx, 'You cannot put images (custom emoji) into channel names on Discord.', error=True)

        options['raid_name'] = arg.strip()
        m = re.match(emojiPattern, options['raid_name'])
        if m:
            options['emoji'] = options['raid_name'][0]
            options['raid_name'] = options['raid_name'][1:].strip()
            if options['emoji'] in [LOCKED_EMOJI, CLOSED_EMOJI]:
                options['emoji'] = None

        if 'ffa' in options['raid_name'].lower():
            options['mode'] = FFA
        # elif options['mode'] == FFA:
        #     options['name'] = f'''ffa {options['raid_name']}'''

        # channel_name = f"{RAID_EMOJI}┊{options['raid_name'].replace(' ', '-')}"[:100]
        # options['channel_name'] = re.sub('[<>]', '', channel_name)

        self.raids[uid] = Raid(self.bot, self, self.guild, ctx.author.id)
        print('[Raid Creation]', self.raids)

        await self.raids[uid].send_confirm_prompt(ctx, options)

    @host.error
    async def host_error(self, ctx, error):
        if isinstance(error, commands.CheckFailure):
            await ctx.send('oopsie poopsie')
        else:
            print_error(ctx, error)

    async def cancel_before_confirm(self, raid, channel, msg=''):
        print(f'[Raid Cancel] {self} was cancelled before it was confirmed.')
        del self.raids[raid.host_id]
        raid.clear_wait_fors()
        await channel.send(f"<@{raid.host_id}> {msg}Your raid was cancelled. {EMOJI['flop']}")

    @commands.command()
    async def round(self, ctx, *, arg=None):
        uid = ctx.author.id
        if uid in self.raids:
            return await self.raids[uid].round_command(ctx, arg)

        return await send_message(ctx, texts.RAID_NOT_FOUND, error=True)

    @commands.command(aliases=['end'])
    async def close(self, ctx, arg=''):
        uid = ctx.author.id
        is_bot_admin = checks.check_bot_admin(ctx.author, ctx.bot)
        if uid in self.raids:
            if self.raids[uid].channel == ctx.channel:
                return await self.raids[uid].end(ctx, is_bot_admin and ('immediately' in arg or 'now' in arg))

        if is_bot_admin:
            for host_id, raid in self.raids.items():
                if raid and raid.channel == ctx.channel:
                    return await raid.end(ctx, 'immediately' in arg or 'now' in arg)

        return await send_message(ctx, texts.RAID_NOT_FOUND, error=True)

    @commands.command()
    async def up(self, ctx, *, arg=None):
        target_raid = None
        is_host = False
        for host_id, raid in self.raids.items():
            if raid and raid.channel == ctx.channel:
                is_host = ctx.author.id == host_id
                target_raid = raid
                break

        if not target_raid:
            return await send_message(ctx, texts.RAID_NOT_FOUND, error=True)

        if not is_host:
            if len(target_raid.ups) == 0:
                msg = f'''The host hasn't told me what the current Pokémon is! They can use `.up pokémon` to tell me!'''
            else:
                msg = f'''The current Pokémon is **{target_raid.ups[-1]}**! Here's a list of all so far: {target_raid.ups}'''
            return await ctx.send(msg)

        await target_raid.up_command(ctx, arg)

    # todo
    @commands.command()
    async def remake(self, ctx, *, arg=None):
        pass

    '''
    host moderation
    '''

    @commands.command(name='group')
    async def group_message(self, ctx, *, arg=None):
        uid = ctx.author.id
        if uid not in self.raids:
            return

        if not arg:
            return await send_message(ctx, f'Type a message that you\'d like to relay to the current round\'s group.',
                                      error=True)

        raid = self.raids[uid]
        if not raid.pool.group:
            return await send_message(ctx, 'No active group! Type `.round` to start one.', error=True)

        mentions = []
        for i, raider in enumerate(raid.pool.group):
            join_type, raider_id = raider
            mention = f'<@{raider_id}>'
            mentions.append(mention)

        msg = f"{' '.join(mentions)} 📣 Message from host:\n{enquote(arg)}"
        await ctx.send(msg)

    @commands.command()
    async def skip(self, ctx, *, arg=None):
        await self.host_moderation(ctx, 'skip', arg)

    @commands.command(aliases=['remove'])
    async def kick(self, ctx, *, arg=None):
        await self.host_moderation(ctx, 'remove', arg)

    @commands.command()
    async def block(self, ctx, *, arg=None):
        await self.host_moderation(ctx, 'block', arg)

    async def host_moderation(self, ctx, action, arg):
        if not arg:
            return

        target_raid = None
        for host_id, raid in self.raids.items():
            if raid and raid.channel == ctx.channel:
                is_host = ctx.author.id == host_id
                is_bot_admin = checks.check_bot_admin(ctx.author, ctx.bot)

                if not is_bot_admin and not is_host:
                    return await send_message(ctx, 'Host or admin only. Use `.q` instead.', error=True)
                target_raid = raid
                break

        if not target_raid:
            return await send_message(ctx, texts.RAID_NOT_FOUND, error=True)

        match = idPattern.search(arg)
        if not match:
            return await send_message(ctx, f'Please tag the member you\'d like to {action}', error=True)

        mention_id = int(match.group(1))
        member = ctx.message.guild.get_member(mention_id)
        if not member:
            return await send_message(ctx, f'Could not remove user! Please contact the mods to manually intervene.',
                                      error=True)

        if member == self.bot.user or member.id == target_raid.host_id:
            return await send_message(ctx, '', error=True, image_url=escuchameUrl)

        if action == 'skip':
            return await target_raid.skip(member)

        if action == 'remove':
            return await target_raid.kick(member, ctx)

        if action == 'block':
            await ctx.send(f'`.block` is not yet implemented, but for now we will attempt to `.remove` the user.')
            return await target_raid.kick(member, ctx)

    @commands.command()
    async def max(self, ctx, *, arg=''):
        uid = ctx.author.id
        if uid not in self.raids:
            return

        raid = self.raids[uid]
        if raid.channel != ctx.channel:
            return await send_message(ctx, f'You may only adjust this in your active raid channel.', error=True)

        if not arg:
            return await send_message(ctx, f'Please enter a number, i.e. `.max 18`', error=True)

        try:
            n = int(arg)
        except ValueError:
            return await send_message(ctx, f'Please enter a number, i.e. `.max 18`', error=True)

        n = clamp(n, 3, 30 if raid.mode == QUEUE else 50)
        size = raid.pool.size()
        if n < size:
            return await send_message(ctx, f'You cannot go lower than the current pool size ({size}).', error=True)

        if raid.max_joins == n:
            return await send_message(ctx, f'That\'s... already the max.', error=True)

        verb = 'increased' if raid.max_joins < n else 'decreased'
        raid.max_joins = n
        await raid.update_channel_emoji()
        await ctx.send(f'Max participants {verb} to **{n}**.')

    @commands.command()
    async def lock(self, ctx):
        target_raid = None
        for host_id, raid in self.raids.items():
            if raid and raid.channel == ctx.channel:
                is_host = ctx.author.id == host_id
                is_bot_admin = checks.check_bot_admin(ctx.author, ctx.bot)

                if not is_bot_admin and not is_host:
                    return
                target_raid = raid
                break

        if not target_raid:
            return await send_message(ctx, f'You may only do this in your active raid channel.', error=True)

        target_raid.locked = not target_raid.locked

        if target_raid.locked:
            msg = 'Raid is now **locked**, the raid will continue but no new raiders will be able to join until you type `.lock` again.'
        else:
            msg = 'Raid is now **unlocked**, new raiders can join again (if there is room).'

        await target_raid.update_channel_emoji()
        await ctx.send(msg)

    @commands.command()
    async def private(self, ctx):
        uid = ctx.author.id
        if uid not in self.raids:
            return

        raid = self.raids[uid]
        if raid.channel != ctx.channel:
            return await send_message(ctx, f'You may only do this in your active raid channel.', error=True)

        raid.private = not raid.private

        if raid.private:
            raid.code = None
            msg = 'Raid is now **private**, which means the `.code` will be hidden. I\'ve removed the old one, so please set a secret one in the form `.code 1234 5678`. If you\'ve pinned it, you might want to `.unpin` it. Type `.private` again to toggle.'
        else:
            msg = f'''Raid is no longer private, which means the code is public again (it's **{raid.code}**). Type `.private` again to toggle.'''

        await ctx.send(msg)

    @commands.command()
    async def rename(self, ctx, *, arg=''):
        name = arg.strip()[:100]
        if not name:
            return await send_message(ctx, f'You have to specify a new channel name.', error=True)

        m = re.search(customEmojiPattern, name)
        if m:
            return await send_message(ctx, 'You cannot put images (custom emoji) into channel names on Discord.', error=True)

        emoji = None
        m = re.match(emojiPattern, name)
        print(name)
        if m:
            print('match')
            emoji = name[0]
            print(emoji)
            if emoji in [LOCKED_EMOJI, CLOSED_EMOJI]:
                emoji = RAID_EMOJI
            name = name[1:].strip()
            print(name)

        target_raid = None
        for host_id, raid in self.raids.items():
            if raid and raid.channel == ctx.channel:
                is_host = ctx.author.id == host_id
                is_bot_admin = checks.check_bot_admin(ctx.author, ctx.bot)

                if not is_bot_admin and not is_host:
                    return
                target_raid = raid
                break

        if not target_raid:
            return await send_message(ctx, f'You may only do this in your active raid channel.', error=True)

        target_raid.emoji = emoji or RAID_EMOJI
        updated_name = f'{target_raid.emoji}┊{name}'
        await target_raid.channel.edit(name=updated_name)
        await target_raid.update_channel_emoji()
        await ctx.message.add_reaction('✅')

    '''
    pins
    '''

    @commands.command()
    async def pin(self, ctx):
        uid = ctx.author.id
        if uid not in self.raids:
            return

        raid = self.raids[uid]
        if raid.channel != ctx.channel:
            return await send_message(ctx, f'You may only pin channels in your active raid channel.', error=True)

        if len(raid.pins) >= 10:
            return await send_message(ctx,
                                      f'For now, you can only `.pin` a total of 10 times (even after `.unpin`ning them). This will be adjusted in the future.',
                                      error=True)

        last_msg = await ctx.channel.history().find(lambda m: m.id != ctx.message.id and m.author == ctx.author)
        if not last_msg:
            return await send_message(ctx, f'No message found by you in recent history (~50 messages).', error=True)

        raid.pins.append(last_msg)
        await last_msg.pin()

        n = len(raid.pins)
        await ctx.send(f'Message #**{n}** pinned! To remove it, type `.unpin {n}`.')

    @commands.command()
    async def unpin(self, ctx, *, arg=''):
        uid = ctx.author.id
        if uid not in self.raids:
            return

        raid = self.raids[uid]
        if raid.channel != ctx.channel:
            return await send_message(ctx, f'You may only unpin channels in your active raid channel.', error=True)

        if not arg:
            return await send_message(ctx, f'Invalid pin! You must include the number, e.g. `.unpin 3` ', error=True)

        try:
            n = int(arg) - 1
            if not (0 <= n < len(raid.pins)):
                raise ValueError
        except ValueError:
            return await send_message(ctx, f'Invalid pin! You must include the number, e.g. `.unpin 3` ', error=True)

        pinned_msg = raid.pins[n]
        if not pinned_msg:
            return await send_message(ctx, f'That message no longer exists and could not be unpinned.', error=True)

        await pinned_msg.unpin()
        raid.pins[n] = None

        await ctx.send(f'Message #**{n + 1}** unpinned! This cannot presently be undone.')

    @commands.command()
    async def echo(self, ctx, *, arg=''):
        uid = ctx.author.id
        if uid not in self.raids:
            return

        raid = self.raids[uid]
        if raid.channel != ctx.channel:
            return await send_message(ctx, f'You may only `.echo` in your active raid channel.', error=True)

        echo_help = f'_Usage_\n`.echo <tag> <message goes here>` to set an echo\n`.echo <tag>` to have me repeat it\nTo update an `.echo`, just set it again.'

        if not arg:
            msg = echo_help
            if len(raid.echos):
                tags = ' '.join([f'`{t}' for t in raid.echos.keys()])
                msg = f'{msg}{DBL_BREAK}Current Tags: {tags}'
            return await send_message(ctx, msg, error=True)

        msg = None
        try:
            tag, msg = arg.split(' ', 1)
        except ValueError:
            tag = arg

        if not msg:
            if tag in raid.echos:
                return await ctx.send(f'**Echo from the host**\n{raid.echos[tag]}')
            return await send_message(ctx, f'Echo not found for tag `{tag}`.{DBL_BREAK}{echo_help}', error=True)

        if len(raid.echos) > 5:
            return await send_message(ctx, f'You cannot have more than 5 echos at a time, currently. If you want more,let jacob know.', error=True)

        raid.echos[tag] = msg[:1000]
        return await ctx.send(f'**Raid echo set for tag `{tag}`**\nUse `.echo {tag}` to have me repeat it.{DBL_BREAK}{raid.echos[tag]}')

    '''
    misc
    '''

    async def view_queue(self, ctx, text=False):
        uid = ctx.author.id
        if uid in self.raids:
            if self.raids[uid].channel == ctx.channel:
                e = self.raids[uid].make_queue_embed(mentions=not text, cmd=ctx.invoked_with)
                return await ctx.send('', embed=e)

        for host_id, raid in self.raids.items():
            if raid.channel == ctx.channel:
                is_bot_admin = checks.check_bot_admin(ctx.author, ctx.bot)
                if is_bot_admin:
                    e = raid.make_queue_embed(mentions=not text, cmd=ctx.invoked_with)
                    return await ctx.send('', embed=e)
                await ctx.message.add_reaction('✅')
                e = raid.make_queue_embed(mentions=False, cmd=ctx.invoked_with)
                return await ctx.author.send(raid.raid_name, embed=e)

        return await send_message(ctx, texts.RAID_NOT_FOUND, error=True)

    @commands.command(aliases=['q'])
    async def queue(self, ctx, arg=''):
        return await self.view_queue(ctx, False)

    @commands.command(name='qtext', aliases=['qt'])
    async def queue_text(self, ctx, arg=''):
        return await self.view_queue(ctx, True)

    @commands.command(name='qfc', aliases=['queuefc'])
    async def queue_fc(self, ctx, arg=''):
        for host_id, raid in self.raids.items():
            if raid and raid.channel == ctx.channel:
                is_host = ctx.author.id == host_id
                is_bot_admin = checks.check_bot_admin(ctx.author, ctx.bot)

                if not is_bot_admin and not is_host:
                    return await send_message(ctx, 'Host or admin only. Use `.q` instead.', error=True)

                lines = []
                for i, uid in enumerate(raid.pool.q):
                    profile = await self.bot.trainers.get_wf_profile(uid)

                    fc = f"SW-{profile['friend_code']}"
                    switch = profile['switch_name']
                    text = f'''🗺 FC: `{fc}` / {EMOJI['discord']}  **{raid.member_name(uid)}** / 🎮 Switch Name: **{switch}** / {ign_as_text(profile, ' / ')}'''
                    lines.append(f"`{i + 1: >2}` {text}\n")

                messages = []
                msg = f'**Active Raider Profiles**\n\n'
                for line in lines:
                    if len(msg) + len(line) < 2000:
                        msg += line
                    else:
                        messages.append(msg)
                        msg = line

                messages.append(msg)
                for msg in messages:
                    await ctx.send(msg)

                return

        return await send_message(ctx, texts.RAID_NOT_FOUND, error=True)

    @commands.command(aliases=['catch'])
    async def caught(self, ctx, arg=None):
        description = f' 🎊 ✨ 🍰   {ctx.author.mention} has **caught** the Pokémon!   🍰 ✨ 🎊 '
        color = random.choice(TYPE_COLORS)
        e = discord.Embed(description=description, color=color) \
            .set_author(name=f'Caught!', icon_url=pokeballUrl)

        caught_msg = await ctx.send('', embed=e)
        for reaction in [EMOJI['lovehonk'], EMOJI['pokeball']]:
            await caught_msg.add_reaction(reaction.strip('<>'))

    @commands.command()
    async def code(self, ctx, *, arg=None):
        for host_id, raid in self.raids.items():
            if raid and raid.channel == ctx.channel:
                is_host = ctx.author.id == host_id

                if not arg or not is_host:
                    if not raid.code:
                        if is_host:
                            return await send_message(ctx, '''You haven't set a code yet. Please choose a valid 8-digit code in the form `.code 1234 5678`''', error=True)
                        else:
                            return await send_message(ctx, 'The code hasn\'t been set by the host.', error=True)

                    if not is_host:
                        msg = f'The code for `{raid.raid_name}` is currently **{raid.code}**. The host may change this later on, keep an eye out.'
                        if raid.private:
                            msg += ' Since this is a private raid, please do not share the code openly (to hide it from lurkers).'
                        # await ctx.message.add_reaction('✅')
                        await ctx.message.delete()
                        return await ctx.author.send(msg)

                error = False
                code = None
                if arg:
                    m = re.search(r'\d{4}\s?\d{4}', arg)
                    if m:
                        code = m.group(0)
                    else:
                        error = True

                if not code:
                    msg = ''
                    if raid.code:
                        msg = f'The code is currently set to **{raid.code}**, but you can change it with `.code 1234 5678` using any valid 8-digit number.'
                    else:
                        msg = f'''You haven't set a code yet. Please choose a valid 8-digit code in the form `.code 1234 5678`'''

                    if raid.private:
                        await ctx.message.add_reaction(ICON_CLOSE if error else '✅')
                        return await ctx.author.send(msg)

                    return await send_message(ctx, msg, error=True)

                raid.code = code
                if raid.private:
                    await ctx.message.delete()
                    msg = '''The code has been **updated**. Participants will have to get the new one by typing `.code` when it's their turn. I'll also send a DM if there's a queue. Since this is a private raid, please do not share the code openly (to hide it from lurkers).'''
                else:
                    msg = f'''The code has been updated to **{raid.code}**.'''

                return await ctx.send(msg)

        return await send_message(ctx, texts.RAID_NOT_FOUND, error=True)

    @commands.command()
    async def leave(self, ctx, arg=None):
        for host_id, raid in self.raids.items():
            if raid and raid.channel == ctx.channel:
                user = self.bot.get_user(ctx.author.id)
                if not user:
                    print(f'[ERROR] Could not `get_user` for `.leave` with id {ctx.author.id}')
                    return
                await raid.user_leave(user, True)
                await ctx.message.add_reaction('✅')
                return

        return await send_message(ctx, texts.RAID_NOT_FOUND, error=True)

    @commands.command()
    async def miss(self, ctx, arg=None):
        for host_id, raid in self.raids.items():
            if raid and raid.channel == ctx.channel:
                user = self.bot.get_user(ctx.author.id)
                if not user:
                    print(f'[ERROR] Could not `get_user` for `.miss` with id {ctx.author.id}')
                    return
                return await raid.miss(user)

        return await send_message(ctx, texts.RAID_NOT_FOUND, error=True)

    '''
    raid admin
    '''

    # @checks.is_jacob()
    # @commands.command()
    # async def init(self, ctx):
    #     await ctx.invoke(self.bind, 661468408856051733)

    # @checks.is_jacob()
    # @raid.group()
    # async def admin(self, ctx):
    #     await ctx.send('**[Raid Admin]**')
    #     if ctx.invoked_subcommand is None:
    #         await ctx.send('Invalid admin command')
    #
    # @checks.is_jacob()
    # @admin.command()
    # async def bind(self, ctx, category_id: int):
    #     try:
    #         self.category = self.bot.get_channel(category_id)
    #         self.guild = self.category.guild
    #     except AttributeError:
    #         await ctx.send(f'Could not bind to {category_id}')
    #     await ctx.send(f'Succesfully bound to **{self.category.name}** on server **{self.category.guild.name}**')

    # @admin.command()
    # async def testmake(self, ctx, count: int):
    #
    #     if self.category is None or self.guild is None:
    #         await send_message(ctx, f'No category bound! Try `.raid admin bind <category id>', error=True)
    #         return
    #
    #     users = ['elliot', 'rory', 'jacob', 'stinky']
    #     pkmn = ['gmax-hatterene', 'shiny-meowth', 'pikachu', 'charmander']
    #
    #     for i in range(count):
    #         name = f'{random.choice(pkmn)}-{random.choice(users)}'
    #         channel = await self.make_channel(name)
    #         self.channels.append(channel)
    #

    @checks.is_jacob()
    @commands.command(name='dangerclearall', aliases=['dangerca'])
    async def clear_all(self, ctx, arg=None):
        await ctx.send('Clearing...')
        await self.clear_channels_dirty()
        await ctx.send('Done.')

    @commands.check_any(checks.is_jacob(), checks.is_wooloo_staff())
    @commands.command()
    async def pause(self, ctx, arg=None):
        self.creating_enabled = not self.creating_enabled
        await ctx.send(f'`creating_enabled = {self.creating_enabled}`')

    @checks.is_jacob()
    @commands.command(name='dbsave')
    async def db_save(self, ctx, arg=None):
        await self.save_raids_to_db()
        await ctx.send(f'Finished.')

    @checks.is_jacob()
    @commands.command(name='dbload')
    async def db_load(self, ctx):
        await self.load_raids_from_db()
        await ctx.send(f'Finished.')

    @checks.is_jacob()
    @commands.command(name='dangerremakedb')
    async def db_remake(self, ctx):
        self.remake_db()
        await ctx.send(f'Finished. If there are active raids, they will need to be cleaned.')

    @checks.is_bot_admin()
    @commands.command()
    async def announce(self, ctx, *, arg):

        if not self.category:
            return

        # emoji = list(re.findall(emojiPattern, arg, flags=re.DOTALL)) + list(re.findall(customEmojiPattern, arg, flags=re.DOTALL))
        emoji = list(demoji.findall(arg).keys()) + list(re.findall(customEmojiPattern, arg, flags=re.DOTALL))

        url = None
        m = re.search(r'http[\w\-._~:/?#[\]@!$&\'()*+,;=]+', arg, flags=re.DOTALL)
        if m:
            url = m.group(0)
            if 'png' in url or 'gif' in url or 'jpg' in url or 'jpeg' in url:
                arg = arg.replace(url, '')
            else:
                url = None
        color = random.choice(TYPE_COLORS)
        e = discord.Embed(title='Botte Announcement!', description=f'''{EMOJI['honk']} {arg}''', color=color)
        if url:
            e.set_image(url=url)

        for channel in self.announce_channels:
            msg = await channel.send('', embed=e)
            for reaction in emoji:
                await msg.add_reaction(reaction.strip('<> '))

        for raid in self.raids.values():
            if not raid.closed and raid.channel is not None:
                msg = await raid.channel.send('', embed=e)
                for reaction in emoji:
                    await msg.add_reaction(reaction.strip('<> '))

        await ctx.send('Sent!')

    @checks.is_bot_admin()
    @commands.command()
    async def raidsay(self, ctx, *, arg):

        if not self.category:
            return

        msg = arg

        for channel in self.announce_channels:
            await channel.send(msg)

        for raid in self.raids.values():
            if not raid.closed and raid.channel is not None:
                await raid.channel.send(msg)

        await ctx.send('Sent!')

    @checks.is_bot_admin()
    @commands.command(aliases=['cl'])
    async def clear(self, ctx):
        if self.archive:
            for channel in self.archive.text_channels:
                await channel.delete()

    async def clear_channels_dirty(self):
        if self.category:
            if self.listing_channel:
                await self.listing_channel.purge(limit=100, check=lambda m: m.author == self.bot.user)

            for channel in self.category.text_channels:
                if channel.name[0] in [RAID_EMOJI, LOCKED_EMOJI, CLOSED_EMOJI]:
                    await channel.edit(sync_permissions=True, category=self.archive, position=0)

    async def make_raid_channel(self, raid, channel_ctx):
        if self.category is None or self.guild is None:
            await channel_ctx.send(
                f"No category bound! jacob should write `.raid admin bind <category id>` {EMOJI['flop']}")
            return

        overwrites = {
            self.guild.default_role: discord.PermissionOverwrite(send_messages=False, read_messages=False if self.bot.config["test_mode"] else None, add_reactions=False),
            self.guild.me: discord.PermissionOverwrite(send_messages=True, read_messages=True if self.bot.config["test_mode"] else None, add_reactions=True),
            self.guild.get_member(raid.host_id): discord.PermissionOverwrite(send_messages=True, read_messages=True if self.bot.config["test_mode"] else None, add_reactions=True)
        }

        for role in self.admin_roles:
            overwrites[role] = discord.PermissionOverwrite(send_messages=True, read_messages=True if self.bot.config["test_mode"] else None, add_reactions=True)

        # todo ban list

        topic = 'please read the pinned messages before raiding'

        channel_name = self.make_channel_name(raid.raid_name, LOCKED_EMOJI if raid.locked else raid.emoji or RAID_EMOJI)
        channel = await self.guild.create_text_channel(channel_name, overwrites=overwrites, category=self.category, topic=topic)
        return channel

    def make_channel_name(self, raid_name, emoji):
        channel_name = f"{emoji}┊{raid_name.replace(' ', '-')}"[:100]
        return re.sub('[<>]', '', channel_name)

    @checks.is_jacob()
    @commands.command(name='manualconfigure')
    async def manual_configure(self, ctx, arg=None):
        self.configure()
        await ctx.send(f'Finished.')

    def configure(self):
        try:
            print(f'Configure step, bot ready: {self.bot.is_ready()}')
            self.category = self.bot.get_channel(self.bot.config['raids_cid'])
            if not self.category:
                return False

            print(f'''Attempted to load raid category {self.bot.config['raids_cid']}: / {self.category}''')
            self.archive = self.bot.get_channel(self.bot.config['archive_cid'])
            print(f'''Attempted to load archive category {self.bot.config['archive_cid']}: / {self.archive}''')

            self.guild = self.category.guild
            print(f'''Set guilt to self.category.guild: {self.category.guild}''')

            self.listing_channel = self.bot.get_channel(self.bot.config['listing_channel'])
            print(f'''Attempted to load listing channel {self.bot.config['listing_channel']}: / {self.listing_channel}''')
            self.thanks_channel = self.bot.get_channel(self.bot.config['thanks_channel'])
            print(f'''Attempted to load thanks channel {self.bot.config['thanks_channel']}: / {self.thanks_channel}''')
            self.log_channel = self.bot.get_channel(self.bot.config['log_channel'])
            print(f'''Attempted to load log channel {self.bot.config['log_channel']}: / {self.log_channel}''')
            self.announce_channels = [self.bot.get_channel(cid) for cid in self.bot.config['announce_channels']]
            print(f'''Attempted to announce channels {self.bot.config['announce_channels']}: / {self.announce_channels}''')

            self.admin_roles = [self.guild.get_role(rid) for rid in self.bot.config['raid_admin_roles']]
            self.max_raids = self.bot.config['max_raids']
        except Exception as e:
            return False
        print('[CONFIG] Loaded')
        return True

def setup(bot):
    cog = Cog(bot)
    bot.add_cog(cog)
    bot.raid_cog = cog


# exit code 0: everything ok
# exit code 1: incorrect input
# exit code 2: input number doesn't match it's base

try:
    input_base = int(input("The base of the number: "))
    input_number = float(input("The number itself: "))
except:
    print("Incorrect input")
    exit(1)

output_base = 10

is_float = bool(float(input_number) - int(input_number))
int_part_len = len(str(int(float(input_number)))) + int(is_float)   # 1 if float, 0 if int
fract_part_len = (len(str(input_number)) - int_part_len) - 2*(int(not is_float))   # - .0
interim_num = int(float(input_number) * (output_base**fract_part_len))   # no point int -> change base

try:
    output_number = int(str(interim_num), int(input_base)) / (int(input_base)**fract_part_len)
except:
    print(input_number, " is not in base ", input_base)
    exit(2)

print("output_number: ", output_number)


a = 2
b = 10

class forWhile:
	#1) for문과 for문
	def for_for(self):
		list = []
		list = [("%d*%d=%d"%(i,j,i*j)) for i in range(a,b) for j in range(a, b)]
		return list
	#2) for문과 while문
	def for_while(self):
		list = []
		for i in range(a,b) :
			j = a
			while j < b :
				list.append(str(i) + "*" + str(j) + "=" + str(i*j))
				j += 1
		return list
	#3) while문과 for문
	def while_for(self):
		list = []
		i = a
		while i < b :
			for j in range(a,b) :
				list.append(str(i) + "*" + str(j) + "=" + str(i*j))
			i += 1
		return list
	#4) while문과 while문
	def while_while(self):
		list = []
		i = a
		while i < b :
			j = a
			while j<10 :
				list.append(str(i) + "*" + str(j) + "=" + str(i*j))
				j += 1
			i += 1
		return list

forWhile = forWhile()

print("#1) for문과 for문")
print(forWhile.for_for())
print("#2) for문과 while문")
print(forWhile.for_while())
print("#3) while문과 for문")
print(forWhile.while_for())
print("#4) while문과 while문")
print(forWhile.while_while())

input()


from tcorex.experiments import data as data_tools
from tcorex.experiments.misc import make_sure_path_exists
from tcorex.corex import Corex as PyCorex
from sklearn.metrics import adjusted_rand_score
import numpy as np
import linearcorex
import argparse
import pickle
import torch
import os

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--n_hidden', '-m', default=64, type=int,
                        help='number of hidden variables')
    parser.add_argument('--n_observed', '-p', default=128, type=int,
                        help='number of observed variables')
    parser.add_argument('--snr', '-s', default=0.1, type=float,
                        help='signal-to-noise ratio')
    parser.add_argument('--n_samples', '-n', default=300, type=int,
                        help='number of samples')
    parser.add_argument('--num_extra_parents', default=0.1, type=float,
                        help='average number of extra parents for each x_i')
    parser.add_argument('--num_correlated_zs', default=0, type=int,
                        help='number of zs each z_i is correlated with (besides z_i itself)')
    parser.add_argument('--random_scale', dest='random_scale', action='store_true',
                        help='if true x_i will have random scales')
    parser.add_argument('--method', '-M', type=str, choices=['linearcorex', 'pycorex'],
                        default='pycorex', help='which implementation of corex to use')
    parser.add_argument('--device', '-d', type=str, default='cuda:0',
                        help='which device to use for pytorch corex')
    parser.add_argument('--output_dir', '-o', type=str, default='outputs/blessing/')
    parser.set_defaults(random_scale=False)
    args = parser.parse_args()
    print(args)

    p = args.n_observed
    m = args.n_hidden
    snr = args.snr
    n = args.n_samples
    assert p % m == 0

    # generate some data
    data, _ = data_tools.generate_approximately_modular(nv=p, m=m, ns=n, snr=snr,
                                                        num_extra_parents=args.num_extra_parents,
                                                        num_correlated_zs=args.num_correlated_zs,
                                                        random_scale=args.random_scale)

    # select the method
    if args.method == 'linearcorex':
        method = linearcorex.Corex(n_hidden=m, verbose=1)
    else:
        method = PyCorex(nv=p, n_hidden=m, verbose=2, max_iter=10000,
                         tol=1e-6, device=args.device, optimizer_class=torch.optim.Adam,
                         optimizer_params={'lr': 0.01})

    # train and compute the clustering score
    method.fit(data)
    true_clusters = np.arange(m).repeat(p//m, axis=0)

    if args.method == 'linearcorex':
        pred_clusters = method.mis.argmax(axis=0)
    else:
        pred_clusters = method.clusters()

    score = adjusted_rand_score(labels_true=true_clusters, labels_pred=pred_clusters)
    print(pred_clusters, score)

    # save the results
    run_id = str(np.random.choice(10**18))

    save_dict = {
        'p': p,
        'm': m,
        'snr': snr,
        'n': n,
        'num_extra_parents': args.num_extra_parents,
        'num_correlated_zs': args.num_correlated_zs,
        'random_scale': args.random_scale,
        'method': args.method,
        'score': score,
        'run_id': run_id
    }

    output_file = os.path.join(args.output_dir, run_id + '.pkl')
    make_sure_path_exists(output_file)
    with open(output_file, 'wb') as fout:
        pickle.dump(save_dict, fout)

if __name__ == '__main__':
    main()


import os
import spacy
import codecs

def replace_utf8mb4( v):
    """Replace 4-byte unicode characters by REPLACEMENT CHARACTER"""
    import re
    INVALID_UTF8_RE = re.compile(u'[^\u0000-\uD7FF\uE000-\uFFFF]', re.UNICODE)
    INVALID_UTF8_RE.sub(u'\uFFFD', v)
    return v

def get_sentences_and_tokens_from_spacy(plain_text_path, spacy_nlp):
    with open(plain_text_path, 'r', encoding='UTF-8-sig') as f:
        sentences = []
        for line in f.readlines():
            if len(line.strip())==0 or line[0] == '\n' or line.strip() == '':
                continue
            line = replace_utf8mb4(line.strip())
            line = line.strip().replace(u'\u3000', u' ').replace(u'\xa0', u' ')
            document = spacy_nlp(line)
            for span in document.sents:
                sentence=[document[i] for i in range(span.start, span.end)]
                sentence_tokens = []
                for token in sentence:
                    token_dict = {}
                    token_dict['pos'] = token.pos_
                    token_dict['text'] = str(token)
                    if str(token_dict['text']).strip() in ['\n', '\t', ' ', '']:
                        continue
                    sentence_tokens.append(token_dict)
                sentences.append(sentence_tokens)
    return sentences

def process_plain_text(data_dir, plain_text_data):
    if not os.path.exists(data_dir):
        os.makedirs(data_dir)
    spacy_nlp = spacy.load('en_core_web_sm', disable=["parser", "ner", "entity_linker", "textcat", "entity_ruler"])
    spacy_nlp.add_pipe(spacy_nlp.create_pipe('sentencizer'))
    base_filename = os.path.basename(plain_text_data)
    output_file = codecs.open(os.path.join(data_dir, 'conll_'+base_filename), 'w', 'utf-8')
    sentences = get_sentences_and_tokens_from_spacy(plain_text_data, spacy_nlp)
    if (len(sentences) == 0):
            print("Error loading annotation -- skipping this question. ")
    else:
        for sentence in sentences:
            for token in sentence:
                output_file.write(
                    '{0} {1} {2}\n'.format(token['text'], base_filename, token['pos']))
            output_file.write('\n')

        output_file.close()
        print('Done.')
        del spacy_nlp


import boringmindmachine as bmm
import subprocess

"""
Run this example like:

    $ python google_auth.py

This requires that you set up API keys
using a JSON file, downloaded from the
Google API Credentials page in the
Google Cloud Platform Console.
"""

keydir = 'keys'

gk = bmm.GoogleKeymaker()
gk.set_apikeys_file('client_secret.json')

print("Creating a dummy key...")
gk.make_a_key('dummy','dummy.json',keydir)
print("Success.")

print("Cleaning up...")
subprocess.call(['rm','-rf',keydir])
print("Done.")


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

'''
Created on 2015年1月17日

@author: mac
'''

import threading
import ConfigParser
import string
class SingletonConfig(object):
    '''
    classdocs
    '''

##单件模式
    objs = {}
    objs_locker =  threading.Lock()

    def __new__(cls,*agrs,**kv):
        if cls in cls.objs:
            return cls.objs[cls]['obj']
        cls.objs_locker.acquire()
        try:
            if cls in cls.objs:## double check locking
                return cls.objs[cls]['obj']
            obj = object.__new__(cls)
            #obj.__init__()
            cls.objs[cls] = {'obj':obj,'init':False}
            setattr(cls,'__init__',cls.decorate_init(cls.__init__))
            return cls.objs[cls]['obj']
        finally:
            cls.objs_locker.release()

    @classmethod
    def decorate_init(cls,fn):
        def init_wrap(*args):
            if not cls.objs[cls]['init']:
                fn(*args)
                cls.objs[cls]['init'] = True
            return

        return init_wrap

    def __init__(self):
        '''
        Constructor
        '''
        #self.apiurl = ""

        self.__read_config__()

    def __read_config__(self):
        config = ConfigParser.ConfigParser()
        config.read("config.ini")

        #接口服务器
        self.apiurl = config.get("api","url")

        #机器人服务器
        self.robothost = config.get("robot","host")
        self.robotport = config.get("robot","port")


"""
我们的任务 , worker,broker 都需要Celery去协调  所以我们需要创建一个Celery对象

"""

from celery import Celery

# import os
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mall.settings")

# 进行Celery允许配置
# 为celery使用django配置文件进行设置
import os

if not os.getenv('DJANGO_SETTINGS_MODULE'):
    os.environ['DJANGO_SETTINGS_MODULE'] = 'mall.settings'

# 以上信息加载到 app创建前面

# selery也是需要使用到django项目中的配置信息的

# 创建celery对象
# 第一步
# 第一个参数,main 一般以celery的文件夹为名字,不要重复
app = Celery(main='celery_tasks')

# 第二步
# app设置broker
# app.config_from_object设置配置文件的路径
app.config_from_object('celery_tasks.config')

# 第三步
# celery可以自动检测任务,检测任务的路径就是任务包的路径
# autodiscover_tasks第一个参数是列表
# 列表中的元素 是任务包的路径
# 路径是从celery_tasks开始就可以
app.autodiscover_tasks(['celery_tasks.sms', 'celery_tasks.email', 'celery_tasks.html'])

# worker 是通过指令来执行的
# celery -A celery实例对象的文件路径   worker -l info

# 这个指令需要在虚拟环境中执行
# celery -A celery_tasks worker -l info

# celery -A celery_tasks.main worker -l info


def sum35(n):
    ''' find the sum of all of the multiples of 3 and 5 under n
    costs: O(n)'''
    count = 0
    for i in range(n + 1):
        if i % 3 == 0 or i % 5 == 0:
            count += i
    return count

# is there a faster way?
''' Maybe you can factor and use the sum of integers equation '''
def sum35_v2(n):
    sum_of_multiples = {}
    for multiple in [3, 5, 15]:
        upper_bound = n // multiple
        sum_of_multiples[multiple] = multiple * (upper_bound * (upper_bound + 1) // 2)
    return sum_of_multiples[3] + sum_of_multiples[5] - sum_of_multiples[15]

''' Now the question is, which one is faster?
    1st one: O(n)
    2nd one:
    Need to answer: How long does integer division take?
    If Python uses repeated subtraction, it would take O(n), or precisely n // d time
    That's for bound
    Multiplication takes O(n^2) or O(n^(log_3_(2)) if the number is big enough
    So the second algorithm is O(n ** 2), which is worse
    '''

print(sum35(15))
print(sum35(1000))
print(sum35_v2(15))


import torch
import zounds
from torch.nn import functional as F
import os
from torch import nn
from featuresynth.data import TrainingData
from featuresynth.generator import DDSPGenerator
from featuresynth.generator.ddsp import np_overlap_add
from featuresynth.util import device
from featuresynth.feature import \
    sr, total_samples, frequency_recomposition, feature_channels, band_sizes, \
    filter_banks, bandpass_filters, slices, compute_features
import numpy as np
from torch.optim import Adam
from featuresynth.discriminator import Discriminator
import os
from random import choice

sr = zounds.SR11025()
scale = zounds.MelScale(zounds.FrequencyBand(20, sr.nyquist), 128)
fb = zounds.learn.FilterBank(
    sr,
    128,
    scale,
    np.linspace(0.25, 0.5, len(scale)),
    normalize_filters=False,
    a_weighting=False).to(device)
fb.filter_bank = fb.filter_bank / 10

def perceptual(x, window=512, log_mag=False):
    x = F.pad(x, (0, window // 2))
    x = torch.stft(x, window, window // 2, normalized=True)
    if log_mag:
        x = torch.log(1e-12 + torch.abs(x[:, :, 0]))
    return x.contiguous().view(x.shape[0], -1)

# def multiscale_loss(x, y, scales=[512, 256, 128, 64]):
#     loss = None
#     for scale in scales:
#         l = torch.abs(perceptual(x, scale) - perceptual(y, scale)).sum()
#         if loss is None:
#             loss = l
#         else:
#             loss += l
#     return loss

def perceptual2(x):
    x = fb.forward(x, normalize=False)
    x = fb.temporal_pooling(x, 512, 256)
    return x

def multiscale_loss(x, y):
    x = fb.forward(x, normalize=False)
    y = fb.forward(y, normalize=False)
    loss = torch.abs(x - y).sum()

    x = fb.temporal_pooling(x, 512, 256)
    y = fb.temporal_pooling(y, 512, 256)
    loss += torch.abs(x - y).sum()

    return loss

def get_filter_coeffs(window_size, n):
    n_coeffs = (window_size // 2) + 1
    start = np.zeros(n_coeffs)
    end = np.zeros(n_coeffs)

    start[0:2] = np.hamming(2)

    end[1:10] = np.hamming(9)

    lines = []
    for i in range(n_coeffs):
        lines.append(np.linspace(start[i], end[i], num=n)[None, :])
    coeffs = np.concatenate(lines, axis=0)[None, :, :]
    return coeffs

def test_spectral_filtering():
    # (1, 129, 64)
    total_samples = 16384
    window_size = 32
    hop_size = 16

    coeffs = get_filter_coeffs(window_size, total_samples // hop_size)

    noise = np.random.uniform(-1, 1, total_samples)
    noise = np.pad(noise, ((0, hop_size),), mode='constant')
    windowed = zounds.sliding_window(noise, window_size, hop_size)
    # (1, 64, 256)
    noise_coeffs = np.fft.rfft(windowed, axis=-1, norm='ortho')
    # (1, 64, 129)

    filtered = coeffs.transpose((0, 2, 1)) * noise_coeffs
    recovered = np.fft.irfft(filtered, axis=-1, norm='ortho')
    samples = np_overlap_add(recovered[:, None, :, :], apply_window=True)
    samples = samples.squeeze()[:total_samples]
    # (1, 64, 256)
    return zounds.AudioSamples(samples, zounds.SR11025()).pad_with_silence()

# def test_spectral_filtering_torch():
#     coeffs = get_filter_coeffs(256)
#     coeffs = torch.from_numpy(coeffs).float()
#
#     noise = torch.FloatTensor(16384).uniform_(-1, 1)
#     windowed = noise.unfold(-1, 256, 256)
#     noise_coeffs = torch.rfft(windowed, 1, normalized=True)
#     noise_coeffs = noise_coeffs.view(1, 64, 129, 2)
#
#     coeffs = coeffs.permute(0, 2, 1)[..., None]
#
#     filtered = coeffs * noise_coeffs
#     recovered = torch.irfft(filtered, 1, normalized=True, signal_sizes=(256,))
#     recovered = recovered.view(-1)
#     return zounds.AudioSamples(
#         recovered.data.cpu().numpy().squeeze(),
#         zounds.SR11025()
#     ).pad_with_silence()

real_noise = zounds.AudioSamples(
    np.random.uniform(-1, 1, 16384),
    zounds.SR11025()
).pad_with_silence()
spec_test = test_spectral_filtering()
# spec_test /= (spec_test.max() + 1e-12)
# torch_spec_test = test_spectral_filtering_torch()
# torch_spec_test /= (torch_spec_test.max() + 1e-12)

if __name__ == '__main__':
    app = zounds.ZoundsApp(globals=globals(), locals=locals())
    app.start_in_thread(8888)

    feature_size = 64

    g = DDSPGenerator(feature_size, feature_channels, 128, None, None, None,
                      None) \
        .to(device) \
        .initialize_weights()
    g_optim = Adam(g.parameters(), lr=0.001, betas=(0, 0.9))

    base_path = '/hdd/musicnet/train_data'
    files = os.listdir(base_path)
    file = choice(files)
    samples = zounds.AudioSamples.from_file(
        os.path.join(base_path, file))[:zounds.Seconds(10)]
    samples = zounds.soundfile.resample(samples, zounds.SR11025())

    start = np.random.randint(0, len(samples) - 16384)
    chunk = samples[start: start + 16384]
    chunk /= (chunk.max() + 1e-12)
    # chunk = spec_test[:16384].astype(np.float32)
    orig = chunk.pad_with_silence()

    target = torch.from_numpy(chunk).to(device).view(1, -1)

    current = None
    inp = compute_features(chunk)
    inp = torch.from_numpy(inp).to(device)
    cond = inp.data.cpu().numpy().squeeze().T

    while True:
        g_optim.zero_grad()
        harmonic, noise, loudness, frequency, filter_coeffs = g(inp)
        output = (harmonic + noise).view(1, -1)

        h = harmonic.data.cpu().numpy().squeeze()
        n = noise.data.cpu().numpy().squeeze()
        h = zounds.AudioSamples(h, zounds.SR11025()).pad_with_silence()
        n = zounds.AudioSamples(n, zounds.SR11025()).pad_with_silence()
        fc = filter_coeffs.data.cpu().numpy().squeeze().T

        l = loudness.data.cpu().numpy().squeeze()
        f = frequency.data.cpu().numpy().squeeze()

        current = zounds.AudioSamples(output.data.cpu().numpy().squeeze(),
                                      zounds.SR11025()).pad_with_silence()

        # loss = multiscale_loss(target, output, scales=[512])
        # loss = torch.abs(perceptual2(target) - perceptual2(output)).sum()
        # loss = torch.abs(
        #     perceptual(target, log_mag=True) -
        #     perceptual(output, log_mag=True)).sum()

        loss = multiscale_loss(target, output)

        loss.backward()

        # for grad in zounds.learn.util.gradients(g):
        #     print(grad)

        g_optim.step()
        print(loss.item())


import time
import numpy as np
from sklearn.metrics import roc_auc_score
from collections import defaultdict
import math

def print_list(in_list):
    line=''
    for item in in_list:
        line=line+str(item)+' '
    return line[0:-1]

def compute_det_curve(target_scores, nontarget_scores):
    n_scores = len(target_scores) + len(nontarget_scores)
    all_scores = np.concatenate((target_scores, nontarget_scores))
    labels = np.concatenate((np.ones(len(target_scores)), np.zeros(len(nontarget_scores))))
    # Sort labels based on scores
    indices = np.argsort(all_scores, kind='mergesort')
    labels = labels[indices]
    # Compute false rejection and false acceptance rates
    tar_trial_sums = np.cumsum(labels)
    nontarget_trial_sums = len(nontarget_scores) - (np.arange(1, n_scores + 1) - tar_trial_sums)
    # value <=thresholds，missing report
    frr = np.concatenate((np.atleast_1d(0), tar_trial_sums / len(target_scores)))  # false rejection rates
    far = np.concatenate((np.atleast_1d(1), nontarget_trial_sums / len(nontarget_scores)))  # false acceptance rates
    thresholds = np.concatenate((np.atleast_1d(all_scores[indices[0]] - 0.001), all_scores[indices]))  # Thresholds are the sorted scores
    return frr, far, thresholds

#target_scores,positive sample
def compute_eer(target_scores, nontarget_scores):
    """ Returns equal error rate (EER) and the corresponding threshold. """
    frr, far, thresholds = compute_det_curve(target_scores, nontarget_scores)
    #draw table Far
    # eer
    abs_diffs = np.abs(frr - far)
    min_index = np.argmin(abs_diffs)
    eer = np.mean((frr[min_index], far[min_index]))
    # FRR@FAR10% (%) approximate value
    abs_diffs_10 = np.abs(far - 0.1)
    min_index_10 = np.argmin(abs_diffs_10)
    frr_10 = round(np.mean(frr[min_index_10]),2)
    return eer, thresholds[min_index],frr_10,far, thresholds

# draw distribute table params, x num label,max_x
graph_group_num = 20
margin = 1
def compute_far(far_list,thresholds_list,group_num):
    # compute_far for FAR curse
    step=round(margin/group_num,4)
    sample_far_list=[]
    sample_thresholds_list=[]
    for i in range(0,group_num):
        # approximate value
        x=step/2+i*step
        temp_list=[abs(k-x) for k in thresholds_list]
        min_index = np.argmin(temp_list)
        sample_thresholds_list.append(round(x,4))
        sample_far_list.append(round(far_list[min_index],4))
    return sample_thresholds_list,sample_far_list

def compute_auc(real_distance_list,fake_distance_list):
    real_length = len(real_distance_list)
    fake_length = len(fake_distance_list)
    # print("real_len", real_length)
    # print("fake_len", fake_length)
    all_distances = np.concatenate((real_distance_list, fake_distance_list))
    labels = np.concatenate((np.ones(real_length), np.zeros(fake_length)))
    auc = roc_auc_score(labels, all_distances)
    return auc

#0-1化处理,阈值也要进行01化处理
def compute_distribution(real_distance_list,fake_distance_list,group_num):
    #分成
    step=round(margin/group_num,2)
    real_group_list=[0]*group_num
    fake_group_list=[0]*group_num
    for item in real_distance_list:
        i=int(item//step)
        real_group_list[i]=real_group_list[i]+1
    for item in fake_distance_list:
        i = int(item // step)
        fake_group_list[i]=fake_group_list[i]+1
    real_group_list=[round(i/len(real_distance_list),2) for i in real_group_list]
    fake_group_list=[round(i/len(fake_distance_list),2) for i in fake_group_list]
    return real_group_list,fake_group_list

def calculate_metrics(real_clip_distance_map,fake_clip_distance_map,label,iteration,evaluate_path):
    real_clip_distance_list = []
    fake_clip_distance_list = []
    # mean
    real_video_distance_list = []
    fake_video_distance_list = []
    # video metrics
    real_video_distance_map = defaultdict(lambda: [])
    fake_video_distance_map = defaultdict(lambda: [])
    for key, value in real_clip_distance_map.items():
        value=1.0/(np.mean(value)+0.1)
        real_clip_distance_list.append(value)
        # real_fadg0_sa1_SH_num
        part_list=key.split('_')
        video_key=part_list[0]+'_'+part_list[1]+'_'+part_list[2]
        if video_key in real_video_distance_map.keys():
            real_video_distance_map[video_key].append(value)
        else:
            real_video_distance_map[video_key]=[value]

    for key, value in fake_clip_distance_map.items():
        value=1.0/(np.mean(value)+0.1)
        fake_clip_distance_list.append(value)
        part_list = key.split('_')
        video_key = part_list[0] + '_' + part_list[1] + '_' + part_list[2]
        if video_key in fake_video_distance_map.keys():
            fake_video_distance_map[video_key].append(value)
        else:
            fake_video_distance_map[video_key] = [value]

    for _,value in real_video_distance_map.items():
        real_video_distance_list.append(np.mean(value))
    for _, value in fake_video_distance_map.items():
        fake_video_distance_list.append(np.mean(value))
    # standardization
    real_clip_distance_list = [math.log(i) for i in real_clip_distance_list]
    fake_clip_distance_list = [math.log(i) for i in fake_clip_distance_list]
    real_video_distance_list = [math.log(i)  for i in real_video_distance_list]
    fake_video_distance_list = [math.log(i) for i in fake_video_distance_list]
    clip_min_point=min(min(real_clip_distance_list),min(fake_clip_distance_list))
    clip_max_point=max(max(real_clip_distance_list),max(fake_clip_distance_list))+0.0001
    video_min_point = min(min(real_video_distance_list), min(fake_video_distance_list))
    video_max_point = max(max(real_video_distance_list), max(fake_video_distance_list))+0.0001

    real_clip_distance_list=[margin*(i-clip_min_point)/(clip_max_point-clip_min_point) for i in real_clip_distance_list]
    fake_clip_distance_list=[margin*(i-clip_min_point)/(clip_max_point-clip_min_point) for i in fake_clip_distance_list]
    real_video_distance_list = [margin*(i - video_min_point) / (video_max_point - video_min_point) for i in real_video_distance_list]
    fake_video_distance_list = [margin*(i - video_min_point) / (video_max_point - video_min_point) for i in fake_video_distance_list]

    # ROC video
    clip_auc  = compute_auc(real_clip_distance_list, fake_clip_distance_list)
    clip_eer, clip_thresholds,clip_frr_10,clip_far_list, clip_thresholds_list = compute_eer(real_clip_distance_list, fake_clip_distance_list)
    sample_clip_thresholds_list, sample_clip_far_list = compute_far(clip_far_list, clip_thresholds_list, graph_group_num)
    real_clip_group_list,fake_clip_group_list=compute_distribution(real_clip_distance_list, fake_clip_distance_list,graph_group_num)
    video_auc  = compute_auc(real_video_distance_list, fake_video_distance_list)
    video_eer, video_thresholds,video_frr_10,video_far_list, video_thresholds_list = compute_eer(real_video_distance_list, fake_video_distance_list)
    sample_video_thresholds_list, sample_video_far_list = compute_far(video_far_list, video_thresholds_list, graph_group_num)
    real_video_group_list, fake_video_group_list = compute_distribution(real_video_distance_list, fake_video_distance_list, graph_group_num)
    print('clip_AUC:{},clip_eer:{},clip_thresholds:{},clip_frr_10:{}'.format(clip_auc,clip_eer,clip_thresholds,clip_frr_10))
    print('video_AUC:{},video_eer:{},video_thresholds:{},video_frr_10:{}'.format(video_auc,video_eer,video_thresholds,video_frr_10))
    real_clip_group_list_line='real_clip_group_list:'+print_list(real_clip_group_list)
    fake_clip_group_list_line='fake_clip_group_list:'+print_list(fake_clip_group_list)
    real_video_group_list_line='real_video_group_list:'+print_list(real_video_group_list)
    fake_video_group_list_line='fake_video_group_list:'+print_list(fake_video_group_list)

    sample_clip_thresholds_list_line='sample_clip_thresholds_list:'+print_list(sample_clip_thresholds_list)
    sample_clip_far_list_line='sample_clip_far_list :'+print_list(sample_clip_far_list)
    sample_video_thresholds_list_line='sample_video_thresholds_list :'+print_list(sample_video_thresholds_list)
    sample_video_far_list_line='sample_video_far_list :'+print_list(sample_video_far_list)

    print(real_clip_group_list_line)
    print(fake_clip_group_list_line)
    print(real_video_group_list_line)
    print(fake_video_group_list_line)
    print(sample_clip_thresholds_list_line)
    print(sample_clip_far_list_line)
    print(sample_video_thresholds_list_line)
    print(sample_video_far_list_line)

    # record train and infer line
    with open(evaluate_path, 'a') as model_f:
        line0 = '\n'+label+':'+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+' model_'+str(iteration)+ '\n'
        line1 = 'clip_auc:' + ' ' + str(clip_auc) + '\n'
        line2 = 'clip_eer:' + ' ' + str(clip_eer) + '  '+'clip_thresholds:'+str(clip_thresholds)+'  '+'clip_frr_10:'+str(clip_frr_10)+ '\n'
        line3 = 'video_auc:' + ' ' + str(video_auc) + '\n'
        line4 = 'video_eer:' + ' ' + str(video_eer) + '  ' + 'video_thresholds:' + str(video_thresholds)+'  '+'video_frr_10:'+str(video_frr_10)+ '\n'
        model_f.write(line0)
        model_f.write(line1)
        model_f.write(line2)
        model_f.write(line3)
        model_f.write(line4)
        model_f.write(real_clip_group_list_line+'\n')
        model_f.write(fake_clip_group_list_line+'\n')
        model_f.write(real_video_group_list_line+'\n')
        model_f.write(fake_video_group_list_line+'\n')

        model_f.write(sample_clip_thresholds_list_line + '\n')
        model_f.write(sample_clip_far_list_line + '\n')
        model_f.write(sample_video_thresholds_list_line + '\n')
        model_f.write(sample_video_far_list_line + '\n')
        meta={
            'clip_auc':clip_auc,
            'clip_eer':clip_eer,
            'clip_thresholds':clip_thresholds,
            'clip_frr_10':clip_frr_10,
            'video_auc': video_auc,
            'video_eer': video_eer,
            'video_thresholds': video_thresholds,
            'video_frr_10': video_frr_10,
        }
    return meta

def test_auc():
    real_clip_distance_map = {
        'real_fadg0_sa1_0':1,
        'real_fadg0_sa2_1':1,
        'real_fadg0_sa3_2':3,
        'real_fadg0_sa1_5':4,
    }
    fake_clip_distance_map = {
        'fake_fadg0_sa4_0': 11,
        'fake_fmdg0_sa1_1': 7,
        'fake_fkdg0_sa2_1': 32,
        'fake_fkdu0_sa8_1': 9,
    }
    calculate_metrics(real_clip_distance_map,fake_clip_distance_map,'real',9,'path')

# def test_table():
#     real_distance_list=[1,2,3,4,5]
#     fake_distance_list=[6,7,8,9,10]
#     a,b=compute_table(real_distance_list, fake_distance_list,10)
#     print('hello')
#test_auc()


# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回对应节点TreeNode
    def KthNode(self, pRoot, k):
        # write code here
        lst = []
        def helper(root):
            if not root:
                return
            helper(root.left)
            lst.append(root)
            helper(root.right)
        helper(pRoot)
        if 0 < k <= len(lst):
            return lst[k - 1]
        return None

62-二叉搜索树的第k个结点.py


import subprocess

class NoTerminal:
    f = ""
    o = ""
    def main(self):
        f = raw_input("Enter file names: ")
        o = raw_input("Enter output names: ")
        self.callShell(f, o)

    def callShell(self, files, output):
        subprocess.call("g++ -std=c++11 " + files + " -o " + output, shell=True)

nt = NoTerminal()
nt.main()


try:
    import vrep
except:
    print ('--------------------------------------------------------------')
    print ('"vrep.py" could not be imported. This means very probably that')
    print ('either "vrep.py" or the remoteApi library could not be found.')
    print ('Make sure both are in the same folder as this file,')
    print ('or appropriately adjust the file "vrep.py"')
    print ('--------------------------------------------------------------')
    print ('')

import time
import numpy as np
import params
import yaml
import argparse
from   utilities import *
from math import sqrt

global angErrHist
global distErrHist

angErrHist = []
distErrHist = []

print ('Program started')

# 3. Routine to get the Distance and angular errors for the go-to-goal PID controller:
def g2g_xy_errors(clientID, pioneerHandle, goal):

    # a: Stream current position and orientation:
    res , pioneerPosition = vrep.simxGetObjectPosition(clientID, pioneerHandle, -1 , vrep.simx_opmode_buffer)
    res , pioneerOrientation = vrep.simxGetObjectOrientation(clientID, pioneerHandle, -1 , vrep.simx_opmode_buffer)

    xp = pioneerPosition[0]
    yp = pioneerPosition[1]
    thetap = pioneerOrientation[2]

    # # VREP orientation returns a value between -pi to +pi. Trnasform this to the range o to 2*pi
    # if thetap < 0:
    #
    #     thetap = 2*np.pi + thetap
    #
    # print ("Thetap -> " , thetap)

    xg = goal[0]
    yg = goal[1]

    diff_x = xg - xp
    diff_y = yg - yp

    # b. Compute orientation error:
    targetOrientation = np.arctan2( diff_y , diff_x)

    # # Arctan2 returns a value between -pi to +pi. Trnasform this to the range o to 2*pi
    # if targetOrientation < 0:
    #
    #     targetOrientation = 2*np.pi + targetOrientation
    #
    # print ("Target -> " , thetap)

    errAng = targetOrientation - thetap

    # Restrict to -pi and +pi:
    errAng = np.mod((errAng+ np.pi), 2*np.pi) - np.pi

    if abs(errAng) < params.angErrThresh:

        reachedOrientation = True
    else:
        reachedOrientation = False

    # c. Compute distance error:
    errDist = np.sqrt( (xg - xp)**2 + (yg - yp)**2)

    if errDist < params.distErrThresh:

        reachedGoal = True
    else:

        reachedGoal = False

    # Return the values:
    return errAng, errDist, reachedOrientation , reachedGoal

# 4. Function to map unicycle commands to differential drive commands:
def diff_drive_map(v,omega, trackWidth,wheelRadius):

    # TO DO: Document the formulas in detail here:

    # limit the meximun velocity
    meximumVelocity = 6

    # 1. Left wheel angular velocity:
    omegaLeft = (v + 0.5*trackWidth*omega)/wheelRadius
    if omegaLeft <= meximumVelocity:
        omegaLeft = (v + 0.5*trackWidth*omega)/wheelRadius
        # omegaLeft = sqrt(x**2+y**2)/t
    else:
        omegaLeft = meximumVelocity

    # 2. Right wheel angular velocity:
    omegaRight = (v - 0.5*trackWidth*omega)/wheelRadius
    if omegaRight <= meximumVelocity:
        omegaRight = (v - 0.5*trackWidth*omega)/wheelRadius
        # omegaRight = sqrt(x**2+y**2)/t
    else:
        omegaRight = meximumVelocity

    return omegaLeft , omegaRight

# 5. Go to Goal PID control from a 2-D differential drive robot:
def g2g_controller_PID(clientID, pioneerHandle, pioneerLeftMotorHandle, pioneerRightMotorHandle, goal):

    global angErrHist , distErrHist

    # Set the sleep time in While function
    sleepTime = 0.2

    # a. Setup internal parameters of the PID controller:
    reachedGoal = False
    reachedOrientation = False
    wheelRadius = 0.0975   # meters - From VREP model of left wheel
    trackWidth = 0.4       # meters - This is approximate
    v= 0
    omega = 0

    timer = 0

    # Continue this as long as the Robot does not reach its goal:
    while not reachedGoal:

        errAng, errDist, reachedOrientation , reachedGoal = g2g_xy_errors(clientID, pioneerHandle, goal)

        # print (" Time = " , timer , " sec" , end= " -> ")
        # print ("Angular Error =  " , errAng, end= " -> ")
        # print (" Distance Error = " , errDist)

        # Append error values to the cache variabes:
        angErrHist.append(errAng)
        distErrHist.append(errDist)

        # Orientation correction:
        if not reachedOrientation:

            # PID control law for Orientation:
            v = 0

            if len(angErrHist) > params.integralWindow:
                omega = (-params.kpTheta*errAng - params.kdTheta*(errAng - angErrHist[-2]) - params.kiTheta*sum(angErrHist[-params.integralWindow:]))

            elif len(angErrHist) > 2:

                omega = (-params.kpTheta*errAng - params.kdTheta*(errAng - angErrHist[-2]) - params.kiTheta*sum(angErrHist))

            else:

                omega =  (-params.kpTheta*errAng)

            omegaLeft , omegaRight  = diff_drive_map(v,omega,trackWidth,wheelRadius)

            res = vrep.simxSetJointTargetVelocity(clientID, pioneerLeftMotorHandle, omegaLeft, vrep.simx_opmode_oneshot_wait)
            res = vrep.simxSetJointTargetVelocity(clientID, pioneerRightMotorHandle, omegaRight, vrep.simx_opmode_oneshot_wait)

        # Distance correction:
        else:

            # Clear the angular error history cache:
            angErrHist = []

            omega = 0.0

            if  len(distErrHist) > params.integralWindow:
                v = 8*(params.kpDist*errDist + params.kdDist*(errDist - distErrHist[-2]) + params.kiDist*sum(distErrHist[-params.integralWindow:]))

            elif len(distErrHist) > 2:

                v = 8*(params.kpDist*errDist + params.kdDist*(errDist - distErrHist[-2]) + params.kiDist*sum(distErrHist))

            else:
                v = 8*(params.kpDist*errDist)

            omegaLeft , omegaRight  = diff_drive_map(v,omega,trackWidth, wheelRadius)

            res = vrep.simxSetJointTargetVelocity(clientID, pioneerLeftMotorHandle, omegaLeft, vrep.simx_opmode_oneshot_wait)
            res = vrep.simxSetJointTargetVelocity(clientID, pioneerRightMotorHandle, omegaRight, vrep.simx_opmode_oneshot_wait)

        # Set the frequency of the controller:
        time.sleep(sleepTime)

    # Notify the user:
    #print(" Robot reached its Goal!")

    # Clear the error history caches:
    angErrHist = []
    distErrHist = []

    v= v/2
    omega = 0

    omegaLeft , omegaRight  = diff_drive_map(v,omega,trackWidth,wheelRadius)

    # Deactivate joint actuations:
    res = vrep.simxSetJointTargetVelocity(clientID, pioneerLeftMotorHandle, omegaLeft, vrep.simx_opmode_oneshot_wait)
    res = vrep.simxSetJointTargetVelocity(clientID, pioneerRightMotorHandle, omegaRight, vrep.simx_opmode_oneshot_wait)

    return reachedGoal

# ---------------------------------- MAIN SCRIPT BEGINS HERE -----------------------------------------------------------------------------#

vrep.simxFinish(-1) # just in case, close all opened connections
clientID=vrep.simxStart('127.0.0.1',19997,True,True,5000,5) # Connect to V-REP
if clientID!=-1:

    print ('Connected to remote API server')

    # 2.a: Handle the Pioneer:
    res , pioneerHandle = vrep.simxGetObjectHandle(clientID, "Pioneer_p3dx", vrep.simx_opmode_blocking)
    res,  pioneerLeftMotorHandle = vrep.simxGetObjectHandle(clientID, "left", vrep.simx_opmode_blocking)
    res,  pioneerRightMotorHandle = vrep.simxGetObjectHandle(clientID, "right", vrep.simx_opmode_blocking)

    # Get the position of the Pioneer for the first time in streaming mode: Still have to understand why this is done!
    res , pioneerPosition = vrep.simxGetObjectPosition(clientID, pioneerHandle, -1 , vrep.simx_opmode_streaming)
    res , pioneerOrientation = vrep.simxGetObjectOrientation(clientID, pioneerHandle, -1 , vrep.simx_opmode_streaming)

    # Deactivate joint actuations:Make sure Pioneer is stationary:
    res = vrep.simxSetJointTargetVelocity(clientID, pioneerLeftMotorHandle, 0, vrep.simx_opmode_streaming)
    res = vrep.simxSetJointTargetVelocity(clientID, pioneerRightMotorHandle, 0, vrep.simx_opmode_streaming)

    ### Step 3: Start the Simulation: Keep printing out status messages!!!
    res = vrep.simxStartSimulation(clientID, vrep.simx_opmode_oneshot_wait)

    if res == vrep.simx_return_ok:

        print ("---!!! Started Simulation !!! ---")

    ### Step 3: Perception:  TO BE DONE:

    # # First call:
    # res,resolution,image=vrep.simxGetVisionSensorImage(clientID, quadCameraHandle,0,vrep.simx_opmode_streaming)
    # print ('firts call',res)
    # time.sleep(5)
    # res,resolution,image=vrep.simxGetVisionSensorImage(clientID, quadCameraHandle,0,vrep.simx_opmode_buffer)
    # print ('second call',res)
    #
    # if res == vrep.simx_return_ok:
    #
    #     print (" successful first image!")
    #
    # time.sleep(5)
    #
    # while (vrep.simxGetConnectionId(clientID) != -1):
    #
    #      res, resolution, image = vrep.simxGetVisionSensorImage(clientID, quadCameraHandle, 0, vrep.simx_opmode_buffer)
    #
    #      print (res)
    #
    #      if res == vrep.simx_return_ok:
    #          print (len(image))

    # # 3. Setup for vectorization:
    # setup_vec()

    # 4. Run the RRT algorithm and directly plot the path:
    startTime = time.time()
    # RRT_path = RRT(start, goal)
    endTime = time.time()

    # Paht for robots
    revPath = []
    output_time=[]
    scale = 1

    # 5. Get the true path from start to goal:
    with open("output.yaml", 'r') as output_file:
        data = yaml.load(output_file, Loader=yaml.FullLoader)
        agent1 = data['agent1']
        agent0 = data['agent0']

    # set agent
    for element in agent0:
        x = element['x'] * scale
        y = element['y'] * scale
        t = element['t']
        coordinates = [x, y]
        element_time = [t]
        output_time.append(element_time)
        revPath.append(coordinates)

    # revPath = reverse_path(RRT_path)
    # revPath = [[10.0,0.0],[10.0, -10.0],[6,-4],[8,7],[-4,-4.0],[0,0]]

    timeRRT= endTime - startTime

    print (" Time taken time is : " , timeRRT ,  "secs")
    print (" The RRT path is : ")
    print (revPath)
    # ----------------------------------------------------- #

    # Start a timer:
    sTime = time.time()

    pathPointCount = 0

    # Loop to traverse RRT Path:
    for immGoal in revPath:

        # Run the Go-to-goal control function:
        reached = g2g_controller_PID(clientID, pioneerHandle, pioneerLeftMotorHandle, pioneerRightMotorHandle, immGoal)

        if reached:

            # Increment the path point count:
            pathPointCount +=1

            print (" Reached node # " , pathPointCount )
            print (" ---------------------------------")

        else:

            print(" There was an ERROR! Please investigate!!!")

    eTime = time.time()

    travelTime = eTime - sTime

    # Display successful path planning message!:
    print ("--- Robot has Successfully reached its final Goal --- ")
    print (" The toal time taken is : " , travelTime , " secs")
    print ("The robot position is : ", pioneerPosition)

    # Set the joint velocities back to zero:
    res = vrep.simxSetJointTargetVelocity(clientID, pioneerLeftMotorHandle, 0, vrep.simx_opmode_streaming)
    res = vrep.simxSetJointTargetVelocity(clientID, pioneerRightMotorHandle, 0, vrep.simx_opmode_streaming)

    # Stop the simulation:
    res = vrep.simxStopSimulation(clientID, vrep.simx_opmode_oneshot_wait)

    if res == vrep.simx_return_ok:

        print (" --- !!!Stopped Simulation!!! ---")

    # Now close the connection to V-REP:
    vrep.simxFinish(clientID)

else:

    print ('Failed connecting to remote API server')

print (' --- Python Remote API Program ended ---')


import mxnet as mx
import numpy as np
import cv2
from tools.image_processing import resize, transform
from tools.rand_sampler import RandSampler

class DetIter(mx.io.DataIter):
    """
    Detection Iterator, which will feed data and label to network
    Optional data augmentation is performed when providing batch

    Parameters:
    ----------
    imdb : Imdb
        image database
    batch_size : int
        batch size
    data_shape : int or (int, int)
        image shape to be resized
    mean_pixels : float or float list
        [R, G, B], mean pixel values
    rand_samplers : list
        random cropping sampler list, if not specified, will
        use original image only
    rand_mirror : bool
        whether to randomly mirror input images, default False
    shuffle : bool
        whether to shuffle initial image list, default False
    rand_seed : int or None
        whether to use fixed random seed, default None
    max_crop_trial : bool
        if random crop is enabled, defines the maximum trial time
        if trial exceed this number, will give up cropping
    is_train : bool
        whether in training phase, default True, if False, labels might
        be ignored
    """
    def __init__(self, imdb, batch_size, data_shape, \
                 mean_pixels=[128, 128, 128], rand_samplers=[], \
                 rand_mirror=False, shuffle=False, rand_seed=None, \
                 is_train=True, max_crop_trial=50):
        super(DetIter, self).__init__()

        self._imdb = imdb
        self.batch_size = batch_size
        if isinstance(data_shape, int):
            data_shape = (data_shape, data_shape)
        self._data_shape = data_shape
        self._mean_pixels = mean_pixels
        if not rand_samplers:
            self._rand_samplers = []
        else:
            if not isinstance(rand_samplers, list):
                rand_samplers = [rand_samplers]
            assert isinstance(rand_samplers[0], RandSampler), "Invalid rand sampler"
            self._rand_samplers = rand_samplers
        self.is_train = is_train
        self._rand_mirror = rand_mirror
        self._shuffle = shuffle
        if rand_seed:
            np.random.seed(rand_seed) # fix random seed
        self._max_crop_trial = max_crop_trial

        self._current = 0
        self._size = imdb.num_images
        self._index = np.arange(self._size)

        self._data = None
        self._label = None
        self._get_batch()

    @property
    def provide_data(self):
        return [(k, v.shape) for k, v in self._data.items()]

    @property
    def provide_label(self):
        if self.is_train:
            return [(k, v.shape) for k, v in self._label.items()]
        else:
            return []

    def reset(self):
        self._current = 0
        if self._shuffle:
            np.random.shuffle(self._index)

    def iter_next(self):
        return self._current < self._size

    def next(self):
        if self.iter_next():
            self._get_batch()
            data_batch = mx.io.DataBatch(data=self._data.values(),
                                   label=self._label.values(),
                                   pad=self.getpad(), index=self.getindex())
            self._current += self.batch_size
            return data_batch
        else:
            raise StopIteration

    def getindex(self):
        return self._current // self.batch_size

    def getpad(self):
        pad = self._current + self.batch_size - self._size
        return 0 if pad < 0 else pad

    def _get_batch(self):
        """
        Load data/label from dataset
        """
        batch_data = []
        batch_label = []
        for i in range(self.batch_size):
            if (self._current + i) >= self._size:
                if not self.is_train:
                    continue
                # use padding from middle in each epoch
                idx = (self._current + i + self._size // 2) % self._size
                index = self._index[idx]
            else:
                index = self._index[self._current + i]
            # index = self.debug_index
            im_path = self._imdb.image_path_from_index(index)
            img = cv2.imread(im_path)
            gt = self._imdb.label_from_index(index).copy() if self.is_train else None
            data, label = self._data_augmentation(img, gt)
            batch_data.append(data)
            if self.is_train:
                batch_label.append(label)
        # pad data if not fully occupied
        for i in range(self.batch_size - len(batch_data)):
            assert len(batch_data) > 0
            batch_data.append(batch_data[0] * 0)
        self._data = {'data': mx.nd.array(np.array(batch_data))}
        if self.is_train:
            self._label = {'label': mx.nd.array(np.array(batch_label))}
        else:
            self._label = {'label': None}

    def _data_augmentation(self, data, label):
        """
        perform data augmentations: crop, mirror, resize, sub mean, swap channels...
        """
        if self.is_train and self._rand_samplers:
            rand_crops = []
            for rs in self._rand_samplers:
                rand_crops += rs.sample(label)
            num_rand_crops = len(rand_crops)
            # randomly pick up one as input data
            if num_rand_crops > 0:
                index = int(np.random.uniform(0, 1) * num_rand_crops)
                width = data.shape[1]
                height = data.shape[0]
                crop = rand_crops[index][0]
                xmin = int(crop[0] * width)
                ymin = int(crop[1] * height)
                xmax = int(crop[2] * width)
                ymax = int(crop[3] * height)
                if xmin >= 0 and ymin >= 0 and xmax <= width and ymax <= height:
                    data = data[ymin:ymax, xmin:xmax, :]
                else:
                    # padding mode
                    new_width = xmax - xmin
                    new_height = ymax - ymin
                    offset_x = 0 - xmin
                    offset_y = 0 - ymin
                    data_bak = data
                    data = np.full((new_height, new_width, 3), 128.)
                    data[offset_y:offset_y+height, offset_x:offset_x + width, :] = data_bak
                label = rand_crops[index][1]

        if self.is_train and self._rand_mirror:
            if np.random.uniform(0, 1) > 0.5:
                data = cv2.flip(data, 1)
                valid_mask = np.where(label[:, 0] > -1)[0]
                tmp = 1.0 - label[valid_mask, 1]
                label[valid_mask, 1] = 1.0 - label[valid_mask, 3]
                label[valid_mask, 3] = tmp

        if self.is_train:
            interp_methods = [cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, \
                              cv2.INTER_NEAREST, cv2.INTER_LANCZOS4]
        else:
            interp_methods = [cv2.INTER_LINEAR]
        interp_method = interp_methods[int(np.random.uniform(0, 1) * len(interp_methods))]
        data = resize(data, self._data_shape, interp_method)
        data = transform(data, self._mean_pixels)
        return data, label


#!/usr/bin/python
# 给定四个包含整数的数组列表 A,B,C,D,计算有多少个元组(i,j,k,l)，使得A[i] + B[j] + C[k] + D[l] = 0。
# 例如：输入: A = [1, 2] B = [-2,-1] C = [-1, 2] D = [0, 2] 输出: 2
# (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
# (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

from typing import Counter

def fourSumCount(A: list, B: list, C: list, D: list):
    # hashmap = dict()
    # for a in A:
    #     for b in B:
    #         if a + b in hashmap:
    #             hashmap[a + b] += 1
    #         else:
    #             hashmap[a + b] = 1

    # count = 0
    # for c in C:
    #     for d in D:
    #         if -c - d in hashmap:
    #             count += hashmap[-c - d]
    # return count

    hashmap = Counter(a + b for a in A for b in B)
    return sum(hashmap.get(-c - d, 0) for c in C for d in D)

def main():
    A = [1, 2]
    B = [-2, -1]
    C = [-1, 2]
    D = [0, 2]
    print(fourSumCount(A, B, C, D))

if __name__ == '__main__':
    main()


import sys
sys.path.append("/Users/inoueshinichi/Desktop/MyGithub/DeepLearning2_NLP") # 親ディレクトリのファイルをインポートするための設定
sys.path.append("/home/inoue/MyGithub/DeepLearning2_NLP")
from common.utils import preprocess, create_co_matrix, cos_similarity, most_similar

def test_most_similar():
    """クエリ単語に対する類似度のランキングを表示
    """
    text = 'You say goodbye and I say hello.'
    corpus, word_to_id, id_to_word = preprocess(text)
    vocab_size = len(word_to_id)
    C = create_co_matrix(corpus, vocab_size)

    most_similar('you', word_to_id, id_to_word, C, top=5)

if __name__ == "__main__":
    test_most_similar()