Задать вопрос
  • Почему тип dict не изолируется внутри класса?

    Vindicar
    @Vindicar
    RTFM!
    class Interface:
        a = 1
        b = dict()
        c = []

    Ты описал класс с тремя атрибутами класса. Не экземпляра, а именно класса.
    Три атрибута экземпляра описываются как
    class Interface:
        def __init__(self):
            self.a = 1
            self.b = dict()
            self.c = []

    А если тебе нужен эквивалент интерфейсов, почитай про typing.Protocol.
    Ответ написан
    Комментировать
  • Как переадресовать локальный порт на внешний IP с помощью Python?

    Vindicar
    @Vindicar
    RTFM!
    Настрой роутер. Если роутер поддерживает UPnP, можно попробовать сделать это программно. Но успешность будет зависеть от настроек и модели роутера.
    Ответ написан
    Комментировать
  • Как сделать анимацию загрузки при условии на python tkinter?

    Vindicar
    @Vindicar
    RTFM!
    1. Подумать.
    2. Сделать.

    А если серьёзно, вынеси загрузку в отдельный поток, в идеале - обёрнутый в класс. Поток НЕ ДОЛЖЕН обращаться напрямую к элементам интерфейса - только к полям своего класса.
    По нажатию кнопки запускай этот поток. Только запуск, без ожидания.

    Чтобы обнаружить завершение, после запуска потока сделай цикл с помощью window.after(). Подробности в доках, но если кратко, метод after() позволяет вызвать функцию в потоке GUI спустя некоторое время. При этом функция может снова запланировать свой вызов через after(), тем самым создавая как-бы цикл. Если не запланируешь новый вызов - цикл прервётся.
    Соответственно, идея в том, что эта функция будет проверять, не закончил ли поток работу (например, читать какое-нибудь логическое значение). Если закончил - она будет вправе обратиться к элементам GUI, чтобы вывести результат. Если не закончил - она снова запланирует свой вызов через after(), скажем, через 200 миллисекунд.

    Ну и да - исключения, чёрт побери! Обрабатывай исключения!
    Ответ написан
    2 комментария
  • Как организовать сравнение даты в переменной с форматом эталона?

    Vindicar
    @Vindicar
    RTFM!
    Документацию читать пробовал?
    ValueError is raised if the date_string and format can’t be parsed by time.strptime() or if it returns a value which isn’t a time tuple

    Если входная строка или строка формата не поддаются разбору вызовом time.strptime(), или если эта функция возвращает не кортеж с описанием даты-времени, функция выбрасывает исключение ValueError.

    Учись обрабатывать исключения блоком try-except.
    Впрочем, если судить вот по этому:
    if res == True:
        ...
    elif res == False:
        ...

    Стоит вообще поучить язык, а потом уже браться за ботов. Это технически сработает, но выдаёт непонимание того, как работают логические переменные.
    Правильнее будет
    if res:
        ...
    else:
        ...


    Также задачу соответствия текста шаблону часто удобнее решать регулярными выражениями. Например:
    import datetime
    import re
    # цифра, за ней может быть ещё одна, за ними "-", "/" или ".", 
    # потом опять цифра, за ней может быть ещё одна, за ними "-", "/" или ".", 
    # потом 2 или 4 цифры
    regexp = re.compile(r'(\d\d?)[-/.](\d\d?)[-/.](\d{2}|\d{4})')
    text = input('Введите дату в формате DD/MM/YYYY: ')
    match = regexp.search(text)
    if match is None:
        print('Вы ввели не дату, или ввели её в неправильном формате')
    else:
        day, month, year = int(regexp.group(1)), int(regexp.group(2)), int(regexp.group(3))
        # тут нужна ещё проверка, так как пользователь может ввести 99/99/9999
        try:
            userdate = datetime.date(year, month, day)
        except ValueError:
            print('Это некорректная дата.')
        else:
            print('Дата корректна.')
    Ответ написан
  • Как записать Input в TelegramBotApi?

    Vindicar
    @Vindicar
    RTFM!
    А теперь еще раз и по-человечески.
    Ты хочешь, чтобы сообщения пользователя интерпретировались по-разному, в зависимости от того, на каком шаге сценария он находится?
    Тебе нужны finite state machine (FSM). Не уверен, что PyTelegramBotAPI их умеет - смотри документацию на него.
    Ответ написан
  • Sqlite - как добавить текст в ячейку бд, если в нем могут содержаться и одинарные, и двойные кавычки?

    Vindicar
    @Vindicar
    RTFM!
    А всего-то нужно прочитать документацию. Там этот случай описан, и показано, как делать правильно.
    con = sqlite3.connect(":memory:")
    cur = con.execute("CREATE TABLE lang(name, first_appeared)")
    
    # This is the named style used with executemany():
    data = (
        {"name": "C", "year": 1972},
        {"name": "Fortran", "year": 1957},
        {"name": "Python", "year": 1991},
        {"name": "Go", "year": 2009},
    )
    cur.executemany("INSERT INTO lang VALUES(:name, :year)", data)
    
    # This is the qmark style used in a SELECT query:
    params = (1972,)
    cur.execute("SELECT * FROM lang WHERE first_appeared = ?", params)
    print(cur.fetchall())
    Ответ написан
    5 комментариев
  • Как запустить двух ботов одновременно?

    Vindicar
    @Vindicar
    RTFM!
    Простого способа нет.
    Если оба бота написаны на базе asyncio, то скорее всего их метод run_forever() или эквивалент сводится к вызову asyncio.run(корутина_тело_бота()). Тогда можно будет свести запуск бота к тайой конструкции
    async def main():
        await asyncio.gather(
            корутина_тело_бота1(),
            корутина_тело_бота2()
        )
    
    if __name__ == '__main__':
        asyncio.run(main())

    Программа завершится, когда завершатся оба бота.
    Но чтобы добраться до "настоящего" тела бота, нужно как минимум зарыться в документацию, а то и почитать исходники библиотеки, в частности, исходники run_forever() (или его аналога).
    Не получится просто взять и написать
    async def bot1():
        bot1.run_forever()

    Чудес не бывает.

    Есть вариант запустить ботов в разных потоках, и это единственный вариант, если хотя бы один из ботов не асинхронный. Но я бы не советовал. Многопоточные программы имеют целую кучу своих специфических багов, которые могут проявляться не при каждом запуске. Они очень неприятны в отладке.
    А уж мешать многопоточность с асинхронностью... тут нужно очень хорошо понимать, как это всё работает.
    Ответ написан
    Комментировать
  • Некорректная работа sqlite. Работа с параметрами. Что мне делать?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, проверить структуру таблицы eBase, какие столбцы там есть.
    Во-вторых, никогда не использовать форматирование строк для составление запросов.
    Для этой цели есть parametrized queries.
    Ответ написан
    5 комментариев
  • Как обработать ошибку UnicodeDecodeError и при этом продолжить чтение файла?

    Vindicar
    @Vindicar
    RTFM!
    Альтернативное решение - использовать не обёртку for ... in file, а использовать цикл while и вызывать file.readline() вручную.
    Ответ написан
    Комментировать
  • Как посмотреть тело функции в python?

    Vindicar
    @Vindicar
    RTFM!
    Для встроенных функций не получится. Они не на Питоне реализованы. Читай исходники, как посоветовал Влад Григорьев .
    Ответ написан
    Комментировать
  • Почему выходит None?

    Vindicar
    @Vindicar
    RTFM!
    else print(item + "-NO")
         ^^^^^
    Ответ написан
    Комментировать
  • Как работает переприсваивании значений переменных Phyton?

    Vindicar
    @Vindicar
    RTFM!
    Мы ведь уже присвоили в предыдущем блоке if, что l1 = a.

    А может, и не присвоили. Не факт, что предыдущий if выполнился. Тогда останется l1 от предыдущей итерации цикла. А на первой итерации - будет начальное значение l1 = 0.
    Ответ написан
    Комментировать
  • Как записать Словарь в CSV по СТОЛБЦАМ в Python?

    Vindicar
    @Vindicar
    RTFM!
    Открой для себя функции zip() и itertools.zip_longest().
    Ответ написан
  • Как проверить запущен ли сервер или нет по его IP адресу на Python?

    Vindicar
    @Vindicar
    RTFM!
    Пинг проверяет доступность целевого узла из данного узла.
    Если по какой-то причине нет связности между двумя узлами, или если машина настроена не отвечать на пинг, или какой-то из промежуточных узлов режет ICMP трафик, ты ответа не получишь, даже если сервер будет активен.

    Кроме того, машина может быть активна и отвечать на пинг, но если сервис (программа), которая тебе нужна, не запущена, ты тоже получишь ложный результат.

    Я бы пытался подключиться к серверу по требуемому тебе протоколу, и судил по этому.
    А если сервер тебе подконтролен - оцени возможность использования существующих средств мониторинга, прежде чем писать свои.
    Ответ написан
    Комментировать
  • Как прочитать первый n строк из файла, удалив их из него?

    Vindicar
    @Vindicar
    RTFM!
    Нет. Ты можешь открыть файл на чтение и запись, и затем скакать по файлу с помощью seek(), но это ничуть не быстрее. Меньше дискового пространства требует, вот и вся выгода.
    Текстовые файлы вообще плохо поддаются частичному обновлению.
    Если тебе такое требуется часто, впору смотреть в сторону простых БД, вроде sqlite. Ей не требуется отдельное серверное ПО, и база данных будет состоять из одного файла. Вполне себе нормальный апгрейд.
    Ответ написан
  • Как поменять местами максимальный и минимальный элемент списка?

    Vindicar
    @Vindicar
    RTFM!
    Включи логику.
    Чтобы прочитать/записать элемент списка, нужно знать его индекс.
    Ты знаешь значение минимума/максимума, но не индекс.
    Вывод: нужно в цикле поиска обновления не только само значение minimum и maximum, но и в отдельной паре переменных хранить индекс i, где был обнаружен последний минимум/максимум.

    Любопытно, что ты уже используешь enumerate() для перечисления списка, но до сих пор не использовал индекс очередного элемента i, который он тебе сообщает.
    Ответ написан
  • Можно ли выполнять код при досрочном завершении программы?

    Vindicar
    @Vindicar
    RTFM!
    Зависит от того, что ты понимаешь под досрочным завершением, и что ты хочешь сделать в рамках реакции на это завершение.
    Например, os._exit() прибьёт процесс так, что никакое завершение не отработает. Аналогично, есть другеи ситуации, когда процесс прибивается "снаружи". В таких случаях только мониторинг со стороны родительского процесса, только хардкор.
    В простейшем случае можно завернуть тело программы в try-except, try-finally или кастомный блок with (скажем, через contextlib.contextmanager).
    Также можно посмотреть в сторону модуля atexit, но там свобода действий будет более ограничена.
    Ответ написан
    Комментировать
  • Можно так сделать с interface?

    Vindicar
    @Vindicar
    RTFM!
    Ты хочешь странного. Но ты можешь сделать класс-посредник, который будет дружественным к "владельцу" (основному классу), и будет предоставлять доступ к защищенным методам владельца. А в остальные функции уже передавать этого посредника. Этакий Public Морозов.

    Но лучше еще раз подумать, зачем тебе доступ к защищенному контенту класса вне этого класса. Или доступ не нужен, или контент не должен быть защищённым.
    Ответ написан
    Комментировать
  • Авторизация пользователя в личном скрипте как?

    Vindicar
    @Vindicar
    RTFM!
    Выше тебе уже написали, что единственный способ - не давать код системы пользователю.

    Можешь потыкать модуль pyarmor, но это не панацея, знающий человек его снимет. Это, впрочем, посложнее, чем открыть код программы блокнотом.
    Ответ написан
    Комментировать
  • Почему все говорят что писать ботов это сложно?

    Vindicar
    @Vindicar
    RTFM!
    А сложность начинается, как только задачи, стоящие перед ботом, перерастают уровень примера в документации видеотуториале пятилетней давности.

    Нужно сделать несколько под-команд у команды. Напишу цепочку if-elif-else, делов то. Ой, а теперь простыня кода на пять экранов, в которой фиг чего найдёшь. Потому что нет привычки структурировать код.

    Нужно, чтобы несколько команд/событий формировали цепочку (сценарий). Например, пользователь отправил тре сообщения, первое с именем, второе с возрастом, третье с адресом. Ой, а как это сделать вообще? Не зная понятия "конечный автомат" (finite state machine, FSM), очень трудно догадаться, как тут поступить.

    Нужно, чтобы ботом могли пользоваться несколько человек. Ой, их данные перепутались! Потому что бот использует глобальные переменные.

    Нужно, чтобы бот выполнил длительную задачу, и написал сообщение, когда она выполнится. Не вопрос, напишу функцию, вызову её, а сразу после отправлю сообщение. Ой, а бот не отвечает! Потому что рабочий цикл asyncio занят этой длительной операцией и не может отреагировать на поступающие данные. Нужно иметь хорошее представление о том, как работает асинхронная программа.

    Нужно добавить боту графический интерфейс - админку. Ой, а работает или интерфейс, или сам бот! Потому что нужно представлять, как устроено большинство GUI-фреймворков, и как устроена асинхронное приложение. А заодно понимать многопоточность, вопросы синхронизации действий между двумя потоками, и особенности работы с asyncio в многопоточных приложениях. Потому что одним потоком тут обойтись будет очень непросто.

    Нужно хранить данные в БД. Ой, а почему у меня проблемы при записи в БД имени пользователя? А потому что погромист собирает SQL-запрос через форматирование строк. Надо было почитать доки, чтобы наткнуться на prepared statements, они же parameterized queries.

    Нужно хранить данные в БД. Вот только данные имеют связи многие-ко-многим. Я знаю! Я буду просто добавлять или удалять столбцы в таблицу! Потому что не освоены даже азы проектирования БД. Тут уже nuff said. И да, я такое видел на этом сайте.

    Незнание средств языка и основных приемов построения алгоритмов и структур данных приводит к диким велосипедам, которые создают больше проблем, чем пользы. Особенно если к этому добавляется нежелание находить и читать документацию на фреймворк, на котором построен бот.
    Ответ написан
    2 комментария