Гузариш ба мундариҷа
Мавзӯи 6 аз 6

Боти ёдраскунанда

Аз фармонҳо то ёдрасии воқеӣ

То ин ҷо бот матнро қабул карда, рӯйхатро нишон медод. Акнун вақт, соҳиби маълумот ва фиристодани дертар-ро мепайвандем. Корбар бояд фавран фаҳмад, ки дархост қабул шуд ва баъд дар вақти лозим паём гирад.

1. Вақти шабонарӯз ва давомнокӣ

Вақти шабонарӯз мавқеъ дар соат аст, масалан 07:05. Давомнокӣ — чӣ қадар интизор шудан лозим аст. Барои ҳисоб вақтро ҳамчун дақиқаҳо аз оғози рӯз ифода кардан қулай аст: соатҳоро ба 60 зарб карда, дақиқаҳоро илова мекунем. Вале бе сана соат муайян намекунад, ки кадом рӯз дар назар аст.

Гузаштан аз нимашабро дар санаи собит бо китобхонаи стандартӣ мебинем. timedelta давомнокиро тасвир мекунад; ҷамъ кардан бо datetime санаро дуруст иваз мекунад.

from datetime import datetime, timedelta

current = datetime(2030, 1, 1, 23, 40)
target = current + timedelta(minutes=35)
print(target.strftime("%Y-%m-%d %H:%M"))
print(7 * 60 + 5)
print(f"{7:02}:{5:02}")

Натиҷа:

2030-01-02 00:15
425
07:05

23:40 бо иловаи 35 дақиқа ба 00:15-и рӯзи дигар расид. Адади 425 мавқеи 07:05 дар дақиқаҳо аз нимашаб аст. Формати :02 аз чап сифр илова мекунад, то навишта ҳамеша дарозии яксон дошта бошад.

Вақте бот танҳо соату дақиқаро мегирад, қоидаи рӯзро ошкоро муайян кардан лозим аст: вақти имрӯз гузашта маънои фардоро дорад; баробарӣ бо вақти ҷорӣ метавонад «ҳозир» ё «фардо» бошад. Дар масъалаҳо қоидаи мушаххаси шарт амал мекунад. Як шабонарӯз 1440 дақиқа дорад. Бақияи тақсим ба адади мусбат дар Python ғайриманфӣ аст: ин барои соати даврӣ муфид аст.

Дар мисолҳо сана барои такрорпазирӣ собит аст. Дар боти воқеӣ минтақаи вақтро пешакӣ интихоб кунед; соати сервер метавонад аз соати корбар фарқ кунад. Ҳисобҳои гузариш ба вақти тобистона сана ва минтақаи вақт мехоҳанд, на танҳо шумораи дақиқаҳо.

2. Соҳиб ва тартиби маълумот

Соҳиб тавассути message.from_user.id ва ҷойи фиристодан тавассути message.chat.id муайян мешавад. Дар муколамаи шахсӣ онҳоро омехтан осон аст, вале дар гурӯҳ як чат чанд касро муттаҳид мекунад. Номро ҳамчун калиди дастрасӣ ба ёдрасиҳои дигарон истифода накунед.

Луғат метавонад рӯйхатҳои алоҳидаро аз рӯи ID нигоҳ дорад. setdefault(key, default) ҳангоми набудани калид қимат месозад ва дар ҳолатҳои дигар қимати мавҷударо бармегардонад. Барои намоиш нусхаи мураттабро бо sorted гирифтан қулай аст: тартиби аслӣ дастрас мемонад.

groups = {11: ["B", "A"], 22: ["C"]}
copy = sorted(groups[11])
print(copy)
print(groups[11], groups[22])
print(sorted(["19:00", "08:05", "12:00"]))
print(sorted(["9:00", "10:00"]))

Натиҷа:

['A', 'B']
['B', 'A'] ['C']
['08:05', '12:00', '19:00']
['10:00', '9:00']

Мураттабкунии нусхаи рӯйхати аввал аслиро дигар накард ва ба корбари дуюм таъсир нарасонд. Вақти дорои сифрҳои аввал ҳамчун сатр дуруст мураттаб мешавад. Навиштаи 9:00 бе сифр пас аз 10:00 афтод — ин аллакай тартиби сатрӣ аст, на вақтӣ.

Агар унсурҳо чанд майдон дошта бошанд, калиди мураттабкуниро ошкоро интихоб кунед. Python тартиби нисбии унсурҳои дорои калиди баробарро нигоҳ медорад. Ин барои ду ёдрасии ҳамвақт муфид аст. Мураттаб кардани тамоми ҷуфт метавонад матнро ҳам муқоиса карда, сабтҳои ҳамвақтро ғайричашмдошт ҷойиваз кунад.

3. «Дар замина» чӣ маъно дорад

Task иҷрои ба нақша гирифташудаи корутина дар ҳамон давраи рӯйдодҳо аст. asyncio.create_task(coroutine) Task-ро бе интизори анҷоми корутина бармегардонад. Барои он ки барномаи омӯзишӣ пеш аз вазифа анҷом наёбад, дар охир онро интизор мешавем.

import asyncio

async def later():
    await asyncio.sleep(0)
    print(2)

async def main():
    task = asyncio.create_task(later())
    print(1)
    await task
    print(task.done())

asyncio.run(main())

Натиҷа:

1
2
True

Дар бот коркардкунанда метавонад вазифа сохта, пас аз тасдиқи дархост анҷом ёбад. Худи вазифа интизор мемонад. await asyncio.sleep(seconds) вазифаҳои дигарро намебандад, вале интизории мустақим дар дохили коркардкунанда намегузорад, ки худи он то охири таваққуф анҷом ёбад. Агар тасдиқ пас аз интизорӣ бошад, он ҳам дер меояд.

Истинодҳоро ба вазифаҳои заминавӣ, масалан дар маҷмӯи tasks, нигоҳ доред. task.add_done_callback(tasks.discard) пас аз анҷом истинодро тоза мекунад. Худи тозакунӣ истисноро коркард намекунад: дар барномаи корӣ хатоҳои фиристоданро гирифта, ба журнал сабт кардан лозим аст. Ҳангоми боздоштани бот муайян кунед, ки кадом вазифаҳоро бекор кардан, интизор шудан ё баъд барқарор кардан лозим аст.

4. Бот чӣ тавр мустақилона менависад

message.answer чатро аз паёми воридшуда медонад. Пас аз чанд дақиқа объекти аслии паём дигар лозим нест, агар chat_id ва матн нигоҳ дошта шуда бошанд. bot.send_message(chat_id, text) ба чати муайян паём мефиристад. aiogram объекти Bot-ро ба коркардкунанда бо параметри bot: Bot медиҳад.

Даъвати воқеии методро бо сессияи омӯзишӣ месанҷем. Сессия (session) барои иҷрои дархостҳо масъул аст. ConsoleSession-и мо ба ҷойи шабака параметрҳоро чоп карда, Message-и сунъӣ бармегардонад. Ин намоиши нақлиёти дархост аст, на фиристодан ба инсони воқеӣ.

import asyncio
from aiogram import Bot
from aiogram.client.session.base import BaseSession
from aiogram.methods import SendMessage
from aiogram.types import Chat, Message

class ConsoleSession(BaseSession):
    async def make_request(self, bot, method, timeout=None):
        print(type(method).__name__, method.chat_id, method.text)
        return Message(message_id=1, date=0,
                       chat=Chat(id=method.chat_id, type="private"),
                       text=method.text)

    async def close(self):
        pass

    async def stream_content(self, *args, **kwargs):
        yield b""

async def main():
    async with Bot("1:TEST", session=ConsoleSession()) as bot:
        await bot.send_message(42, "⏰ A")

asyncio.run(main())

Натиҷа:

SendMessage 42 ⏰ A

Бот ба корбаре, ки аллакай суҳбатро оғоз кардааст, ё ба чати дастрас навишта метавонад. Фиристодан метавонад бо хато анҷом ёбад: масалан, шахс ботро манъ кардааст. Аз ин рӯ сохтани бомуваффақияти вазифаи заминавӣ ҳанӯз расонидани паёмро кафолат намедиҳад.

Қисмҳо дар дохил чӣ гуна мепайванданд

Фармони воридшуда санҷида мешавад. Бот соҳиб, чат ва матнро сабт карда, таъхирро ҳисоб мекунад ва интизориро ба нақша мегирад. Ҳангоми хоби вазифа давраи рӯйдодҳо ба паёмҳои дигар хизмат мерасонад. Пас аз анҷоми интизорӣ вазифа SendMessage сохта, ҷавоби Telegram-ро интизор мешавад.

Рӯйхатҳо дар луғати одӣ ва вазифаҳои asyncio танҳо то вақти кори раванд зиндагӣ мекунанд. Пас аз оғози дубора ҳам маълумот ва ҳам интизории ба нақша гирифташуда гум мешаванд. Барои боти устувор сабтҳоро дар пойгоҳи додаҳо нигоҳ дошта, ҷадвалро ҳангоми оғоз барқарор кунед. Барои такрорҳо ва қоидаҳои мураккаб нақшагире мисли APScheduler истифода бурдан мумкин аст; талаботи нигоҳдорӣ ва барқарорсозӣ ҳамоно мемонад.

Оғоз дар Telegram

Бо фармони /newbot дар @BotFather бот созед. Токенро дар муҳит нигоҳ доред: PowerShell — $env:BOT_TOKEN = "123456:ABC..."; macOS/Linux — export BOT_TOKEN="123456:ABC...". Барнома онро бо os.getenv("BOT_TOKEN") хонда, polling-ро оғоз мекунад. Баъд боти худро кушода, суҳбатро оғоз кунед.

Хатоҳои маъмул ва ислоҳ

  1. Ба назар нагирифтани рӯзи дигар. Фарқи одии соатҳо метавонад таъхири манфӣ диҳад. Аввал рӯзи таъинотро муайян карда, вақтҳои пеш, пас ва маҳз баробар ба ҳозирро санҷед.
  2. Фиристодан ба ҷойи нодуруст. bot.send_message(user_id, text) маънои «ба чати гурӯҳии аслӣ»-ро надорад. message.chat.id-ро ҳамчун нишонии расонидан ва ID-и фиристандаро ҳамчун соҳиби маълумот нигоҳ доред.
  3. Бастани давра ҳангоми интизорӣ. time.sleep(60) дар функсияи асинхронӣ давраро бозмедорад. await asyncio.sleep(60) истифода карда, муайян кунед, ки Task-и алоҳида интизор шавад ё худи коркардкунанда.
  4. Фаромӯш кардани воҳид. asyncio.sleep(5) панҷ сония интизор мешавад, на панҷ дақиқа. Давомнокиро як бор ба сония табдил дода, воҳидҳоро равшан ном баред.
  5. Ҷадвали доимӣ ҳисобидани вазифа. Пас аз анҷоми раванд create_task чизеро барқарор намекунад. Барои нигоҳдорӣ пойгоҳ, барқарорсозӣ ҳангоми оғоз ва коркарди хатоҳои расониданро истифода кунед.

Ёддошт

Савол Восита ё қоида
Вақт ё таъхир? Соат лаҳзаро ифода мекунад; sleep сонияҳои давомнокиро мегирад
Сарҳади рӯз куҷост? 1440 дақиқа; қоидаи баробариро алоҳида муайян кунед
Маълумоти кӣ? from_user.id
Ба куҷо фиристодан? chat.id
Чӣ тавр бо тартиб нишон диҳем? sorted(..., key=...) ва формати яксони вақт
Чӣ тавр алоҳида интизор шавем? asyncio.create_task ва asyncio.sleep
Чӣ тавр дертар фиристем? bot.send_message(chat_id, text)
Чӣ пас аз оғози дубора мемонад? Танҳо маълумоти ошкоро сабтшуда ва ҷадвали барқароршуда