亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

提醒功能:如何使其接受多個時間參數值?

提醒功能:如何使其接受多個時間參數值?

繁星淼淼 2023-09-12 16:55:27
所以,我嘗試使用discord.py 創建一個提醒功能。這是我的代碼:@client.command(name = "reminder", brief = "I'll send a message to the future.",                description = "State what I have to remind you, as well as when and in which channel and I'll do it! "                             "Write d for days, h for hours, m for minutes and s for seconds after the number and then "                              "what you want to be remided of. For example: >reminder 1h 30m eat chocolate",                aliases = ["remind", "remindme", "remindto"])async def reminder(ctx, time, *, reminder):    user = ctx.message.author    seconds = 0    if reminder is None:        ctx.send("Please, tell me what you want me to remind you about!")    if time.lower().endswith("d"):        seconds += float(time[:-1]) * 60 * 60 * 24        counter = f"{seconds // 60 // 60 // 24} days"    if time.lower().endswith("h"):        seconds += float(time[:-1]) * 60 * 60        counter = f"{seconds // 60 // 60} hours"    if time.lower().endswith("m"):        seconds += float(time[:-1]) * 60        counter = f"{seconds // 60} minutes"    if time.lower().endswith("s"):        seconds += float(time[:-1])        counter = f"{seconds} seconds"    if seconds == 0:        await ctx.send("You can't tell me that!")    else:        await ctx.send(f"Alright, I will remind you about {reminder} in {counter}.")        await asyncio.sleep(seconds)        await ctx.send(f"Hi, <@{user.id}>, you asked me to remind you about {reminder} {counter} ago.")        return我的問題是,當有人為“時間”寫出多個論點時,我不知道如何使其發揮作用。例如,如果我調用該函數>reminder 1h 30min eat chocolate,它會在 1 小時內提醒我“30 分鐘吃巧克力”,而不是在 1 小時 30 分鐘內提醒我。我不知道是否有辦法解決這個問題(除了寫1.5h)。任何輸入都會有用。多謝!
查看完整描述

2 回答

?
白板的微信

TA貢獻1883條經驗 獲得超3個贊

您的用戶輸入的消息在“某處”被分割成參數,然后調用您發布的異步方法。您顯示的代碼中未完成用戶輸入的“拆分” 。


如果您想'1d 3hours 52sec Check StackOverflow for answers.'作為用戶輸入進行處理,則需要在使用拆分參數調用之前更改此消息的方式。split async def reminder(ctx, time, *, reminder)


您需要更改它,以便time提供為'1d 3hours 52sec'和reminder提供為'Check StackOverflow for answers.':


# correctly proivided params

reminder(ctx, "1d 3hours 52sec", *, reminder="Check StackOverflow for answers")

如果您無法更改此拆分行為,請禁止用戶使用的消息的時間部分內存在空格:


看來您的用戶文本當前是按空格分割的,第一個文本是提供的time,其余的文本是reminder消息。


如果您禁止時間組件內的空格,您可以更改方法以正確解析諸如 之類的輸入的時間'1d3hours52sec Check StackOverflow for answers.'。


這可能是處理上述消息的方法的非異步實現:


一些輔助方法和導入:


imort time 


def format_seconds(secs):

    # mildly adapted from source: https://stackoverflow.com/a/13756038/7505395 

    # by Adam Jacob Muller

    """Accepts an integer of seconds and returns a minimal string formatted into

    'a years, b months, c days, d hours, e minutes, f seconds' as needed."""

    periods = [

        ('year',        60*60*24*365),

        ('month',       60*60*24*30),

        ('day',         60*60*24),

        ('hour',        60*60),

        ('minute',      60),

        ('second',      1)

    ]


    strings=[]

    for period_name, period_seconds in periods:

        if secs > period_seconds:

            period_value , secs = divmod(secs, period_seconds)

            has_s = 's' if period_value > 1 else ''

            strings.append("%s %s%s" % (period_value, period_name, has_s))


    return ", ".join(strings)


def convert_timestring_to_seconds(time):

    """Convert a math expression to integer,only allows [0..9+* ] as chars."""

    if not all(c in "1234567890+* " for c in time):

        raise Exception()

    # this are seconds - using eval as we can be sure nothing harmful can be in it

    # if you are paranoid, use https://stackoverflow.com/a/33030616/7505395 instead

    count = eval(time)

    if type(count) != int:

        raise Exception()

    return count

方法上下文對象的模擬:


class MockContext:

    def __init__(self):

        class User:

            def __init__(self):

                self.id = "mee-id"

            def __str__(self):

                return "mee"

        class Message:

            def __init__(self):

                self.author = User() 

        self.message = Message()

        self.send = print 

以及您更改后的方法(非異步和模擬以實現最小的可重現示例目的):


def reminder(ctx, time, *, reminder):

    user = ctx.message.author


    if not time:

        ctx.send("Please, tell me WHEN you want me to remind you!")

        return

    elif not reminder:

        ctx.send("Please, tell me WHAT you want me to remind you about!")

        return


    # order and 3.7+ is important - (else use the sorting one down below)

    replacer = {"days":24*60*60, "hours":60*60, "minutes":60, "min":60, 

                "seconds":1, "sec":1, "d":24*60*60, "h":60, "m":60, "s":1}

    safe_time = time # for error output we remember the original input for time


    for unit in replacer: # or sorted(replacer, key=len, reverse=True) below 3.8 

        time = time.replace(unit, f"*{replacer[unit]}+")

    time = time.rstrip("+")


    try:

        count = convert_timestring_to_seconds(time)

    except Exception as ex:

        ctx.send(f"Unable to understand the time of '{safe_time}'!", ex)

        return


    if count == 0:

        ctx.send("You can't tell me that!") 

    else:

        counter = format_seconds(count)

        ctx.send(f"Alright, I will remind you about '{reminder}' in '{counter}'.")

        import time

        time.sleep(2)

        ctx.send(f"Hi, <@{user.id}>, you asked me to remind you about '{reminder}' some '{counter}' ago.")

這可以像這樣調用:


context_mock = MockContext() 


reminder(context_mock, "1d5min270seconds", reminder = "abouth this") 

reminder(context_mock, "1d5min270seconds", reminder = "")

reminder(context_mock, "", reminder = "")


reminder(context_mock, "buffalo", reminder = "abouth this") 

并產生以下輸出:


# reminder(context_mock, "1d5min270seconds", reminder = "abouth this") 

Alright, I will remind you about 'abouth this' in '1 day, 9 minutes, 30 seconds'.

<2s delay>

Hi, <@mee-id>, you asked me to remind you about 'abouth this' some '1 day, 9 minutes, 30 seconds' ago.


# reminder(context_mock, "1d5min270seconds", reminder = "")

Please, tell me WHAT you want me to remind you about!


# reminder(context_mock, "", reminder = "")

Please, tell me WHEN you want me to remind you!


# reminder(context_mock, "buffalo", reminder = "abouth this")

Unable to understand the time of 'buffalo'! 


查看完整回答
反對 回復 2023-09-12
?
慕村225694

TA貢獻1880條經驗 獲得超4個贊

這就是我最終解決問題的方法:


async def reminder(ctx):

    user = ctx.message.author

    def check(msg):

        return msg.author == ctx.author and msg.channel == ctx.channel

               #and type(msg.content) == int

    await ctx.send("Oh my! Yes, tell me, what do you need to remember?")

    reminder = await client.wait_for("message", check=check)


    await ctx.send("Okay! When do you want me to remind you that? (d for days, h for hours, m for minutes, s for seconds)")

    Time = await client.wait_for("message", check=check)

    times = str(Time.content)

    Times = times.split()


    seconds = 0


    for time in Times:

        if time.lower().endswith("d"):

            seconds += float(time[:-1]) * 60 * 60 * 24

            counter = f"{seconds // 60 // 60 // 24} days"

        if time.lower().endswith("h"):

            seconds += float(time[:-1]) * 60 * 60

            counter = f"{seconds // 60 // 60} hours"

        if time.lower().endswith("m"):

            seconds += float(time[:-1]) * 60

            counter = f"{seconds // 60} minutes"

        if time.lower().endswith("s"):

            seconds += float(time[:-1])

            counter = f"{seconds} seconds"

        if seconds == 0:

            await ctx.send("You can't tell me that!")


    else:

        await ctx.send(f"Alright, I will remind you about {reminder.content} in {times}.")

        await asyncio.sleep(seconds)

        await ctx.send(f"Hi, <@{user.id}>, you asked me to remind you about {reminder.content} some time ago. "

                   f"Don't forget about it!")

因此,機器人不會弄亂函數的參數,而是分別向用戶詢問提醒和時間。


查看完整回答
反對 回復 2023-09-12
  • 2 回答
  • 0 關注
  • 139 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號