text:
from discord import Member, StoreChannel, user_command
from discord import Embed
from discord.ext.commands import Cog, command, slash_command, cooldown, BucketType
import random, discord, db, datetime, asyncio, time
from discord.utils import get
from discord.ui import InputText, Modal
import numpy as np
import decimal

# def soal_pilgan():
#     data = {}
#     randomizer = random.randint(0, 54554)
#     temp = db.others_con['others']['eng_dict'].find({'index' : randomizer})[0]
#     answer = temp['word'].lower()
#     clue = temp['meaning']
#     data['soal'] =

# class PilganButton(discord.ui.Button):
#     def __init__(self, pilihan):
#         """
#         A button for one role. `custom_id` is needed for persistent views.
#         """
#         super().__init__(
#             label=pilihan,
#             style=discord.enums.ButtonStyle.secondary,
#             custom_id=str(f'{pilihan}_id'),
#         )

#     async def callback(self, interaction: discord.Interaction):
#         """This function will be called any time a user clicks on this button.
#         Parameters
#         ----------
#         interaction : discord.Interaction
#             The interaction object that was created when a user clicks on a button.
#         """
#         # Figure out who clicked the button.
#         user = interaction.user
#         # Get the role this button is for (stored in the custom ID).
#         role = interaction.guild.get_role(int(self.custom_id))

#         if role is None:
#             # If the specified role does not exist, return nothing.
#             # Error handling could be done here.
#             return

#         # Add the role and send a response to the uesr ephemerally (hidden to other users).
#         if role not in user.roles:
#             # Give the user the role if they don't already have it.
#             await user.add_roles(role)
#             await interaction.response.send_message(f"🎉 You have been given the role {role.mention}", ephemeral=True)
#         else:
#             # Else, Take the role from the user
#             await user.remove_roles(role)
#             await interaction.response.send_message(
#                 f"❌ The {role.mention} role has been taken from you", ephemeral=True
#             )

def faktorial(n):
    if n == 0:
        return 1
    else:
        return n * faktorial(n - 1)

class Games(Cog):
    def __init__(self, bot):
        self.bot = bot

    @command(name='quiz.algorithm')
    @cooldown(1, 240, BucketType.user)
    async def algorithm_quiz(self, ctx):
        """
        > Shows an algorithm quiz. Your task is to answer correctly. Rewards exp if win and minus a quarter of the rewards if lost.

        **Params:**
        >    no params required

        **Returns:**
        >    **`embed`** → question

        **Example:**
        > ```<prefix>quiz.algorithm```
        """

        # det = {
        #     0 : 'Coin Change',
        #     1 : 'Fibonacci Series',
        #     2 : 'Factorial',
        #     3 : 'Grid Traveler'
        # }

        # determiner = np.random.choice([0, 1], 1, p = [0.25, 0.25, 0.25, 0.25])[0]
        determiner = np.random.choice([0, 1], 1)[0]

        if determiner == 0:
            # ===========
            # dp function
            # ===========
            m = [1, 2, 5, 10, 20, 50, 100]
            memo = {}

            def dpCoin2(n):
                memo[0] = 0

                for i in range(1, n + 1):
                    best = 1e20
                    for j in m:
                        if j <= i:
                            best = min(best, memo[i - j] + 1)
                            memo[i] = best

                return memo[n]

            det_ = random.choice([(2, 1e2), (3, 1e3), (4, 1e4), (5, 1e5)])
            money = n = int(round(random.random(), det_[0]) * det_[1])
            memo = {x:0 for x in range(0, n + 1)}

            random_char = list(map(chr, range(97, 122)))[random.randint(0, 24)].upper()

            soal = [(f"Diketahui bahwa ada {len(m)} jenis dollar, yaitu {', '.join(['$' + str(i) for i in m])}. Jika {random_char} menghendaki uang sebanyak ${money}, maka banyak lembaran paling minimum yang dapat diterima {random_char} adalah ...",
                     dpCoin2(money))]

            soal = random.choice(soal)

            timeout = det_[0] * 50
            exp_multiplier = det_[0] * 120

            answer = soal[1]

            soal_embed = Embed(title = 'Solve this question!')
            soal_embed.add_field(name='Question', value=f'```{soal[0]}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal_embed.add_field(name='Reminder', value=f"```You can code for answer```", inline=False)
            soal_e = await ctx.reply(embed=soal_embed)

        if determiner == 1:
            def formulaFib(n):
                decimal.getcontext().prec = int(n / 3)

                root_5 = decimal.Decimal(5).sqrt()
                phi = ((1 + root_5) / 2)

                a = ((phi ** n) - ((-phi) ** -n)) / root_5

                return round(a)

            det_ = random.choice([(2, 1e2), (3, 1e3), (4, 1e4), (5, 1e5)])
            n = int(round(random.random(), det_[0]) * det_[1])

            soal = [(f"Let f(0) = 0,\n    f(1) = 1,\nand f(n) = f(n - 1) + f(n - 2)\nthen f({n}) = ...",
                     str(formulaFib(n))[:2000]),

                    (f"Let f(0) = 0,\n    f(1) = 1,\nand f(n) = f(n - 1) + f(n - 2)\nthen f({n}) consists of ... digits.",
                       len(str(formulaFib(n)))),

                    (f"Let f(0) = 0,\n    f(1) = 1,\nand f(n) = f(n - 1) + f(n - 2)\nthen sum of each digits of f({n}) is ...",
                       sum([int(x) for x in str(formulaFib(n))]))]

            soal = random.choice(soal)

            timeout = det_[0] * 50
            exp_multiplier = det_[0] * 120

            answer = soal[1]

            soal_embed = Embed(title = 'Solve this question!')
            soal_embed.add_field(name='Question', value=f'```{soal[0]}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal_embed.add_field(name='Reminder', value=f"```You can code for answer. If the answer has > 2000 digits, answer with last 2000 digits of the number.```", inline=False)
            soal_e = await ctx.reply(embed=soal_embed)

        def is_correct(m):
            return m.author == ctx.author

        try:
            start_time = time.time()
            guess = await self.bot.wait_for("message", check=is_correct, timeout=timeout)
        except asyncio.TimeoutError:
            db.add_exp(ctx.author.id, int(-1/4*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))

            soal_embed = Embed(title = 'Question Summary')
            soal_embed.add_field(name='Correct Answer', value=f"```{answer}```", inline=False)
            await soal_e.edit(embed=soal_embed)

            return await ctx.reply(embed=Embed(title="Time's Up!", description=f'Your exp was decreased by **`{int(1/4*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier))}`**'))

        if str(guess.content) == str(answer) or float(guess.content) == float(answer):
            db.add_exp(ctx.author.id, int(exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))

            await soal_e.edit(embed=Embed(title='You got that!', description=f'Your exp was increased by **`{int(exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier))}`**'))
            await guess.delete()
        else:
            db.add_exp(ctx.author.id, int(-1/4*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))

            soal_embed = Embed(title = 'Question Summary')
            soal_embed.add_field(name='Correct Answer', value=f"```{answer}```", inline=False)
            await soal_e.edit(embed=soal_embed)

            await ctx.reply(embed=Embed(title='Oops!', description=f'Your exp was decreased by **`{int(1/4*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier))}`**'))

    @command(name='quiz.basic-math')
    @cooldown(1, 60, BucketType.user)
    async def basic_math(self, ctx, level = 1):
        """
        > Shows a simple mathematic sentence. Your task is to answer correctly. Rewards `level * (30 + (operator * 10) + (length each operand * 10))` exp if win and minus half of the rewards if lost. You should answer within `level / 2 * (5 + (operator * 3) + (length each operand * 2))` seconds. Answer decimal with round 2 numbers behind dot.

        **Params:**
        >    **`level`** → question level, default to `{1}` max `{5}`

        **Returns:**
        >    **`embed`** → math question

        **Example:**
        > ```<prefix>quiz.basic-math 3```
        """
        if level < 1 or level > 5:
            ctx.command.reset_cooldown(ctx)
            raise Exception('level should not exceeds range between 1 and 5')

        det = {
            1 : [[1, 6], [1,  10],      [0.4, 0.4, 0.2, 0]],
            2 : [[2, 6], [10, 100],     [0.4, 0.4, 0.2, 0]],
            3 : [[3, 7], [100, 500],    [0.3, 0.4, 0.2, 0.1]],
            4 : [[4, 7], [100, 500],    [0.3, 0.3, 0.2, 0.2]],
            5 : [[5, 8], [100,  1000],  [0.25, 0.25, 0.25, 0.25]]
        }

        chc = det[int(level)]

        randomizer = random.randint(chc[0][0], chc[0][1])
        math_sentence = ''
        math_sentence_true = ''
        operand = np.random.choice([x for x in range(chc[1][0], chc[1][1])], randomizer + 1)
        operator = np.random.choice(['+', '-', '*', '/'], randomizer, p=chc[2])

        for i in range(randomizer):
            math_sentence_true += f'{operand[i]} {operator[i]} '
            math_sentence += f'{operand[i]}⠀{operator[i]}⠀' # inserting U+2800 as invisible character to prevent copy - paste

        math_sentence_true += str(operand[randomizer])
        math_sentence += str(operand[randomizer])

        timeout = level * (5 + (len(operator) * 3) + (sum(len(str(x)) for x in operand) * 2))
        exp_multiplier = level * (30 + (len(operator) * 10) + (sum(len(str(x)) for x in operand) * 5))

        answer = round(eval(math_sentence_true), 2)

        soal_embed = Embed(title = 'Solve this question!')
        soal_embed.add_field(name='Math sentence', value=f'```{math_sentence}```', inline=False)
        soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
        soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
        soal_embed.add_field(name='Reminder', value=f"```If the question contains division (/), always put dot, and round two numbers\nExample  : 12.345 → 12.35\n         : 12     → 12.00```", inline=False)
        soal = await ctx.reply(embed=soal_embed)

        def is_correct(m):
            return m.author == ctx.author

        try:
            guess = await self.bot.wait_for("message", check=is_correct, timeout=timeout)
        except asyncio.TimeoutError:
            db.add_exp(ctx.author.id, -1/2*exp_multiplier)

            soal_embed = Embed(title = 'Question Summary')
            soal_embed.add_field(name='Math sentence', value=f'```{math_sentence}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal_embed.add_field(name='Correct Answer', value=f"```{answer}```", inline=False)
            await soal.edit(embed=soal_embed)

            return await ctx.reply(embed=Embed(title="Time's Up!", description=f'Your exp was decreased by **`{1/2 * exp_multiplier}`**'))

        if str(guess.content) == str(answer) or float(guess.content) == float(answer):
            db.add_exp(ctx.author.id, exp_multiplier)

            await ctx.reply(embed=Embed(title='You got that!', description=f'Your exp was increased by **`{exp_multiplier}`**'))

        else:
            db.add_exp(ctx.author.id, -1/2*exp_multiplier)

            soal_embed = Embed(title = 'Question Summary')
            soal_embed.add_field(name='Math sentence', value=f'```{math_sentence}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal_embed.add_field(name='Correct Answer', value=f"```{answer}```", inline=False)
            await soal.edit(embed=soal_embed)

            await ctx.reply(embed=Embed(title='Oops!', description=f'Your exp was decreased by **`{1/2 * exp_multiplier}`**'))

    @command(name='quiz.intermediate-math')
    @cooldown(1, 240, BucketType.user)
    async def intermediate_math(self, ctx):
        """
        > Shows a intermediate math question. Your task is to answer correctly. Rewards `360 * (1 + 1 / time elapsed)` exp if win and minus half of the rewards if lost. You should answer within `level / 2 * (5 + (operator * 3) + (length each operand * 2))` seconds. Answer decimal with round 2 numbers behind dot.

        **Params:**
        >    no params required

        **Returns:**
        >    **`embed`** → math question

        **Example:**
        > ```<prefix>quiz.intermediate-math```
        """

        # det = {
        #     0 : 'kombinasi',
        #     1 : 'permutasi',
        #     2 : 'permutasi-siklis',
        #     3 : 'permutasi-berulang'
        # }

        determiner = np.random.choice([0, 1, 2, 3], 1, p = [0.22, 0.23, 0.25, 0.3])[0]

        if determiner == 0:
            peserta = random.randint(5, 15)
            dipilih = random.randint(2, 4)
            list_char = list(map(chr, range(97, 97 + peserta)))

            random_char = list(map(chr, range(97, 122)))[random.randint(0, 24)].upper()
            jenis = random.randint(5, 9)
            total_jenis = random.randint(jenis + 2, jenis + 5)
            wajib = random.randint(jenis - (jenis - 1), jenis - (jenis - 4))

            soal = [(f"Terdapat {peserta} peserta dalam sebuah {np.random.choice(['perkemahan', 'pertunjukan', 'kompetisi'], 1)[0]} (sebut saja {', '.join([x.upper() for x in list_char])}). Panitia meminta {dipilih} dari keseluruhan peserta untuk menjadi perwakilan menyambut juri. Berapakah banyak susunan penyambutan berbeda yang mungkin dari {dipilih} peserta tersebut?",
                     faktorial(peserta) / (faktorial(peserta - dipilih) * faktorial(dipilih))),

                    (f"{random_char} diminta untuk membeli {jenis} jenis sayuran dari pedagang yang menjual {total_jenis} jenis sayuran berbeda. Jika {wajib} jenis diantaranya harus dibeli, berapa banyak kombinasi {jenis} sayuran yang mungkin dibeli {random_char}?",
                     faktorial(total_jenis - wajib) / (faktorial(jenis - wajib) * faktorial(total_jenis - jenis))),

                    (f"{random_char} diminta untuk mengerjakan {jenis} soal dari {total_jenis} soal yang tersedia. Apabila soal nomor 1 - {wajib} wajib dikerjakan, berapakah banyak cara {random_char} mengerjakan soal?",
                     faktorial(total_jenis - wajib) / (faktorial(jenis - wajib) * faktorial(total_jenis - jenis))),

                    (f"{random_char} diminta untuk mengunjungi {jenis} zona pengungsian dari {total_jenis} zona yang ada. Bila {random_char} diwajibkan mengunjungi {wajib} zona, berapa banyak kombinasi {jenis} zona yang mungkin dikunjungi {random_char}?",
                     faktorial(total_jenis - wajib) / (faktorial(jenis - wajib) * faktorial(total_jenis - jenis)))]

            soal = random.choice(soal)

            timeout = 30 + (peserta + dipilih) * 10
            exp_multiplier = 360

            answer = soal[1]

            soal_embed = Embed(title = 'Solve this question!')
            soal_embed.add_field(name='Question', value=f'```{soal[0]}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal_embed.add_field(name='Reminder', value=f"```If the question contains division (/), always put dot, and round two numbers\nExample  : 12.345 → 12.35\n         : 12     → 12.00```", inline=False)
            soal_e = await ctx.reply(embed=soal_embed)

        if determiner == 1:
            peserta = random.randint(7, 15)
            juara = np.random.choice([3, 5, 7], 1)[0]
            list_char = list(map(chr, range(97, 97 + peserta)))

            random_char = list(map(chr, range(97, 122)))[random.randint(0, 24)].upper()
            jenis = random.randint(5, 9)
            total_jenis = random.randint(jenis + 2, jenis + 5)
            wajib = random.randint(jenis - (jenis - 1), jenis - (jenis - 4))

            soal = [(f"Akan dipilih {juara} juara terbaik dari {peserta} peserta dalam sebuah {np.random.choice(['kompetisi', 'perlombaan', 'olimpiade'], 1)[0]}. Berapakah banyak kemungkinan juara berbeda yang mungkin dari {peserta} peserta tersebut?", faktorial(peserta) / faktorial(peserta - juara)),
                    (f"Terdapat beberapa baris dalam buku tamu. Berapakah banyak kemungkinan yang tersedia hingga buku tamu tersebut terisi {jenis} baris?", faktorial(jenis)),
                    (f"Ketua sebuah event ingin menunjuk {jenis} dari {total_jenis} anggota yang masing-masingnya bertanggung jawab selama {jenis} hari event itu berjalan. Berapakah banyak kemungkinan penunjukan anggota tersebut", faktorial(total_jenis) / faktorial(total_jenis - jenis))]

            soal = random.choice(soal)

            timeout = 30 + (peserta + juara) * 10
            exp_multiplier = 480

            answer = soal[1]

            soal_embed = Embed(title = 'Solve this question!')
            soal_embed.add_field(name='Question', value=f'```{soal[0]}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal_embed.add_field(name='Reminder', value=f"```If the question contains division (/), always put dot, and round two numbers\nExample  : 12.345 → 12.35\n         : 12     → 12.00```", inline=False)
            soal_e = await ctx.reply(embed=soal_embed)

        if determiner == 2:
            peserta = random.randint(4, 10)
            list_char = list(map(chr, range(97, 97 + peserta)))

            random_char = list(map(chr, range(97, 122)))[random.randint(0, 24)].upper()
            jenis = random.randint(5, 9)
            total_jenis = random.randint(jenis + 2, jenis + 5)
            wajib = random.randint(jenis - (jenis - 1), jenis - (jenis - 4))

            soal = [(f"Terdapat {peserta} orang dalam ruangan rapat meja bundar. Mengharapkan adanya komunikasi yang baik, panitia menghendaki adanya pengacakan susunan tempat duduk. Berapa banyakkah kemungkinan posisi duduk yang dapat dibentuk?", faktorial(peserta - 1)),
                    (f"{random_char} memiliki {jenis} buah pernik yang akan disusun menjadi sebuah {np.random.choice(['kalung', 'gelang'], 1)[0]}. Banyak cara {random_char} untuk merangkainya adalah?", faktorial(jenis - 1))]

            soal = random.choice(soal)

            timeout = 30 + (peserta) * 15
            exp_multiplier = 360

            answer = soal[1]

            soal_embed = Embed(title = 'Solve this question!')
            soal_embed.add_field(name='Question', value=f'```{soal[0]}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal_embed.add_field(name='Reminder', value=f"```If the question contains division (/), always put dot, and round two numbers\nExample  : 12.345 → 12.35\n         : 12     → 12.00```", inline=False)
            soal_e = await ctx.reply(embed=soal_embed)

        if determiner == 3:
            kata = db.others_con['others']['ina_dict'].find({'_id' : random.randint(1, 35970)})[0]['katakunci'].upper()
            counter = {i : kata.count(i) for i in set(kata)}

            soal = f"Berapa banyak kata baru yang berbeda yang dapat disusun dari huruf-huruf penyusun kata \"{kata}\"?"

            timeout = 30 + (len(kata)) * 15
            exp_multiplier = 360

            pembagi = 1
            for i in counter.values():
                pembagi *= faktorial(i)
            answer = faktorial(len(kata)) / pembagi

            soal_embed = Embed(title = 'Solve this question!')
            soal_embed.add_field(name='Question', value=f'```{soal}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal_embed.add_field(name='Reminder', value=f"```If the question contains division (/), always put dot, and round two numbers\nExample  : 12.345 → 12.35\n         : 12     → 12.00```", inline=False)
            soal_e = await ctx.reply(embed=soal_embed)

        def is_correct(m):
            return m.author == ctx.author

        try:
            start_time = time.time()
            guess = await self.bot.wait_for("message", check=is_correct, timeout=timeout)
        except asyncio.TimeoutError:
            db.add_exp(ctx.author.id, int(-1/2*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))

            soal_embed = Embed(title = 'Question Summary')
            soal_embed.add_field(name='Correct Answer', value=f"```{answer}```", inline=False)
            await soal_e.edit(embed=soal_embed)

            return await ctx.reply(embed=Embed(title="Time's Up!", description=f'Your exp was decreased by **`{int(1/2*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier))}`**'))

        if str(guess.content) == str(answer) or float(guess.content) == float(answer):
            db.add_exp(ctx.author.id, int(exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))

            await soal_e.edit(embed=Embed(title='You got that!', description=f'Your exp was increased by **`{int(exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier))}`**'))
            await guess.delete()
        else:
            db.add_exp(ctx.author.id, int(-1/2*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))

            soal_embed = Embed(title = 'Question Summary')
            soal_embed.add_field(name='Correct Answer', value=f"```{answer}```", inline=False)
            await soal_e.edit(embed=soal_embed)

            await ctx.reply(embed=Embed(title='Oops!', description=f'Your exp was decreased by **`{int(1/2*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier))}`**'))

    @command(name='quiz.jumbled-word')
    @cooldown(1, 30, BucketType.user)
    async def jumbled_word(self, ctx, language = 'eng'):
        """
        > Takes a shuffled word from a dictionary. Your task is to rearrange the word correctly. Rewards `60 + (word length * 30)` exp if win and minus half of the rewards if lost. You should answer within `5 + (word length * 3)` seconds.

        **Params:**
        >    **`language`** → dictionary language, default to `{eng}` another option `{ina}`

        **Returns:**
        >    **`embed`** → jumbled word and clues

        **Example:**
        > ```<prefix>quiz.jumbled-word ina```
        """
        if language == 'eng':
            randomizer = random.randint(0, 54554)
            temp = db.others_con['others']['eng_dict'].find({'index' : randomizer})[0]
            answer = temp['word'].lower()
            clue = temp['meaning']
        elif language == 'ina':
            randomizer = random.randint(1, 35970)
            temp = db.others_con['others']['ina_dict'].find({'_id' : randomizer})[0]
            answer = temp['katakunci'].lower()
            clue = temp['artikata']
        taken_by = [temp['taken_by']]
        word = ''

        while ctx.author.id in taken_by or len(answer) < 3:
            if language == 'eng':
                randomizer = random.randint(0, 54554)
                temp = db.others_con['others']['eng_dict'].find({'index' : randomizer})[0]
                answer = temp['word'].lower()
                clue = temp['meaning']
            elif language == 'ina':
                randomizer = random.randint(1, 35970)
                temp = db.others_con['others']['ina_dict'].find({'_id' : randomizer})[0]
                answer = temp['katakunci'].lower()
                clue = temp['artikata']
            taken_by = [temp['taken_by']]
            word = ''

        if ' ' in answer:
            lst = []
            for i in answer.split(' '):
                lst.append("".join(random.sample(i, len(i))))
            word = " ".join(random.sample(lst, len(lst)))
            while word == answer:
                if ' ' in answer:
                    lst = []
                    for i in answer.split(' '):
                        lst.append("".join(random.sample(i, len(i))))
                    word = " ".join(random.sample(lst, len(lst)))
        else:
            word = "".join(random.sample(answer, len(answer)))
            while word == answer:
                word = "".join(random.sample(answer, len(answer)))

        timeout = 5 + len(word) * 3
        exp_multiplier = 60 + len(word) * 30

        soal_embed = Embed(title = 'Arrange the word!')
        soal_embed.add_field(name='Jumbled word', value=f'```{word}```', inline=False)
        soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
        soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
        soal_embed.add_field(name='Clue', value=f'```{clue}```', inline=False)
        soal = await ctx.reply(embed=soal_embed)

        def is_correct(m):
            return m.author == ctx.author

        try:
            guess = await self.bot.wait_for("message", check=is_correct, timeout=timeout)
        except asyncio.TimeoutError:
            db.add_exp(ctx.author.id, -1/2*exp_multiplier)
            return await soal.edit(embed=Embed(title="Time's Up!", description=f'Your exp was decreased by **`{1/2 * exp_multiplier}`**.\nThe correct answer is **{answer}**'))

        if answer in guess.content:
            db.add_exp(ctx.author.id, exp_multiplier)
            taken_by.append(ctx.author.id)

            db.others_con['others']['eng_dict'].update_one({'index' : randomizer}, {"$set": {'taken_by': taken_by}})
            await soal.edit(embed=Embed(title='You got that!', description=f'Your exp was increased by **`{exp_multiplier}`**'))
            await guess.delete()

        else:
            db.add_exp(ctx.author.id, -1/2*exp_multiplier)
            await soal.edit(embed=Embed(title='Oops!', description=f'Your exp was decreased by **`{1/2 * exp_multiplier}`**\nThe correct answer is **{answer}**'))

    @command(name='quiz.world-nations')
    @cooldown(1, 30, BucketType.user)
    async def world_nation(self, ctx):
        """
        > Takes a random questions about nations around the world. Your task is to answer correctly. Rewards `240 * (1 + 1 / time elapsed)` exp if win and minus half of the rewards if lost. You should answer within `60` seconds.

        **Params:**
        >    no params required

        **Returns:**
        >    **`embed`** → question and choices

        **Example:**
        > ```<prefix>quiz.world-cities```
        """
        timeout = 60
        exp_multiplier = 240

        kategori = ['0', '1', '2', '3', '4', '5']
        determiner = np.random.choice(kategori, 1)[0]

        # soal mencari negara dari nama kota
        if determiner == '0':
            sumber_soal = 'cities_dict'
            randomizer = random.randint(0, 23018)
            temp = db.others_con['others']['cities_dict'].find({'index' : randomizer})[0]
            answer = temp['country']
            city = temp['name']
            taken_by = temp['taken_by'][determiner]
            choice = [temp['country']]

            while ctx.author.id in taken_by:
                randomizer = random.randint(0, 23018)
                temp = db.others_con['others']['cities_dict'].find({'index' : randomizer})[0]
                answer = temp['country']
                city = temp['name']
                taken_by = temp['taken_by'][determiner]
                choice = [temp['country']]

            for i in range(4):
                countries = db.others_con['others']['cities_dict'].find({'index' : random.randint(0, 23018)})[0]['country']
                while countries == answer or countries in choice:
                    countries = db.others_con['others']['cities_dict'].find({'index' : random.randint(0, 23018)})[0]['country']

                choice.append(countries)

            urutan = random.sample('abcde', 5)
            choices = {}
            choice_value = ''
            for i, j in enumerate(urutan):
                choices[j] = choice[i]

            for i in sorted (choices) :
                choice_value += f'   {i}. {choices[i]}\n'

            soal_embed = Embed(title = 'Answer this question!')
            soal_embed.add_field(name='Question', value=f'```In which country is {city} located?```', inline=False)
            soal_embed.add_field(name='Choice', value=f'```{choice_value}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal = await ctx.reply(embed=soal_embed)

        # soal mencari negara dari nama provinsi
        elif determiner == '1':
            sumber_soal = 'cities_dict'
            randomizer = random.randint(0, 23018)
            temp = db.others_con['others']['cities_dict'].find({'index' : randomizer})[0]
            answer = temp['country']
            subcountry = temp['subcountry']
            taken_by = temp['taken_by'][determiner]
            choice = [temp['country']]

            while ctx.author.id in taken_by:
                randomizer = random.randint(0, 23018)
                temp = db.others_con['others']['cities_dict'].find({'index' : randomizer})[0]
                answer = temp['country']
                subcountry = temp['subcountry']
                taken_by = temp['taken_by'][determiner]
                choice = [temp['country']]

            for i in range(4):
                countries = db.others_con['others']['cities_dict'].find({'index' : random.randint(0, 23018)})[0]['country']
                while countries == answer or countries in choice:
                    countries = db.others_con['others']['cities_dict'].find({'index' : random.randint(0, 23018)})[0]['country']

                choice.append(countries)

            urutan = random.sample('abcde', 5)
            choices = {}
            choice_value = ''
            for i, j in enumerate(urutan):
                choices[j] = choice[i]

            for i in sorted (choices) :
                choice_value += f'   {i}. {choices[i]}\n'

            soal_embed = Embed(title = 'Answer this question!')
            soal_embed.add_field(name='Question', value=f'```In which country is subcountry {subcountry} located?```', inline=False)
            soal_embed.add_field(name='Choice', value=f'```{choice_value}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal = await ctx.reply(embed=soal_embed)

        # soal mencari kota dari nama negara
        elif determiner == '2':
            sumber_soal = 'cities_dict'
            randomizer = random.randint(0, 23018)
            temp = db.others_con['others']['cities_dict'].find({'index' : randomizer})[0]
            answer = temp['name']
            country = temp['country']
            taken_by = temp['taken_by'][determiner]
            same_country = [x['name'] for x in db.others_con['others']['cities_dict'].find({'country' : country})]
            choice = [temp['name']]

            while ctx.author.id in taken_by:
                randomizer = random.randint(0, 23018)
                temp = db.others_con['others']['cities_dict'].find({'index' : randomizer})[0]
                answer = temp['name']
                country = temp['country']
                taken_by = temp['taken_by'][determiner]
                same_country = [x['name'] for x in db.others_con['others']['cities_dict'].find({'country' : country})]
                choice = [temp['name']]

            for i in range(4):
                cities = db.others_con['others']['cities_dict'].find({'index' : random.randint(0, 23018)})[0]['name']
                while cities == answer or cities in choice or cities in same_country:
                    cities = db.others_con['others']['cities_dict'].find({'index' : random.randint(0, 23018)})[0]['name']

                choice.append(cities)

            urutan = random.sample('abcde', 5)
            choices = {}
            choice_value = ''
            for i, j in enumerate(urutan):
                choices[j] = choice[i]

            for i in sorted (choices) :
                choice_value += f'   {i}. {choices[i]}\n'

            soal_embed = Embed(title = 'Answer this question!')
            soal_embed.add_field(name='Question', value=f'```{country} has a city named...```', inline=False)
            soal_embed.add_field(name='Choice', value=f'```{choice_value}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal = await ctx.reply(embed=soal_embed)

        # soal mencari kota dari nama provinsi
        elif determiner == '3':
            sumber_soal = 'cities_dict'
            randomizer = random.randint(0, 23018)
            temp = db.others_con['others']['cities_dict'].find({'index' : randomizer})[0]
            answer = temp['name']
            subcountry = temp['subcountry']
            country = temp['country']
            taken_by = temp['taken_by'][determiner]
            same_subcountry = [x['name'] for x in db.others_con['others']['cities_dict'].find({'subcountry' : subcountry})]
            choice = [temp['name']]

            while ctx.author.id in taken_by:
                randomizer = random.randint(0, 23018)
                temp = db.others_con['others']['cities_dict'].find({'index' : randomizer})[0]
                answer = temp['name']
                country = temp['country']
                subcountry = temp['subcountry']
                taken_by = temp['taken_by'][determiner]
                same_subcountry = [x['name'] for x in db.others_con['others']['cities_dict'].find({'subcountry' : subcountry})]
                choice = [temp['name']]

            for i in range(4):
                cities = db.others_con['others']['cities_dict'].find({'index' : random.randint(0, 23018)})[0]['name']
                while cities == answer or cities in choice or cities in same_subcountry:
                    cities = db.others_con['others']['cities_dict'].find({'index' : random.randint(0, 23018)})[0]['name']

                choice.append(cities)

            urutan = random.sample('abcde', 5)
            choices = {}
            choice_value = ''
            for i, j in enumerate(urutan):
                choices[j] = choice[i]

            for i in sorted (choices) :
                choice_value += f'   {i}. {choices[i]}\n'

            soal_embed = Embed(title = 'Answer this question!')
            soal_embed.add_field(name='Question', value=f'```{subcountry} subcountry in {country}, has a city named...```', inline=False)
            soal_embed.add_field(name='Choice', value=f'```{choice_value}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal = await ctx.reply(embed=soal_embed)

        # soal mencari dial number dari mata uang
        elif determiner == '4':
            sumber_soal = 'countries_dict'
            randomizer = random.randint(0, 249)
            temp = db.others_con['others']['countries_dict'].find({'index' : randomizer})[0]
            answer = temp['Dial']
            currency = temp['ISO4217-currency_name']
            same_currency = [x['Dial'] for x in db.others_con['others']['countries_dict'].find({'ISO4217-currency_name' : currency})]
            taken_by = temp['taken_by'][determiner]
            choice = [temp['Dial']]

            while ctx.author.id in taken_by or currency == 'undefined':
            # while currency == None:
                randomizer = random.randint(0, 249)
                temp = db.others_con['others']['countries_dict'].find({'index' : randomizer})[0]
                answer = temp['Dial']
                currency = temp['ISO4217-currency_name']
                same_currency = [x['Dial'] for x in db.others_con['others']['countries_dict'].find({'ISO4217-currency_name' : currency})]
                taken_by = temp['taken_by'][determiner]
                choice = [temp['Dial']]

            for i in range(4):
                dials = db.others_con['others']['countries_dict'].find({'index' : random.randint(0, 249)})[0]['Dial']
                while dials == answer or dials in choice or dials in same_currency or dials == 'undefined':
                    dials = db.others_con['others']['countries_dict'].find({'index' : random.randint(0, 249)})[0]['Dial']

                choice.append(dials)

            urutan = random.sample('abcde', 5)
            choices = {}
            choice_value = ''
            for i, j in enumerate(urutan):
                choices[j] = choice[i]

            for i in sorted (choices) :
                choice_value += f'   {i}. {choices[i]}\n'

            soal_embed = Embed(title = 'Answer this question!')
            soal_embed.add_field(name='Question', value=f'```Country which using {currency} as currency, has dial code ...```', inline=False)
            soal_embed.add_field(name='Choice', value=f'```{choice_value}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal = await ctx.reply(embed=soal_embed)

        # soal mencari mata uang dari fifa
        elif determiner == '5':
            sumber_soal = 'countries_dict'
            randomizer = random.randint(0, 249)
            temp = db.others_con['others']['countries_dict'].find({'index' : randomizer})[0]
            answer = temp['ISO4217-currency_name']
            fifa = temp['FIFA']
            taken_by = temp['taken_by'][determiner]
            choice = [temp['ISO4217-currency_name']]

            while ctx.author.id in taken_by or answer == 'undefined' or fifa == 'undefined':
            # while currency == None:
                randomizer = random.randint(0, 249)
                temp = db.others_con['others']['countries_dict'].find({'index' : randomizer})[0]
                answer = temp['ISO4217-currency_name']
                fifa = temp['FIFA']
                taken_by = temp['taken_by'][determiner]
                choice = [temp['ISO4217-currency_name']]

            for i in range(4):
                currencies = db.others_con['others']['countries_dict'].find({'index' : random.randint(0, 249)})[0]['ISO4217-currency_name']
                while currencies == answer or currencies in choice or currencies == 'undefined':
                    currencies = db.others_con['others']['countries_dict'].find({'index' : random.randint(0, 249)})[0]['ISO4217-currency_name']

                choice.append(currencies)

            urutan = random.sample('abcde', 5)
            choices = {}
            choice_value = ''
            for i, j in enumerate(urutan):
                choices[j] = choice[i]

            for i in sorted (choices) :
                choice_value += f'   {i}. {choices[i]}\n'

            soal_embed = Embed(title = 'Answer this question!')
            soal_embed.add_field(name='Question', value=f'```Country which using {fifa} as FIFA code, using ... as currency```', inline=False)
            soal_embed.add_field(name='Choice', value=f'```{choice_value}```', inline=False)
            soal_embed.add_field(name='Answer Timeout', value=f'```{timeout} seconds```', inline=True)
            soal_embed.add_field(name='Potential Reward', value=f'```{exp_multiplier} exp```', inline=True)
            soal = await ctx.reply(embed=soal_embed)

        def is_correct(m):
            return m.author == ctx.author

        try:
            start_time = time.time()
            guess = await self.bot.wait_for("message", check=is_correct, timeout=timeout)
        except asyncio.TimeoutError:
            db.add_exp(ctx.author.id, int(-1/2*(exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier))))
            return await soal.edit(embed=Embed(title="Time's Up!", description=f'Your exp was decreased by **`{1/2 * (exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier))}`**.\nThe correct answer is **{answer}**'))

        try:
            if choices[guess.content.lower()] == answer:
                db.add_exp(ctx.author.id, int(exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))
                taken_by.append(ctx.author.id)

                db.others_con['others'][sumber_soal].update_one({'index' : randomizer}, {"$set": {f'taken_by.{determiner}': taken_by}})
                await soal.edit(embed=Embed(title='You got that!', description=f'Your exp was increased by **`{int((exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))}`**'))
                await guess.delete()

            else:
                db.add_exp(ctx.author.id, int(-1/2*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))
                await soal.edit(embed=Embed(title='Oops!', description=f'Your exp was decreased by **`{int(1/2 * (exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))}`**\nThe correct answer is **{answer}**'))
        except Exception as e:
            print(e)
            db.add_exp(ctx.author.id, int(-1/2*exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))
            await soal.edit(embed=Embed(title='Oops!', description=f'Your exp was decreased by **`{int(1/2 * (exp_multiplier + (1 / int(time.time() - start_time) * exp_multiplier)))}`**\nThe correct answer is **{answer}**'))

    @user_command(name="Deadly RPS", guild_ids=db.guild_list, description='Rock-Paper-Scissors with your friend with 100% lowest exp as bid')
    @cooldown(1, 300, BucketType.user)
    async def deadly_rps(self, ctx, member):

        if ctx.author.id == member.id:
            ctx.command.reset_cooldown(ctx)
            raise Exception('same player')

        player = {ctx.author.id : None, member.id : None}
        a_exp = db.servers_con['servers']['social_credit'].find({'discord_id' : ctx.author.id})[0]['u_exp']
        b_exp = db.servers_con['servers']['social_credit'].find({'discord_id' : member.id})[0]['u_exp']
        taruhan = 0

        if a_exp <= 0 or b_exp <= 0:
            ctx.command.reset_cooldown(ctx)
            raise Exception('one of the player has 0 or minus exp')

        if a_exp > b_exp:
            taruhan = b_exp
        else:
            taruhan = a_exp

        print(taruhan, a_exp, b_exp)

        class MyView(discord.ui.View):
            @discord.ui.select(
                placeholder="Pick your side. You CAN'T change this later",
                min_values=1,
                max_values=1,
                options=[
                    discord.SelectOption(emoji = '🗿', label="Rock", value = 'Rock'),
                    discord.SelectOption(emoji = '📄', label="Paper", value = 'Paper'),
                    discord.SelectOption(emoji = '✂', label="Scissors", value = 'Scissors'),
                ],
            )
            async def callback(self, select, interaction: discord.Interaction):
                user = interaction.user
                # Get the rb ole this button is for (stored in the custom ID).

                if user.id not in player.keys():
                    await interaction.response.send_message(f"not eligible", ephemeral=True)
                    return

                # Add the role and send a response to the uesr ephemerally (hidden to other users).
                if user.id in player.keys() and player[user.id] == None:
                    # Give the user the role if they don't already have it.
                    player[user.id] = select.values[0]
                    await interaction.response.send_message(f"You selected {select.values[0]}", ephemeral=True)

                else:
                    await interaction.response.send_message(f"not allowed to change.", ephemeral=True)

                print(player)
                winner = None
                if player[ctx.author.id] != None and player[member.id] != None:
                    if player[ctx.author.id] == 'Rock' and player[member.id] == 'Paper':
                        winner = member
                        loser = ctx.author

                    elif player[ctx.author.id] == 'Rock' and player[member.id] == 'Scissors':
                        winner = ctx.author
                        loser = member

                    elif player[ctx.author.id] == 'Paper' and player[member.id] == 'Rock':
                        winner = ctx.author
                        loser = member

                    elif player[ctx.author.id] == 'Paper' and player[member.id] == 'Scissors':
                        winner = member
                        loser = ctx.author

                    elif player[ctx.author.id] == 'Scissors' and player[member.id] == 'Rock':
                        winner = member
                        loser = ctx.author

                    elif player[ctx.author.id] == 'Scissors' and player[member.id] == 'Paper':
                        winner = ctx.author
                        loser = member

                    else:
                        winner = None

                    if winner != None:
                        db.add_exp(winner.id, taruhan)
                        db.add_exp(loser.id, -taruhan)
                        await interaction.channel.send(f"[{ctx.author.mention} with **{player[ctx.author.id]}** against {member.mention} with **{player[member.id]}**]\nThe RPS winner is {winner.mention}! Got a total of `{db.number_format(taruhan)}` exp")
                    else:
                        await interaction.channel.send(f"[{ctx.author.mention} with **{player[ctx.author.id]}** against {member.mention} with **{player[member.id]}**]\nThe RPS ended in a draw.")

        try:
            view = MyView()
            msg = await ctx.interaction.response.send_message(f"Deadly RPS between {ctx.author.mention} v.s. {member.mention} \n**`{db.number_format(taruhan)}` exp will be given to the winner**. The bid consist of:\n> {ctx.author.mention} with `{round(taruhan / a_exp * 100, 2)}%` of exp\n> {member.mention} with `{round(taruhan / b_exp * 100)}%` of exp", view=view)
        except asyncio.TimeoutError:
            msg = await ctx.interaction.response.edit_message('Timeout!')
            await msg.delete()

def setup(bot):
    bot.add_cog(Games(bot))


text:
# Deep Traffic
import os
# Import required packages
import pygame
import sys
from pygame.locals import *
import numpy as np

# Import model and GUI related modules
from car import Car, DEFAULT_CAR_POS
from gui_util import draw_basic_road, \
    draw_road_overlay_safety, \
    draw_road_overlay_vision, \
    control_car, \
    identify_free_lane, \
    Score, \
    draw_inputs, \
    draw_actions, \
    draw_gauge, \
    draw_score
from deep_traffic_agent import DeepTrafficAgent

# Advanced view
from advanced_view.road import AdvancedRoad

import config

# Model name
model_name = config.MODEL_NAME

deep_traffic_agent = DeepTrafficAgent(model_name)

# Define game constant
OPTIMAL_CARS_IN_SCENE = 15
ACTION_MAP = ['A', 'M', 'D', 'L', 'R']
monitor_keys = [pygame.K_UP, pygame.K_RIGHT, pygame.K_LEFT, pygame.K_DOWN]

if config.VISUALENABLED:
    pygame.init()
    pygame.font.init()
    pygame.display.set_caption('DeepTraffic')
    fpsClock = pygame.time.Clock()

    main_surface = pygame.display.set_mode((1600, 800), pygame.DOUBLEBUF | pygame.HWSURFACE)
    advanced_road = AdvancedRoad(main_surface, 0, 550, 1010, 800, lane=6)
else:
    os.environ["SDL_VIDEODRIVER"] = "dummy"
    main_surface = None

lane_map = [[0 for x in range(7)] for y in range(100)]

episode_count = deep_traffic_agent.model.get_count_episodes()

speed_counter_avg = []
hard_brake_avg = []
alternate_line_switching = []

action_stats = np.zeros(5, np.int32)

PREDEFINED_MAX_CAR = config.MAX_SIMULATION_CAR

# New episode/game round
while episode_count < config.MAX_EPISODE + config.TESTING_EPISODE * 3:
    is_training = config.DL_IS_TRAINING and episode_count < config.MAX_EPISODE and not config.VISUALENABLED

    # Score object
    score = Score(score=0)

    subject_car = Car(main_surface,
                      lane_map,
                      speed=60,
                      y=DEFAULT_CAR_POS,
                      lane=4,
                      is_subject=True,
                      score=score,
                      agent=deep_traffic_agent)
    object_cars = [Car(main_surface,
                       lane_map,
                       speed=60,
                       y=800,
                       lane=6,
                       is_subject=False,
                       score=score,
                       subject=subject_car)
                   for i in range(6, 7)]

    frame = 0

    game_ended = False

    delay_count = 0
    speed_counter = []
    subject_car_action = 'M'

    while True: # frame < config.MAX_FRAME_COUNT:
        # brick draw
        # bat and ball draw
        # events
        if config.VISUALENABLED and not config.DLAGENTENABLED:
            pressed_key = pygame.key.get_pressed()
            keydown_key = []

            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    keydown_key.append(event.key)

        if config.VISUALENABLED:
            ressed_key = pygame.key.get_pressed()
            keydown_key = []

            for event in pygame.event.get():
                if event.type == QUIT or event.type == pygame.K_q:
                    pygame.quit()
                    sys.exit()

        # Setup game background
        draw_basic_road(main_surface, subject_car.speed)

        # Car to identify available moves in the order from top to bottom
        cars = [subject_car]
        cars.extend([o_car for o_car in object_cars if o_car.removed is False])
        cars.sort(key=lambda t_car: t_car.y, reverse=True)

        available_lanes_for_new_car = identify_free_lane(cars)

        # Add more cars to the scene
        if len(cars) < PREDEFINED_MAX_CAR and np.random.standard_normal(1)[0] >= 0:
            # Decide position(Front or back)
            map_position = np.random.choice([0, 1], 1)[0]
            position = available_lanes_for_new_car[map_position]
            if len(position) > 0:
                # Back
                if map_position:
                    new_car_speed = np.random.random_integers(30, 90)
                    new_car_y = 1010
                    new_car_lane = int(np.random.choice(position, 1))
                else:
                    new_car_speed = np.random.random_integers(30, 60)
                    new_car_y = -100
                    new_car_lane = int(np.random.choice(position, 1))
                # Decide lanes
                new_car = Car(main_surface,
                              lane_map,
                              speed=new_car_speed,
                              y=new_car_y,
                              lane=new_car_lane,
                              is_subject=False,
                              subject=subject_car,
                              score=score)
                object_cars.append(new_car)
                if position:
                    cars.append(new_car)
                else:
                    cars.insert(0, new_car)

        # main game logic
        # Reinitialize lane map
        for y in range(100):
            for x in range(7):
                lane_map[y][x] = 0

        # Identify car position
        for car in cars:
            car.identify()

        for car in cars:
            car.identify_available_moves()

        cache = False
        if delay_count < config.DELAY and not game_ended and is_training:
            delay_count += 1
            cache = True
        else:
            delay_count = 0

        q_values = None
        # Car react to road according to order
        for car in cars[::-1]:
            # For object car
            if car.subject is not None:
                car.decide(game_ended, cache=cache, is_training=is_training)
                continue

            if config.DLAGENTENABLED:
                # Get prediction from DeepTrafficAgent
                q_values, temp_action = car.decide(game_ended, cache=cache, is_training=is_training)
                if not cache:
                    subject_car_action = temp_action
                    q_values = np.sum(q_values)
                    if not is_training:
                        action_stats[deep_traffic_agent.get_action_index(temp_action)] += 1
            elif config.VISUALENABLED:
                # Manual control
                is_controlled = False
                for key in monitor_keys:
                    if pressed_key[key] or key in keydown_key:
                        is_controlled = True
                        control_car(subject_car, key)
                if not is_controlled:
                    car.move('M')

        # Show road overlay (Safety)
        # draw_road_overlay_safety(main_surface, lane_map)
        draw_road_overlay_vision(main_surface, subject_car)

        for car in cars:
            car.draw()

        # Decide end of game
        if game_ended:
            deep_traffic_agent.remember(score.score,
                                        subject_car.get_vision(),
                                        end_episode=True,
                                        is_training=is_training)
            break
        elif frame >= config.MAX_FRAME_COUNT: # abs(score.score) >= config.GOAL:
            game_ended = True

        # Show statistics
        if config.VISUALENABLED:
            draw_score(main_surface, score.score)

            draw_inputs(main_surface, subject_car.get_vision())
            draw_actions(main_surface, subject_car_action)
            draw_gauge(main_surface, subject_car.speed)

            # Setup advanced view
            advanced_road.draw(frame, subject_car)

            # collision detection
            fpsClock.tick(20000)
            pygame.event.poll()
            pygame.display.flip()

        frame += 1
        speed_counter.append(subject_car.speed)

        if q_values is not None:
            deep_traffic_agent.model.log_q_values(q_values)

    episode_count = deep_traffic_agent.model.increase_count_episodes()
    avg_speed = np.average(speed_counter)
    if not is_training:
        speed_counter_avg.append(avg_speed)
        deep_traffic_agent.model.log_testing_speed(avg_speed)
    else:
        print("Average speed for episode{}: {}".format(episode_count, avg_speed))
        deep_traffic_agent.model.log_average_speed(avg_speed)
    deep_traffic_agent.model.log_total_frame(frame)
    deep_traffic_agent.model.log_terminated(frame < config.MAX_FRAME_COUNT - 1)
    deep_traffic_agent.model.log_reward(score.score)

    deep_traffic_agent.model.log_hard_brake_count(subject_car.hard_brake_count)

    if episode_count > config.MAX_EPISODE:
        alternate_line_switching.append(subject_car.alternate_line_switching)
        hard_brake_avg.append(subject_car.hard_brake_count)
        if (episode_count - config.MAX_EPISODE) % config.TESTING_EPISODE == 0:
            avg_speed = np.average(speed_counter_avg)
            median_speed = np.median(speed_counter_avg)
            avg_hard_brake = np.average(hard_brake_avg)
            median_hard_brake = np.median(hard_brake_avg)
            avg_alternate_line_switching = np.average(alternate_line_switching)
            median_alternate_line_switching = np.median(alternate_line_switching)
            print("Car:{},Speed:(Mean: {}, Median: {}),Hard_Brake:(Mean: {}, Median: {}), Line::(Mean: {}, Median: {})"
                  .format(PREDEFINED_MAX_CAR, avg_speed, median_speed, avg_hard_brake, median_hard_brake,
                          avg_alternate_line_switching, median_alternate_line_switching))
            if abs(PREDEFINED_MAX_CAR - 40) < 1:
                deep_traffic_agent.model.log_average_test_speed_40(avg_speed)
                PREDEFINED_MAX_CAR = 20
            elif abs(PREDEFINED_MAX_CAR - 20) < 1:
                deep_traffic_agent.model.log_average_test_speed_20(avg_speed)
                PREDEFINED_MAX_CAR = 60
            else:
                deep_traffic_agent.model.log_average_test_speed_60(avg_speed)
            speed_counter_avg = []
            hard_brake_avg = []
            alternate_line_switching = []

deep_traffic_agent.model.log_action_frequency(action_stats)

ext: py

reason: import numpy


text:
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axes_grid1.inset_locator
import mpl_toolkits.basemap
from matplotlib import patheffects

from mslib.mswms.mpl_hsec import MPLBasemapHorizontalSectionStyle
from mslib.mswms.mpl_vsec import AbstractVerticalSectionStyle
from mslib.mswms.utils import get_style_parameters, get_cbar_label_format
from mslib import thermolib

MSSChemSpecies = {
    'AERMR01': 'fine_sea_salt_aerosol',
    'AERMR02': 'medium_sea_salt_aerosol',
    'AERMR03': 'coarse_sea_salt_aerosol',
    'AERMR04': 'fine_dust_aerosol',
    'AERMR05': 'medium_dust_aerosol',
    'AERMR06': 'coarse_dust_aerosol',
    'AERMR07': 'hydrophobic_organic_matter_aerosol',
    'AERMR08': 'hydrophilic_organic_matter_aerosol',
    'AERMR09': 'hydrophobic_black_carbon_aerosol',
    'AERMR10': 'hydrophilic_black_carbon_aerosol',
    'AERMR11': 'sulfate_aerosol',
    'C2H6': 'ethane',
    'C3H8': 'propane',
    'C5H8': 'isoprene',
    'CH4': 'methane',
    'CO': 'carbon_monoxide',
    'HCHO': 'formaldehyde',
    'HNO3': 'nitric_acid',
    'NH3': 'ammonia',
    'NMVOC': 'nmvoc_expressed_as_carbon',
    'NO': 'nitrogen_monoxide',
    'NO2': 'nitrogen_dioxide',
    'O3': 'ozone',
    'OH': 'hydroxyl_radical',
    'PAN': 'peroxyacetyl_nitrate',
    'PM2P5': 'pm2p5_ambient_aerosol',
    'PM10': 'pm10_ambient_aerosol',
    'SO2': 'sulfur_dioxide',
}

MSSChemQuantities = {
    'mfrac': ('mass_fraction', 'kg kg-1', 1),
    'mconc': ('mass_concentration', 'ug m-3', 1),
    'nfrac': ('mole_fraction', 'mol mol-1', 1),
    'nconc': ('mole_concentration', 'mol m-3', 1),
}

MSSChemTargets = {
    qtylong + '_of_' + species + '_in_air': (key, qty, units, scale)
    for key, species in MSSChemSpecies.items()
    for qty, (qtylong, units, scale) in MSSChemQuantities.items()}

class HS_MSSChemStyle(MPLBasemapHorizontalSectionStyle):
    """
    Pressure level version for Chemical Mixing ratios.
    """
    styles = [
        ("auto", "auto colour scale"),
        ("autolog", "auto logcolour scale"), ]

    # In order to use information from the DataAccess class to construct the titles, we override the set_driver to set
    # self.title.  This cannot happen in __init__, as the WMSServer doesn't initialize the layers with the driver but
    # rather sets the driver only after initialization.
    def set_driver(self, driver):
        super(HS_MSSChemStyle, self).set_driver(driver=driver)
        self.title = self._title_tpl.format(modelname=self.driver.data_access._modelname)

    def _plot_style(self):
        bm = self.bm
        ax = self.bm.ax

        lonmesh_, latmesh_ = np.meshgrid(self.lons, self.lats)
        lonmesh, latmesh = bm(lonmesh_, latmesh_)

        show_data = np.ma.masked_invalid(self.data[self.dataname]) * self.unit_scale
        # get cmin, cmax, cbar_log and cbar_format for level_key
        cmin, cmax, clevs, cmap, norm, ticks = get_style_parameters(
            self.dataname, self.style, None, None, show_data)

        tc = bm.contourf(lonmesh, latmesh, show_data, levels=clevs, cmap=cmap, extend="both", norm=norm)

        for cont_data, cont_levels, cont_colour, cont_label_colour, cont_style, cont_lw, pe in self.contours:
            cs_pv = ax.contour(lonmesh, latmesh, self.data[cont_data], cont_levels,
                               colors=cont_colour, linestyles=cont_style, linewidths=cont_lw)
            cs_pv_lab = ax.clabel(cs_pv, colors=cont_label_colour, fmt='%i')
            if pe:
                plt.setp(cs_pv.collections, path_effects=[patheffects.withStroke(linewidth=cont_lw + 2,
                                                                                foreground="w")])
                plt.setp(cs_pv_lab, path_effects=[patheffects.withStroke(linewidth=1, foreground="w")])

        # define position of the colorbar and the orientation of the ticks
        if self.crs.lower() == "epsg:77774020":
            cbar_location = 3
            tick_pos = 'right'
        else:
            cbar_location = 4
            tick_pos = 'left'

        # Format for colorbar labels
        cbar_label = self.title
        cbar_format = get_cbar_label_format(self.style, np.abs(clevs).max())

        if not self.noframe:
            cbar = self.fig.colorbar(tc, fraction=0.05, pad=0.08, shrink=0.7,
                                     norm=norm, label=cbar_label, format=cbar_format, ticks=ticks)
            cbar.set_ticks(clevs)
            cbar.set_ticklabels(clevs)
        else:
            axins1 = mpl_toolkits.axes_grid1.inset_locator.inset_axes(
                ax, width="3%", height="40%", loc=cbar_location)
            self.fig.colorbar(tc, cax=axins1, orientation="vertical", format=cbar_format, ticks=ticks)

            # adjust colorbar fontsize to figure height
            fontsize = self.fig.bbox.height * 0.024
            axins1.yaxis.set_ticks_position(tick_pos)
            for x in axins1.yaxis.majorTicks:
                x.label1.set_path_effects([patheffects.withStroke(linewidth=4, foreground='w')])
                x.label1.set_fontsize(fontsize)

def make_msschem_hs_class(
        entity, nam, vert, units, scale, add_data=None, add_contours=None, fix_styles=None,
        add_styles=None, add_prepare=None):
    if add_data is None:
        add_data = []
    _contourname = ""
    if add_contours is None:
        add_contours = []
    elif add_contours[0][0] == "air_pressure":
        _contourname = "_pcontours"

    class fnord(HS_MSSChemStyle):
        name = "HS_{}_{}{}".format(entity, vert, _contourname)
        dataname = entity
        units = units
        unit_scale = scale
        _title_tpl = nam + " (" + vert + ")"
        long_name = entity
        if units:
            _title_tpl += " ({})".format(units)

        required_datafields = [(vert, entity, None)] + add_data
        contours = add_contours

    fnord.__name__ = nam
    fnord.styles = list(fnord.styles)

    return fnord

for vert in ["ml", "al", "pl"]:
    for stdname, props in MSSChemTargets.items():
        name, qty, units, scale = props
        key = "HS_MSSChemStyle_" + vert.upper() + "_" + name + "_" + qty
        globals()[key] = make_msschem_hs_class(stdname, name, vert, units, scale)

_pressurelevels = np.linspace(5000, 95000, 19)
_npressurelevels = len(_pressurelevels)
for vert in ["ml"]:
    for stdname, props in MSSChemTargets.items():
        name, qty, units, scale = props
        # ToDo string substitution
        key = "HS_MSSChemStyle_" + vert.upper() + "_" + name + "_" + qty + "_pcontours"
        globals()[key] = make_msschem_hs_class(
            stdname, name, vert, units, scale, add_data=[(vert, "air_pressure", None)],
            add_contours=[("air_pressure", _pressurelevels,
                           ["dimgrey"] * _npressurelevels,
                           ["dimgrey"] * _npressurelevels,
                           ["dotted"] * _npressurelevels, 1, True)],)

class VS_MSSChemStyle(AbstractVerticalSectionStyle):
    """ CTM tracer vertical tracer cross sections via MSS-Chem
    """
    styles = [
        ("auto", "auto colour scale"),
        ("autolog", "auto log colour scale"), ]

    # Variables with the highest number of dimensions first (otherwise
    # MFDatasetCommonDims will throw an exception)!
    required_datafields = [("ml", "air_pressure", "Pa")]

    # In order to use information from the DataAccess class to construct the titles, we override the set_driver to set
    # self.title.  This cannot happen in __init__, as the WMSServer doesn't initialize the layers with the driver but
    # rather sets the driver only after initialization.
    def set_driver(self, driver):
        super(VS_MSSChemStyle, self).set_driver(driver=driver)
        # for altitude level model data, when we don't have air_pressure information, we want to warn users that the
        # vertical section is only an approximation
        vert = self.name[-2:]
        if vert != "pl":
            # look for valid times including air_pressure
            init_times = self.driver.data_access.get_init_times()
            valid_times = self.driver.data_access.get_valid_times(
                "air_pressure", vert, init_times[0])
            if len(valid_times) == 0:
                self.title = self.title.replace(
                    "(" + vert + ")", "(" + vert + "; WARNING: vert. distribution only approximate!)")

    def _prepare_datafields(self):
        """Computes potential temperature from pressure and temperature if
        it has not been passed as a data field.
        """
        if self.name[-2:] == "pl":
            self.data["air_pressure"] = np.empty_like(self.data[self.dataname])
            self.data["air_pressure"][:] = self.driver.vert_data[::-self.driver.vert_order, np.newaxis]
        elif self.name[-2:] == "tl":
            self.data["air_potential_temperature"] = np.empty_like(self.data[self.dataname])
            self.data["air_potential_temperature"][:] = self.driver.vert_data[::-self.driver.vert_order, np.newaxis]
        elif self.name[-2:] == "al":
            # CAMS Regional Ensemble doesn't provide any pressure information, but we want to plot vertical sections
            # anyways, so we do a poor-man's on-the-fly conversion here.
            if 'air_pressure' not in self.data:
                self.data["air_pressure"] = np.empty_like(self.data[self.dataname])
                flightlevel = 3.28083989501 / 100. * self.driver.vert_data[::-self.driver.vert_order, np.newaxis]
                self.data['air_pressure'][:] = thermolib.flightlevel2pressure_a(flightlevel)

    def _plot_style(self):
        ax = self.ax
        curtain_cc = self.data[self.dataname] * self.unit_scale
        curtain_cc = np.ma.masked_invalid(curtain_cc)
        curtain_p = self.data["air_pressure"]  # TODO* 100

        numlevel = curtain_p.shape[0]
        numpoints = len(self.lats)
        curtain_lat = self.lat_inds.repeat(numlevel).reshape((numpoints, numlevel)).transpose()

        # Filled contour plot of cloud cover.
        # INFO on COLORMAPS:
        #    http://matplotlib.sourceforge.net/examples/pylab_examples/show_colormaps.html
        if self.p_bot > self.p_top:
            visible = (curtain_p <= self.p_bot) & (curtain_p >= self.p_top)
        else:
            visible = (curtain_p >= self.p_bot) & (curtain_p <= self.p_top)

        if visible.sum() == 0:
            visible = np.ones_like(curtain_cc, dtype=bool)

        cmin, cmax, clevs, cmap, norm, ticks = get_style_parameters(
            self.dataname, self.style, None, None, curtain_cc[visible])

        cs = ax.contourf(curtain_lat, curtain_p, curtain_cc, clevs, cmap=cmap, extend="both", norm=norm)

        # Contour lines
        for cont_data, cont_levels, cont_colour, cont_label_colour, cont_style, cont_lw, pe in self.contours:
            if cont_levels is None:
                pl_cont = ax.plot(self.lat_inds, self.data[cont_data].reshape(-1), "o", color="k", zorder=100)
                plt.setp(pl_cont, path_effects=[patheffects.withStroke(linewidth=4, foreground="w")])
            else:
                cs_pv = ax.contour(curtain_lat, curtain_p, self.data[cont_data], cont_levels,
                                   colors=cont_colour, linestyles=cont_style, linewidths=cont_lw)
                plt.setp(cs_pv.collections,
                         path_effects=[patheffects.withStroke(linewidth=cont_lw + 2, foreground="w")])
                cs_pv_lab = ax.clabel(cs_pv, colors=cont_label_colour, fontsize=8, fmt='%i')
                plt.setp(cs_pv_lab, path_effects=[patheffects.withStroke(linewidth=1, foreground="w")])

        # Pressure decreases with index, i.e. orography is stored at the
        # zero-p-index (data field is flipped in mss_plot_driver.py if
        # pressure increases with index).
        self._latlon_logp_setup(titlestring=self.title)

        # Format for colorbar labels
        cbar_format = get_cbar_label_format(self.style, np.median(np.abs(clevs)))
        cbar_label = self.title

        # Add colorbar.
        if not self.noframe:
            self.fig.subplots_adjust(left=0.08, right=0.95, top=0.9, bottom=0.14)
            self.fig.colorbar(cs, fraction=0.05, pad=0.01, format=cbar_format, label=cbar_label, ticks=ticks)
        else:
            axins1 = mpl_toolkits.axes_grid1.inset_locator.inset_axes(
                ax, width="1%", height="40%", loc=1)
            self.fig.colorbar(cs, cax=axins1, orientation="vertical", format=cbar_format, ticks=ticks)

            # adjust colorbar fontsize to figure height
            fontsize = self.fig.bbox.height * 0.024
            axins1.yaxis.set_ticks_position("left")
            for x in axins1.yaxis.majorTicks:
                x.label1.set_path_effects([patheffects.withStroke(linewidth=4, foreground='w')])
                x.label1.set_fontsize(fontsize)

def make_msschem_vs_class(
        entity, nam, vert, units, scale, add_data=None,
        add_contours=None, fix_styles=None, add_styles=None, add_prepare=None):

    # This is CTM output, so we cannot expect any additional meteorological
    # parameters except for air_pressure
    if add_data is None:
        if vert == "al":
            # "al" is altitude layer, i.e., for CTM output with no pressure information
            # at all (e.g., CAMS reg. Ensemble)
            # In those cases we derive air_pressure from the altitude alone, in the _prepare_datafields() method
            add_data = []
        elif vert == 'pl':
            # "pl" are pressure levels.  Here, the air_pressure information is implicitly contained in the vertical
            # dimension coordinate, so we don't need to explicitly load it here.
            add_data = []

        else:
            # all other layer types need to read air_pressure from the data
            add_data = [(vert, "air_pressure", "Pa")]
    if add_contours is None:
        add_contours = []

    class fnord(VS_MSSChemStyle):
        name = "VS_{}_{}".format(entity, vert)
        dataname = entity
        units = units
        unit_scale = scale
        title = nam + " (" + vert + ")"
        long_name = entity
        if units:
            title += " ({})".format(units)
        required_datafields = [(vert, entity, None)] + add_data
        contours = add_contours if add_contours else []

    fnord.__name__ = nam
    fnord.styles = list(fnord.styles)

    if add_styles is not None:
        fnord.styles += add_styles
    if fix_styles is not None:
        fnord.styles = fix_styles
    if add_prepare is not None:
        fnord._prepare_datafields = add_prepare

    return fnord

for vert in ["ml", "tl", "pl", "al"]:
    for stdname, props in MSSChemTargets.items():
        name, qty, units, scale = props
        key = "VS_MSSChemStyle_" + vert.upper() + "_" + name + "_" + qty
        globals()[key] = make_msschem_vs_class(stdname, name, vert, units, scale)

max_stars_repo_name: iamansoni/MSS

max_issues_repo_name: iamansoni/MSS

max_forks_repo_name: iamansoni/MSS


text:
"""
Python re-implementation of "Visual Object Tracking using Adaptive Correlation Filters"
@inproceedings{Bolme2010Visual,
  title={Visual object tracking using adaptive correlation filters},
  author={Bolme, David S. and Beveridge, J. Ross and Draper, Bruce A. and Lui, Yui Man},
  booktitle={Computer Vision & Pattern Recognition},
  year={2010},
}
"""
import numpy as np
import cv2,os
from utils import _get_img_lists,_linear_mapping,_window_func_2d,_get_gauss_response

class mosse():
    def __init__(self,learning_rate=0.125,sigma=2.,img_path = 'datasets/surfer/'
                ,bbox_init_gt=[228,118,140,174],chose_ROI=False,num_pretrain=8):
        """
        num_pretrain: Times to generate eight small perturbations (fi) of random affine transformations
        """
        self.learning_rate=learning_rate
        self.sigma=sigma
        self.frame_list = _get_img_lists(img_path)
        self.frame_list.sort()
        self.first_frame = cv2.imread(self.frame_list[0])
        self.bbox_init_gt=bbox_init_gt
        self.chose_ROI=chose_ROI
        self.num_pretrain=num_pretrain

    def init(self):
        if self.chose_ROI:
            bbox = cv2.selectROI('demo', self.first_frame, False, False)
        else:
            bbox = self.bbox_init_gt
        if len(self.first_frame.shape)!=2:
            assert self.first_frame.shape[2]==3
            self.first_frame=cv2.cvtColor(self.first_frame,cv2.COLOR_BGR2GRAY)
        self.first_frame=self.first_frame.astype(np.float32)/255
        x,y,w,h=tuple(bbox)
        self._center=(x+w/2,y+h/2)
        self.w,self.h=w,h
        w,h=int(round(w)),int(round(h))

        self._fi=cv2.getRectSubPix(self.first_frame,(w,h),self._center)
        self._G=np.fft.fft2(_get_gauss_response((w,h),self.sigma))

        self._Ai=np.zeros_like(self._G)
        self._Bi=np.zeros_like(self._G)
        for _ in range(self.num_pretrain):
            # AFFINE TRANSFORMATION
            fi=self._rand_warp(self._fi)
            Fi=np.fft.fft2(self._preprocessing(fi))
            self._Ai+=self._G*np.conj(Fi)
            self._Bi+=Fi*np.conj(Fi)

    def update(self):
        for idx in range(len(self.frame_list)):
            current_frame = cv2.imread(self.frame_list[idx])
            current_frame_BGR=current_frame
            if len(current_frame.shape)!=2:
                assert current_frame.shape[2]==3
                current_frame=cv2.cvtColor(current_frame,cv2.COLOR_BGR2GRAY)
            current_frame=current_frame.astype(np.float32)/255
            Hi=self._Ai/self._Bi
            fi=cv2.getRectSubPix(current_frame,(int(round(self.w)),int(round(self.h))),self._center)
            fi=self._preprocessing(fi)
            Gi=Hi*np.fft.fft2(fi)
            hi = _linear_mapping(np.real(np.fft.ifft2(Hi)))
            gi = _linear_mapping(np.real(np.fft.ifft2(Gi)))
            curr=np.unravel_index(np.argmax(gi, axis=None),gi.shape)
            dy,dx=curr[0]-(self.h/2),curr[1]-(self.w/2)
            x_c,y_c=self._center
            x_c+=dx
            y_c+=dy
            self._center=(x_c,y_c)
            fi=cv2.getRectSubPix(current_frame,(int(round(self.w)),int(round(self.h))),self._center)
            fi=self._preprocessing(fi)
            Fi=np.fft.fft2(fi)
            self._Ai=self.learning_rate*(self._G*np.conj(Fi))+(1-self.learning_rate)*self._Ai
            self._Bi=self.learning_rate*(Fi*np.conj(Fi))+(1-self.learning_rate)*self._Bi

            # visualize the tracking process...
            cv2.rectangle(current_frame_BGR, (int(self._center[0]-self.w/2),int(self._center[1]-self.h/2)), (int(self._center[0]+self.w/2),int(self._center[1]+self.h/2)), (255, 0, 0), 2)
            cv2.imshow('demo', current_frame_BGR)
            cv2.waitKey(1)
            cv2.imshow('fi',fi)
            cv2.waitKey(1)
            cv2.imshow('gi',gi)
            cv2.waitKey(1)
            cv2.imshow('hi',hi)
            cv2.waitKey(1)

    def _preprocessing(self,img,eps=1e-5):
        # First, the pixel values are transformed using a log function which helps with low contrast lighting situations.
        img=np.log(img+1)
        # The pixel values are normalized to have a mean value of 0.0 and a norm of 1.0
        img=(img-np.mean(img))/(np.std(img)+eps)
        # Finally, the image is multiplied by a cosine window which gradually
        # reduces the pixel values near the edge to zero. This also
        # has the benefit that it puts more emphasis near the center of the target.
        cos_window = _window_func_2d(int(round(self.w)),int(round(self.h)))
        preprocessed_img = cos_window*img
        return preprocessed_img

    def _rand_warp(self,img):
        """
        The training set is constructed using
        random affine transformations to generate eight small perturbations (fi)
        of the tracking window in the initial frame.
        """
        h, w = img.shape[:2]
        C = .1
        ang = np.random.uniform(-C, C)
        c, s = np.cos(ang), np.sin(ang)
        W = np.array([[c + np.random.uniform(-C, C), -s + np.random.uniform(-C, C), 0],
                      [s + np.random.uniform(-C, C), c + np.random.uniform(-C, C), 0]])
        center_warp = np.array([[w / 2], [h / 2]])
        tmp = np.sum(W[:, :2], axis=1).reshape((2, 1))
        W[:, 2:] = center_warp - center_warp * tmp
        warped = cv2.warpAffine(img, W, (w, h), cv2.BORDER_REFLECT)
        return warped

if __name__ == "__main__":

    init_gt=[228,118,140,174]
    img_path = 'datasets/surfer/'

    tracker = mosse(img_path=img_path,bbox_init_gt=init_gt,chose_ROI=False)
    tracker.init()
    tracker.update()


text:
import urllib
import urllib2
import os
import re
from google import search
from urlparse import urlsplit
from bs4 import BeautifulSoup
from urlparse import urljoin
import numpy
from scipy.sparse import csc_matrix
import robotexclusionrulesparser
import robotparser
import urlparse
import requests
import mimetypes
import socket
import datetime
import signal

class Crawl(object):
	def __init__(self):
		self.starttime = datetime.datetime.utcnow()
		self.timeout = 4

		self.statistic = {"404":0, "403":0, "totalSize":0.0}		# statistic data for the output.
		self.urlInfo = {}		# store attributes of each url, used for output. PGID[ 0. crawled time, 1. size , 2.estimate rank, 3.final rank]
		self.urlWL = []			# to store urls, waiting list

		self.vistedList = {}	# check repeat & store all visted links
		self.crawledList = {}	# store url which is alreay crawled
		self.urlID = 0

		self.rankDic = {}		# to store urls(id) and their ranks
		self.blackListType = {'jpg', 'pdf', 'jsp', 'cms', 'asp', 'webm', 'gz', 'sig', 'ogv', 'png', 'zip', 'txt'}

		self.siteCounter = {}	# to limit the pages from per site
		self.siteLimit = float('Inf')		# set the max pages from the same site
		self.recalculate = 30				# when to recalculate the pagerank and update the waiting list

		self.PG = {}			# save page's url, and index
		self.PGreverse = {}		# save page's index, and url for reverse lookup
		self.PGID = 0			# assign a page ID for each page in the pagerank matrix

		self.mapping = {}		# to store the mapping relation between links (use PGID)

	def downloadPage(self, url):
		path='/Users/gpz/Desktop/downloadPage/'
		file_name = str(self.vistedList[url]) + '.html'
		dest_dir=os.path.join(path,file_name)
		urllib.urlretrieve(url , dest_dir)

	def getStartPage(self, query, number):
		result = []
		for item in search(query, tld="co.in", num=number, stop=1, pause=1):
			result.append(item)
		for url in result:							# for the first 10 url
			if url not in self.vistedList:
				self.vistedList[url] = self.urlID		# add to visted list
				self.urlID += 1

				size = self.formatFilter(url)
				if size:								# if HTML
					self.urlWL = [url] + self.urlWL		# enqueue to waiting list
					self.PG[url] = self.PGID			# add to page dictionary for ranking
					self.PGreverse[self.PGID] = url
					self.urlInfo[self.PGID] = [datetime.datetime.utcnow().isoformat(), size]			# add PGID to urlInfo, with crawled time and size
					self.statistic['totalSize'] += float(size)
					self.PGID += 1
		return

	def addMapping(self, Url, toUrl):					# add map relationship to mapping dictionary
		UrlID = self.PG[Url]
		toUrlID = self.PG[toUrl]
		if UrlID not in self.mapping:
			self.mapping[UrlID] = [toUrlID]
		else:
			if toUrlID not in self.mapping[UrlID]:
				self.mapping[UrlID].append(toUrlID)
		return

	def findUrl(self, PageLimit):			# get url from the content of a list of urls
		while self.PGID < PageLimit:
			try:
				url = self.urlWL.pop()
			except IndexError:			# if waiting list is empty
										# update the pagerank and waiting list, put more high rank urls into self.urlWL
				matrix = self.matrixGenerator()
				Rank = self.pageRank(matrix)
				self.updateRankinfo(Rank)

				if len(self.urlWL) == 0:	# if the waiting list is still empty after updating
					print "The url waiting list is empty, please modify function 'updateRank' or some parameters and try again ! "
					break
				else:
					print "recalculate"
					continue

			self.crawledList[url] = 1

			try:							# catch exception, if error, discard this url
				urlf = urllib2.urlopen(url, timeout = self.timeout)
				soup = BeautifulSoup(urlf.read(), "html.parser")
			except urllib2.HTTPError, err:
				if err.code == 404:
					self.statistic["404"] += 1
					print "404 page not found"
				elif err.code == 403:
					self.statistic["403"] += 1
					print "403 Access denied"
				else:
					print "some error occured:", err.code

				continue

			except urllib2.URLError, err:
				print "some other error occured:", err.reason
				continue

			except:
				print "some other error occured:"
				continue

			link_list = soup.findAll("a", href=True)
			for link in link_list:
				fullUrl = urljoin(url, link["href"]).rstrip('/')		# Complete relative URLs in the current page
				if fullUrl.split('.')[-1] not in self.blackListType:	# a serial of url filters

					if fullUrl in self.PG and fullUrl != url:					# add mapping relation if found one
						self.addMapping(url, fullUrl)

						# check if already visted, check cgi page, check download page, check login page
					if (fullUrl not in self.vistedList) and ("cgi" not in fullUrl) and ("account" not in fullUrl) and ("login" not in fullUrl) and ("download" not in fullUrl):
						self.vistedList[fullUrl] = self.urlID
						self.urlID += 1
						siteBaseUrl = self.getBaseUrl(fullUrl)
						if (siteBaseUrl not in self.siteCounter) or (self.siteCounter[siteBaseUrl] > self.siteLimit):

							print fullUrl							# this line is used for testing

							size = self.formatFilter(fullUrl)
							if size != 0:							# if it's text/html
								try:
									is_allowed = self.getRobotExclu(siteBaseUrl)
								except:								# don't have a robots.txt may means there is no access limitation.
									print "robots.txt is not reachable in this website."
									continue						# don't have a robots.txt may also be considered as a not valid webiste (maybe some tmp website)

								if is_allowed == 1:				# if allowed to access
									if siteBaseUrl not in self.siteCounter:	# count current site in siteCounter
										self.siteCounter[siteBaseUrl] = 1
									else:
										self.siteCounter[siteBaseUrl] += 1

									self.PG[fullUrl] = self.PGID			# add to PG and PGreverse
									self.PGreverse[self.PGID] = fullUrl
									self.urlInfo[self.PGID] = [datetime.datetime.utcnow().isoformat(), size]		# add PGID to urlInfo, with crawled time and size
									self.statistic['totalSize'] += float(size)
									self.PGID += 1

									if self.PGID%10 == 0:					# display the progress
										print float(self.PGID)/PageLimit

									#print fullUrl
									#self.downloadPage(url)				# if text/html, download the current page

									self.addMapping(url, fullUrl)			# add mapping relation

									if self.PGID % self.recalculate == 0:	# each time increase a certain number, recalculate the rank
										matrix = self.matrixGenerator()
										Rank = self.pageRank(matrix)
										self.updateRankinfo(Rank)
										print "recalculate"
										#print self.urlInfo				# this line is used for testing
										#print self.urlWL				# this line is used for testing
										#print self.mapping 			# this line is used for testing
										break

		matrix = self.matrixGenerator()
		Rank = self.pageRank(matrix)
		self.getFinalRank()
		self.output()
		return

	def getBaseUrl(self, url):			# get base url, e.g. "http://www.xxxx.xxx"
		parsed = urlsplit(url)
		host = parsed.netloc
		return 'http://' + host

	def formatFilter(self, url):		# check if the url type is text/html
		try:
			signal.signal(signal.SIGALRM, self.handler)
			signal.alarm(5)

			response = requests.get(url, timeout = self.timeout)
			content_type = response.headers['content-type']

			signal.alarm(0)

			if content_type.split(";")[0] == 'text/html':
				return response.headers["Content-Length"]			# if text/html, return page size
			else:
				return 0

		except AssertionError:
			print "get format timeout."
			return 0

		except:
			return 0

	def getRobotExclu(self, url):
		try:
			signal.signal(signal.SIGALRM, self.handler)
			signal.alarm(5)
			BaseUrl = self.getBaseUrl(url)
			AGENT_NAME = '*'
			parser = robotparser.RobotFileParser()
			parser.set_url(urlparse.urljoin(BaseUrl, 'robots.txt'))
			parser.read()
			url = url.encode('utf-8')
			signal.alarm(0)
			return parser.can_fetch(AGENT_NAME, url)
		except AssertionError:
			print "get robots.txt time out"
			return 0

	def matrixGenerator(self):						# export the mapping dictionary to a n*n relation matrix
		matrix = [[0 for col in xrange(self.PGID)] for row in xrange(self.PGID)]
		for i in self.mapping:
			length = len(self.mapping[i])
			for j in self.mapping[i]:
				matrix[i][j] = (1.0/length)
		return matrix

	def updateRankinfo(self, rank):						# update rank dictionary and update url waiting list
		Rank_Sort = []									# a tmp variable for ranking
		for i in xrange(self.PGID):
			self.rankDic[i] = rank[i]
			if len(self.urlInfo[i]) != 3:				# assign the estimate rank if there isn't one
				self.urlInfo[i].append(rank[i])

			if self.PGreverse[i] not in self.crawledList:
				Rank_Sort.append([rank[i], i])

		Rank_Sort.sort()
		self.urlWL = []								# reset the waiting list for Ranked url
		for pair in Rank_Sort:						# add all sorted links to waiting list in asc order
		#for pair in Rank_Sort[-20:]:				# add top 20 to the waiting list
			#self.urlWL = [self.PGreverse[pair[-1]]] + self.urlWL		# add url to the waiting list
			self.urlWL.append(self.PGreverse[pair[-1]])

		return

	def pageRank(self, Matrix):		# read a n*n matrix
		MinSum = 0.001			# the min sum of pageranks between iterations, below this value will be converged
		Prob = 0.85			# probability of following a transition. 1-s probability of teleporting to another state.

		L = len(Matrix)
		A = csc_matrix(Matrix, dtype = numpy.float)			# transform G into markov matrix A
		rowSums = numpy.array(A.sum(1))[:,0]
		ri, ci = A.nonzero()
		A.data /= rowSums[ri]

		sink = rowSums==0							# check sink states

		r0 = numpy.zeros(L)							# compute pagerank R until converge
		r1 = numpy.ones(L)

		while numpy.sum(numpy.abs(r1-r0)) > MinSum:
			r0 = r1.copy()
			for i in xrange(L):						# calculate each pagerank at a time

				Ai = numpy.array(A[:,i].todense())[:,0]	# number of inlinks
				Bi = sink/float(L)					# sink state
				Ci = numpy.ones(L)/float(L)

				r1[i] = r0.dot(Ai*Prob + Bi*Prob + Ci*(1-Prob))

		return r1/float(sum(r1))

	def getFinalRank(self):							# save the final rank into urlInfo dictionary, prepare for the output
		for i in xrange(self.PGID):
			self.urlInfo[i].append(self.rankDic[i])
		return

	def output(self):
		print  "start writing........"
		file = open("output.csv", "w")
		file.write("ID, URL, Time, Size, Estimate page rank, Final page rank\n")
		for ID in self.urlInfo:
			writeContent = str(ID) + "," + self.PGreverse[ID] + "," + self.urlInfo[ID][0] + "," + self.urlInfo[ID][1] + "," + str(self.urlInfo[ID][2]) + "," + str(self.urlInfo[ID][3]) + "\n"
			try:
				file.write(writeContent)
			except:
				continue

		file.write("404 numbers:," + str(self.statistic["404"]))
		file.write("\n403 numbers:," + str(self.statistic["403"]))
		file.write("\ntotalsize:," + str(self.statistic["totalSize"]))
		spendTime = datetime.datetime.utcnow()-self.starttime
		file.write("\ntotalTime:," + str(spendTime))

		file.close()

	def handler(self, signum, frame):
		raise AssertionError

# run the code

A = Crawl()
A.getStartPage('ebbets field',10)
A.findUrl(1200)

max_stars_repo_path: 1-crawler/PR crawler/PRcrawler.py

max_issues_repo_path: 1-crawler/PR crawler/PRcrawler.py

max_forks_repo_path: 1-crawler/PR crawler/PRcrawler.py

reason: import numpy,from scipy


text:
import numpy as np
from keras.layers import *
from keras.models import *
from keras.optimizers import *
from pathlib import Path
from keras import backend as K
from keras.utils import to_categorical
import tensorflow as tf
from custom_layers import *
from keras.callbacks import *
from sklearn.utils import shuffle
from multiprocessing.pool import ThreadPool
from math import ceil
import sys
import h5py
from datetime import datetime
from sklearn.metrics import accuracy_score, confusion_matrix, log_loss
from plot_cm import plot_cm
from my_models import get_mobile_net as get_model
import inspect
import os
import os.path

np.random.seed(7)
root_path = r'data/custom_derived.h5'   #Path to the derived features

dtime = datetime.now().strftime('-%B-%d(%a)-%H-%H-%S')
fname = Path(sys.argv[0]).stem

train_split = .65
test_split = .75
modelname = 'MobileNetv1'
num_feat = 64
seg_len = 200
feat = 'mfb'
dtype = np.float16

modelf = os.path.join('Models', f'{modelname}{str(seg_len)}{dtime}.h5')

# ecatg = dict((c,i) for (i,c) in enumerate(['noise', 'music', 'speech']))
# ecatg = ['custom', 'noise', 'speech']

# if (not 'X_train' in locals()) or input('Reload Data? [Y/N] :').lower()=='y':
with h5py.File(root_path, mode='r') as db:
    fdict = {}

    file_handler_hdf5 = None
    for key in db['../datasets/custom/'].keys():
        fdict[key] = db[f'../datasets/custom/{key}']
        file_handler_hdf5 = db[f'../datasets/custom/{key}'] #!!!! debug

    # fdict = dict((c, []) for c in ecatg.keys())
    # for k in db.keys():
    #     c = k.split('\\')[0]
    #     if c in ecatg:
    #         fdict[c].append(k)

    # for key in ecatg.keys():
    #     for subkey in db[key].keys():
    #         for file in db[key][subkey].keys():
    #             fdict[key].append(db[key][subkey][file].name)

    # print(fdict.keys())

    # train, val, test = {}, {}, {}
    # for k in fdict:
    #     np.random.shuffle(fdict[k])
    #     # print(fdict[k][:5])
    #     ut = int(len(fdict[k])*train_split)
    #     uv = int(len(fdict[k])*test_split)
    #     train[k], val[k], test[k] = fdict[k][:ut], fdict[k][ut:uv],\
    #                             fdict[k][uv:]

    def frm_proc(frms):
        #frms = (frms-frms.mean(axis=(1,2), keepdims=True))/(np.amax(np.abs(frms), axis=(1,2), keepdims=True)+1e-2)#/frms.std(axis=(1,2), keepdims=True)
        return frms.astype(dtype)#

    def frm_gen(filtered):
        if len(filtered)<seg_len:
            filtered = np.pad(filtered, pad_width=((seg_len-len(filtered), 0), (0,0)),
                                mode='wrap')
        seg_points1 = np.arange(seg_len, len(filtered), seg_len)
        seg_points2 = np.arange(seg_len//2, len(filtered), seg_len)

        frms = np.stack(np.split(filtered, seg_points1)[:-1]+
                                np.split(filtered, seg_points2)[1:-1]+
                                [filtered[-seg_len:]])
        return frm_proc(frms)

    class data_gen:
        def __init__(self, dic):
            self.dic = dic
            self.labels = []

        def yield_dat(self):
            # print(self.dic['mfb'])
            dat = frm_gen(self.dic['mfb'])
            yield dat
            # for k, files in self.dic.items():
            #     print(k,files)
            #     ln = len(files)
            #     dat = frm_gen(db[fl][feat])
            #     exit()
            #     print('Concatenating {} {} files...'.format(ln, k.upper()))
            #     for i, fl in enumerate(files):
            #         # print(i,fl)
            #         # print(db[fl][feat][:])
            #         # exit()
            #         if not i % 50:
            #             print('Read', str(i), 'out of', str(ln), 'files...')

            #         dat = frm_gen(db[fl][feat])
            #         # lbl = len(dat)*[float(ecatg[k])]

            #         # self.labels.append(lbl)
            #         # self.labels.append(len(dat)*[fl])
            #         yield dat

    data_gen_instance = data_gen(file_handler_hdf5)
    print('\nConcatenating input data...')
    # dg = data_gen(train)
    data_gen_instance = data_gen(file_handler_hdf5)
    # if 'X_train' in locals():
    #     del X_train
    X_in = np.vstack(data_gen_instance.yield_dat())
    print(X_in.shape)
    # Y_in = np.hstack(dg.labels)

    # print('\nConcatenating train data...')
    # dg = data_gen(train)
    # if 'X_train' in locals():
    #     del X_train
    # X_train = np.vstack(dg.yield_dat())
    # Y_train = np.hstack(dg.labels)

    # print('\nConcatenating validation data...')
    # dg = data_gen(val)
    # if 'X_val' in locals():
    #     del X_val
    # X_val = np.vstack(dg.yield_dat())
    # Y_val = np.hstack(dg.labels)

    # print('\nConcatenating test data...')
    # dg = data_gen(test)
    # if 'X_test' in locals():
    #     del X_test
    # X_test = np.vstack(dg.yield_dat())
    # Y_test = np.hstack(dg.labels)

K.clear_session()

# https://github.com/tensorflow/tensorflow/issues/43174#issuecomment-691657692
from tensorflow.compat.v1 import ConfigProto
from tensorflow.compat.v1 import InteractiveSession

config = ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)
sess = tf.compat.v1.Session()

# in_shape = X_train.shape[1:]

model_weights_path = os.path.join('Models', 'model_weights')
if os.path.isfile(model_weights_path) or os.path.isdir(model_weights_path):
    print('Loading pretrained model...')
    model = tf.keras.models.load_model(model_weights_path)

else:
    print('Loading pretrained model FAILED')
    exit()

print(model.summary())

# Yp_val = model.predict(X_val, verbose=1, batch_size=256)

'''
bs=256 t=1.9706239700317383s
bs=512 t=0.26128530502319336s
bs=1024 t=0.30574631690979004s
bs=2048 t=0.3024265766143799s
bs=4096 t=0.1718432903289795s
bs=8192 t=0.17038655281066895s
bs=16384 t=0.17225027084350586s

import time
for bs in [4096]:#, 256, 512, 1024, 2048, 4096, 8192, 16384]:
    t0=time.time()
    Yp_val = model.predict(X_in, verbose=1, batch_size=bs)#256)
    t1=time.time()
    print(f'bs={bs} t={t1-t0}s')
print(Yp_val)
'''

Yp_val = model.predict(X_in, verbose=1, batch_size=256)

with open('data/custom_out.csv', 'w') as f:
    f.write(f'noise;music;speech\n')
    for noise, music, speech in Yp_val:
        f.write(f'{noise};{music};{speech}\n')

# Yp_test = model.predict(X?_test, verbose=1, batch_size=256)

# ll_val = log_loss(Y_val, Yp_val)
# ll_test = log_loss(Y_test, Yp_test)

# acc_val = accuracy_score(Y_val, Yp_val.argmax(-1))
# acc_test = accuracy_score(Y_test, Yp_test.argmax(-1))

# cm_val = confusion_matrix(Y_val, Yp_val.argmax(-1))
# cm_test = confusion_matrix(Y_test, Yp_test.argmax(-1))

# plot_cm(cm_val, list(ecatg.keys()), True, 'Confusion Matrix - Validation')
# plot_cm(cm_test, list(ecatg.keys()), True, 'Confusion Matrix - Test')

# sns = np.vectorize(lambda x: 1 if x==ecatg['speech'] else 0)
# acc_sns_val = accuracy_score(sns(Y_val), sns(Yp_val.argmax(-1)))
# acc_sns_test = accuracy_score(sns(Y_test), sns(Yp_test.argmax(-1)))

# print('Test Accuracy = {:0.4}%'.format(acc_test*100))