@Murat-student

Проблема с кодом на Python ошибка после компиляции в Exe для windows 10?

возникла необходимость в маленьком приложении для windows 10, которая бы выключала дисплей вечером и включала его под утро.
в коде программы eсть функция def check_schedule2():
ЕЕ задача проверять каждые 3 минуты что текущее время в диапазоне между временем выключения и временем включения монитора, если выполняется условие то отрубается монитор.
Работает она вроде бы нормально если время выключения к примеру 23:00 и время включения 7:00.
Но вот если выставить время выключения 00:05 , то уже не срабатывает нормально условие.
Может что то добавить нужно?
И вторая проблема, что при компиляции через PYINSTALLER , в один файл, конечная программа выдает ошибку
Traceback (most recent call last):
File "program_api.py", line 118, in
File "program_api.py", line 59, in check_schedule2
TypeError: '>' not supported between instances of 'str' and 'NoneType'

судя по ошибке я понял что оператор сравнения не работает с разными типами данных, но не понимаю как привести к одному типу для сравнения.
сам код программы
spoiler

# импортируем необходимые модули
import os
import time
import datetime
import win32api
import win32con
import pyautogui
import tkinter as tk
from tkinter import ttk

# устанавливаем некоторые константы, используемые в программе
FILENAME = "monitor_schedule.txt"  # имя файла, в который сохраняется расписание

# получаем путь к рабочей папке
current_directory = os.getcwd()

# определяем функцию, которая сохраняет расписание в файл
def save_schedule(start_time, end_time):
    with open(os.path.join(current_directory, FILENAME), "w") as f:
        f.write(f"{start_time},{end_time}")

# определяем функцию, которая загружает расписание из файла
def load_schedule():
    try:
        with open(os.path.join(current_directory, FILENAME), "r") as f:
            data = f.read()
            start_time, end_time = data.strip().split(",")
            return start_time, end_time
    except FileNotFoundError:
        return None, None
# функция winapi для включения
def turn_monitor_on():
    pyautogui.press('esc')
    #win32api.SendMessage(win32con.HWND_BROADCAST,win32con.WM_SYSCOMMAND, win32con.SC_MONITORPOWER, -1)
#  функция использующая winapi для выключения
def turn_monitor_off():
    win32api.SendMessage(win32con.HWND_BROADCAST,win32con.WM_SYSCOMMAND, win32con.SC_MONITORPOWER, 2)
def move_cursor():
    x, y = (0,0)
    win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, x, y)
# определяем функцию, которая проверяет расписание и включает/выключает монитор при необходимости
def check_schedule():
    start_time, end_time = load_schedule()
    if start_time and end_time:
        now = time.strftime("%H:%M")
        if now == start_time:
            print ('monitor must on')
            turn_monitor_on()
        elif now == end_time:
            print('monitor must of')
            turn_monitor_off()
    root.after(30000, check_schedule)
# Проверка на случайное пробуждение от мышки, выключает монитор через каждые 3 минуты
def check_schedule2():
    start_time, end_time = load_schedule()
    now = time.strftime("%H:%M")
    print  ('Shedule2 run')
    print (start_time)
    if now > start_time and now < end_time:
            print ('monitor on')
    else:
            print ('monitor go off')
            turn_monitor_off()
    root.after(180000,check_schedule2)

# определяем функцию, которая сохраняет расписание, когда пользователь нажимает на кнопку "Save"
def save_button_click(start_entry, end_entry):
    start_time = start_entry.get()
    end_time = end_entry.get()

    # проверяем, что введенные значения соответствуют формату времени HH:MM
    try:
        datetime.datetime.strptime(start_time, "%H:%M")
        datetime.datetime.strptime(end_time, "%H:%M")
    except ValueError:
        status_label.config(text="Ошибка: время должно быть в формате HH:MM")
        return

    # приводим введенное время в нужный формат
    start_time = datetime.datetime.strptime(start_time, "%H:%M").strftime("%H:%M")
    end_time = datetime.datetime.strptime(end_time, "%H:%M").strftime("%H:%M")

    save_schedule(start_time, end_time)
    status_label.config(text="расписание сохранено")

# создаем главное окно программы
root = tk.Tk()
root.title("Включение/Выключение Монитора")
#root.geometry("500x150")
root.title.__sizeof__
# создаем интерфейс программы с помощью библиотеки Tkinter
start_label = tk.Label(root, text="Вкл монитора:(H:M)")
start_label.grid(row=0, column=0)

start_entry = tk.Entry(root,width = 5)
start_entry.grid(row=0, column=1)

end_label = tk.Label(root, text="Выкл монитора:(H:M)")
end_label.grid(row=1, column=0)

end_entry = tk.Entry(root,width = 5)
end_entry.grid(row=1, column=1)

save_button = tk.Button(root, text="Сохранить", command=lambda: save_button_click(start_entry, end_entry))
save_button.grid(row=2, column=1)

status_label = tk.Label(root, text="")
status_label.grid(row=3, column=0, columnspan=2)

# загружаем расписание из файла и заполняем поля ввода
start_time, end_time = load_schedule()
if start_time and end_time:
    start_entry.insert(0, start_time)
    end_entry.insert(0, end_time)

# Start the scheduler
check_schedule()
check_schedule2()
root.mainloop()

  • Вопрос задан
  • 206 просмотров
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
# определяем функцию, которая загружает расписание из файла
def load_schedule():
    try:
        ...  # реальная ошибку у тебя где-то здесь!
    except FileNotFoundError:  # но при ошибке ты глотаешь исключение и молча возвращаешь None
        return None, None

def check_schedule2():
    start_time, end_time = load_schedule()
    ...  # а тут не проверяем, вернула ли функция значение или None

Выстрел в ногу удался, что тут скажешь. Сначала скрыл истинную причину ошибки за молчаливым return None, потом не стал проверять, что вернулось, а теперь столкнулся с этим None ниже по коду и пытаешься понять, что произошло.

А еще да, сравнение строк производится лексикографически (посимвольно). Т.е. строка "2" будет больше чем "12". Конкретно в твоём случае это сработает, так как у тебя будет "02", а не "2" для двух часов, но так делать всё равно неправильно. Я бы рекомендовал почитать про класс datetime.datetime (модуль datetime), его экземпляры можно сравнивать напрямую.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы