import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from PIL import Image, ImageTk
class ScrollableLabel(tk.Frame):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
# Переменная для хранения LaTeX-текста
self.latex_text = r'$\\sum_{i=0}^5(x_i); $' * 100
# Создаем Canvas и Scrollbar (вертикальный и горизонтальный)
self.canvas = tk.Canvas(self, bg="white")
self.v_scrollbar = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
self.h_scrollbar = tk.Scrollbar(self, orient="horizontal", command=self.canvas.xview)
# Настраиваем Canvas для поддержки прокрутки
self.scrollable_frame = tk.Frame(self.canvas, bg="white")
self.scrollable_frame.bind(
"<Configure>",
lambda e: self.canvas.configure(
scrollregion=self.canvas.bbox("all")
)
)
self.canvas.create_window((20, 20), window=self.scrollable_frame, anchor="nw")
self.canvas.configure(yscrollcommand=self.v_scrollbar.set, xscrollcommand=self.h_scrollbar.set)
# Размещаем Canvas и Scrollbar
self.v_scrollbar.pack(side="right", fill="y")
self.h_scrollbar.pack(side="bottom", fill="x")
self.canvas.pack(side="left", fill="both", expand=True)
# Привязываем прокрутку колесом мыши
self.bind_mouse_wheel()
# Создаем LaTeX-изображение
self.create_latex_label()
def bind_mouse_wheel(self):
"""
Привязывает прокрутку колесом мыши к Canvas.
"""
# Для вертикальной прокрутки (Windows/Linux)
self.canvas.bind_all("<MouseWheel>", self._on_mouse_wheel)
# Для горизонтальной прокрутки (Shift + колесо мыши)
self.canvas.bind_all("<Shift-MouseWheel>", self._on_shift_mouse_wheel)
def _on_mouse_wheel(self, event):
"""
Обрабатывает событие вертикальной прокрутки колесом мыши.
"""
if event.num == 4 or event.delta > 0: # Прокрутка вверх
self.canvas.yview_scroll(-1, "units")
elif event.num == 5 or event.delta < 0: # Прокрутка вниз
self.canvas.yview_scroll(1, "units")
def _on_shift_mouse_wheel(self, event):
"""
Обрабатывает событие горизонтальной прокрутки колесом мыши (Shift + колесо).
"""
if event.delta > 0: # Прокрутка влево
self.canvas.xview_scroll(-1, "units")
elif event.delta < 0: # Прокрутка вправо
self.canvas.xview_scroll(1, "units")
def create_latex_label(self):
"""
Создает Label с LaTeX-изображением и добавляет его в scrollable_frame.
"""
# Создаем фигуру matplotlib для рендеринга LaTeX
fig = Figure(figsize=(20, 20)) # Размер фигуры
fig.patch.set_alpha(1) # Прозрачный фон
ax = fig.add_subplot(111)
ax.axis("off") # Отключаем оси
# Рендерим LaTeX-текст
ax.text(0.0, 1.0, self.latex_text, fontsize=20, ha="left", va="top", usetex=True)
# Отчекрыживаем поля
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
# Преобразуем фигуру в изображение
canvas = FigureCanvasTkAgg(fig, master=self.scrollable_frame)
canvas.draw()
# Получаем изображение из canvas
width, height = fig.get_size_inches() * fig.get_dpi() # Размеры в пикселях
image = Image.frombytes('RGBA', (int(width), int(height)), bytes(canvas.buffer_rgba()))
# Для версий matplotlib <= 3.8:
# image = Image.frombytes('RGB', (int(width), int(height)), canvas.tostring_rgb())
# image.save('lol.png')
# Преобразуем изображение в формат, поддерживаемый Tkinter
self.image = ImageTk.PhotoImage(image)
# Создаем Label с изображением и добавляем его в scrollable_frame
self.label = tk.Label(self.scrollable_frame, image=self.image, bg="white")
self.label.pack(pady=10)
# Сохраняем ссылку на изображение, чтобы оно не удалялось сборщиком мусора
self.label.image = self.image
def update_latex_text(self, new_text):
"""
Обновляет LaTeX-текст и перерисовывает Label.
"""
self.latex_text = new_text
# Очищаем scrollable_frame и создаем новый Label
for widget in self.scrollable_frame.winfo_children():
widget.destroy()
self.create_latex_label()
if __name__ == "__main__":
root = tk.Tk()
root.title("LaTeX в Tk.Label с прокруткой")
# Создаем ScrollableLabel
scrollable_label = ScrollableLabel(root)
scrollable_label.pack(fill="both", expand=True, padx=10, pady=10)
# Создаем Entry для ввода текста
entry = tk.Entry(root, font=("Arial", 14))
entry.pack(fill="x", padx=10, pady=5)
# Создаем Button для обновления текста
def on_button_click():
new_text = entry.get()
scrollable_label.update_latex_text(new_text)
button = tk.Button(root, text="Обновить", command=on_button_click, font=("Arial", 14))
button.pack(pady=5)
root.mainloop()
start_time
заведомо "меньше", чем server_time
, а вы вычитаете из меньшего большее, то и возникает разница в -1 день. abs
при подсчёте дельты:from datetime import datetime, timezone
start_time = datetime(2025, 1, 27, 23, 59, 59, tzinfo=timezone.utc)
server_time = datetime(2025, 1, 28, 0, 0, 0, tzinfo=timezone.utc)
delta = start_time - server_time
print("Дельта:", delta)
>>> Дельта: -1 day, 23:59:59
abs_delta = abs(start_time - server_time)
print("Дельта:", abs_delta)
>>> Дельта: 0:00:01
for event in pg.event.get():
, из-за этого не обрабатываются корректно нажатия на кнопки.while running:
clock.tick(60)
mouse = pg.mouse.get_pos()
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
if game_over:
if event.type == pg.MOUSEBUTTONDOWN:
if WIDTH / 3 <= mouse[0] <= WIDTH / 3 + WIDTH_BUTT0N and HEIGHT / 2.5 <= mouse[1] <= HEIGHT / 2.5 + HEIGHT_BUTTON:
game_over = False
else:
if event.type == pg.KEYDOWN and generation_happen == 1:
if event.key == pg.K_LEFT:
board = move_left(board)
if event.key == pg.K_UP:
board = move_up(board)
if event.key == pg.K_DOWN:
board = move_down(board)
if event.key == pg.K_RIGHT:
board = move_right(board)
time = 0
generation_happen = 0
if not game_over:
if time is not None:
time += 1
if is_terminal(board):
game_over = True
if time is not None and time >= 10:
generation_2_or_4(board)
time = None
generation_happen = 1
screen.fill(BACK)
for row in range(4):
for column in range(4):
COLOR = colors[board[row][column]]
x_play_cell = column * size_of_cell + (column + 1) * margin
y_play_cell = row * size_of_cell + (row + 1) * margin
pg.draw.rect(screen, COLOR, (x_play_cell, y_play_cell, size_of_cell, size_of_cell))
if board[row][column] != 0:
text = font.render(str(board[row][column]), True, BLACK)
screen.blit(text, (35 + x_play_cell, y_play_cell + 25))
else:
screen.fill(BACK)
pg.draw.rect(screen, WHITE, [WIDTH / 3, HEIGHT / 2.5, WIDTH_BUTT0N, HEIGHT_BUTTON])
screen.blit(text, (WIDTH / 3, HEIGHT / 2.5))
pg.display.flip()
pg.quit()
index_col=0
: test_df = pd.read_excel(orders_path)
test_df.columns = ['Weekday', 'Shop_1', 'Shop_2', 'Shop_3', 'Shop_4']
test_df = pd.read_excel(orders_path, index_col=0)
if not os.path.exists(orders_path):
print(f"Файл {orders_path} не найден.")
<input type="number" step="0.00000001" id="numberInput" />
<script>
const input = document.getElementById("numberInput");
input.addEventListener("input", () => {
const value = parseFloat(input.value);
if (!isNaN(value)) {
input.value = value.toFixed(8); // Форматируем до 8 знаков после запятой
}
});
</script>
width
, height
, наверное, не лучшая идея. Надо подстраивать под разрешение монитора, там где её запустили. Я, запустив, например, не увидел счётчик про который вы говорите.count_lifes
должна быть глобальной. Сейчас вы её обнуляете в цикле, каждый тик. pack()
нет таких параметров: https://metanit.com/python/tkinter/2.4.phpbtnSc.pack(anchor=CENTER)
SORT_BUTTON = (By.XPATH, "(//span[@class='select2-selection select2-selection--single select2-selection--buttoned select2-selection--buttoned-dark select select--sorting'])[1]")
SORT_ASC_OPTION = (By.ID, 'select2-catalog_sorting_mobile-7h-result-jsvp-price:asc')
SORT_DESC_OPTION = (By.ID, 'select2-catalog_sorting_mobile-7h-result-jsvp-price:desc')
def select_sort_option()
добавил небольшую задержку (2-3 секунды) после WebDriverWait(self.driver, 10).until(EC.staleness_of(option))
. [...11900, 11900, 7735, 11900...],
что никак не будет равно отсортированному списку цен в assert
.test_sort_by_price[\u0426\u0435\u043d\u0430 \u043f\u043e \u0432\u043e\u0437\
,[pytest]
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True
prerequisite: python 3.9 и winrt
import asyncio
from winrt.windows.ui.notifications.management import UserNotificationListener
from winrt.windows.ui.notifications import KnownNotificationBindings
async def notification_handler(listener, seen_notifications):
print("Слушатель уведомлений запущен. Ожидание новых уведомлений...")
# Бесконечно слушаем уведомления
while True:
try:
# Получение всех текущих уведомлений
notifications = await listener.get_notifications_async(0)
for notification in notifications:
notification_id = notification.id # Получаем уникальный ID уведомления
# Проверяем, было ли это уведомление уже обработано
if notification_id not in seen_notifications:
seen_notifications.add(notification_id) # Добавляем ID в множество обработанных уведомлений
try:
# Получение информации об уведомлении
app_name = notification.app_info.display_info.display_name
binding = notification.notification.visual.get_binding(KnownNotificationBindings.get_toast_generic())
if binding:
text_elements = binding.get_text_elements()
title = text_elements[0].text if len(text_elements) > 0 else "Без заголовка"
body = text_elements[1].text if len(text_elements) > 1 else "Без текста"
print(f"Новое уведомление!")
print(f"Приложение: {app_name}")
print(f"Заголовок: {title}")
print(f"Текст: {body}")
print("-" * 50)
# Проверяем что ув. от нужного приложения и делаем всякое нужное с ним.
except Exception as e:
print(f"Ошибка при обработке уведомления: {e}")
# Задержка перед следующим циклом
await asyncio.sleep(1)
except Exception as e:
print(f"Ошибка при получении уведомлений: {e}")
await asyncio.sleep(5) # Задержка перед повторной попыткой в случае ошибки
async def main():
# Получение текущего слушателя уведомлений
listener = UserNotificationListener.get_current()
# Смотрим есть ли разрешение на доступ к уведомлениям. Если нет, лезем в настройки уведомлений.
access_status = await listener.request_access_async()
if access_status != 1:
print("Нет разрешения на доступ к уведомлениям. Проверьте настройки конфиденциальности.")
return
seen_notifications = set() # Множество для хранения ID уже обработанных уведомлений
await notification_handler(listener, seen_notifications)
if __name__ == "__main__":
asyncio.run(main())
import requests
from bs4 import BeautifulSoup
def parse_table(div, results):
# Ищем таблицы внутри данного div
tables = div.find_all('table')
for table in tables:
rows = table.find_all('tr')
for row in rows:
cells = row.find_all('td')
if cells:
# Извлекаем название и ссылку
name = cells[0].get_text(strip=True)
link = cells[0].find('a')['href'] if cells[0].find('a') else None
if link:
results[name] = link
def recursive_parse(url, visited, results):
if url in visited:
return
visited.add(url)
print('Парсим URL:', url)
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# Ищем все div с itemscope
divs = soup.find_all('div', itemscope=True)
for div in divs:
parse_table(div, results) # Парсим таблицы внутри найденного div
# Ищем все ссылки на подстраницы
links = soup.find_all('a', href=True)
for link in links:
sub_url = link['href']
# Проверяем, что ссылка ведет на подстраницу и не является текущим URL
if 'respublika_bashkortostan' in sub_url and sub_url.startswith('http') and sub_url != url:
recursive_parse(sub_url, visited, results)
# Начальная URL
start_url = 'https://russiaschools.ru/respublika_bashkortostan/'
visited_urls = set()
results_dict = {}
recursive_parse(start_url, visited_urls, results_dict)
for name, link in results_dict.items():
print(f'Название: {name}, Ссылка: {link}')
file_content="$(cat /some/file)"
echo $file_content
>>> lol kek cheburek. kol
echo "$file_content"
>>> lol
kek cheburek.
kol
f=""
while IFS= read -r line || [[ -n "$line" ]]; do
f+="${line}"$'\n'
done < 1.txt
f="${f%$'\n'}"
echo "$f" > 2.txt