Уведомления

Группа в Telegram: @pythonsu

Уведомления

  • Found 3484 posts.

Python для новичков » Определить используется ли в данный момент диалоговое окно » вчера 16:51:06

Код определяет запущен ли в данный момент указанный процесс:
 import psutil
def check_python_program(program_name):
    for proc in psutil.process_iter():
        try:
            if proc.name() == program_name:
                return True
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass
    return False
if check_python_program("msedge.exe"):
    print("Программа запущена.")
else:
    print("Программа не запущена.")
Процесс ‘микрософт едж’ всегда запущен в фоне, получится определить используется в данный момент окно браузера или нет?

Python для новичков » Не могу пометить узлы, добавляемые в цикле » вчера 12:40:29

Пытаюсь создать сеть с возможностью гибкого изменения ее параметров: количества слоев, узлов в слоях и положения узлов на рисунке.
Основная часть программы
 n_nd = 1
for i_l in range(n_lines):
    for i_n in range(n_nods[i_l]):
        G.add_node(1,label=str(n_nd))
        n_nd += 1
        G.add_edge(i_l,i_n)
        pos = {n_nd:(i_l,i_n) }
nx.draw(G,with_label=True)
В таком виде nx.draw считается ошибкой:
“ Traceback (most recent call last):
File ”c:\Users\frost\Net\Net.py“, line 22, in <module>
nx.draw(G,with_label=True)
File ”C:\Users\frost\AppData\Local\Programs\Python\Python312\Lib\site-packages
\networkx\drawing\nx_pylab.py“, line 126, in draw
draw_networkx(G, pos=pos, ax=ax, **kwds)
File ”C:\Users\frost\AppData\Local\Programs\Python\Python312\Lib\site-packages
\networkx\drawing\nx_pylab.py“, line 305, in draw_networkx
raise ValueError(f”Received invalid argument(s): {invalid_args}“)
ValueError: Received invalid argument(s): with_label ”
Линия 22 это draw
При использовании nx.draw(G) все рисуется.

Python для новичков » Inline кнопки в TG. Что делаю не так? » Дек. 27, 2024 10:30:50

Приветствую! Пытаюсь создать меня чтобы при нажатии кнопки провалиться в следующее меню. При нажатии на кнопку “Веб сайты” я не перехожу в следующее меню. В чём ошибка?


import telebot
from telebot import types

bot = telebot.TeleBot(“***”)

@bot.message_handler(commands= ) *тут всё норм, почему то не отображается *
def start(message):
markup = types.InlineKeyboardMarkup()
btn1 = types.InlineKeyboardButton(“Веб сайты”, callback_data=“sites”)
btn2 = types.InlineKeyboardButton(“Игры”, callback_data=“games”)
btn3 = types.InlineKeyboardButton(“Приложения ”, callback_data=“apps”)
markup.row(btn1, btn2, btn3)
bot.send_message(message.chat.id, “Привет! Это бот для языка программирования.\n\nВыберите какое направление вас интересует”, reply_markup=markup)
#await message.answer(“Привет! Это бот для подбора языка программирования.\n\nВыберите какое направление вас интересует”)

@bot.callback_query_handler(func=lambda callback:True)
def callback(call):
markup = types.InlineKeyboardMarkup()
if call.data == “start”:
btn1 = types.InlineKeyboardButton(“Веб сайты”, callback_data=“sites”)
btn2 = types.InlineKeyboardButton(“Игры”, callback_data=“games”)
btn3 = types.InlineKeyboardButton(“Приложения ”, callback_data=“apps”)
markup.row(btn1, btn2, btn3)
bot_send_message_edit_text(“Привет! Это бот для языка программирования.\n\nВыберите какое направление вас интересует”, reply_markup=markup)
#bot.send_message(message.chat.id, “Привет! Это бот для подбора языка программирования”, reply_markup=markup)
elif call.data == ‘sites’:
btn1 = types.InlineKeyboardButton('Большие сайты', callback_data='sites-big')
btn2 = types.InlineKeyboardButton('Маленькие', callback_data='sites-small')
btn3 = types.InlineKeyboardButton('Назад', callback_data='start')
markup.add(btn1, btn2, btn3)
bot.send_message_edit_text(“Привет! Это бот для языка программирования.\n\nВыберите какое направление вас интересует”, callback_data=start)

#bot.send_message(message.chat.id, “Привет”, reply_markup=markup)
#reply_markup=markup1


bot.polling(none_stop=True)

Флейм » Купить Google Gmail YouTube аккаунты (Продажа Google, Gmail, YouTube) » Дек. 24, 2024 05:09:42



Google, Gmail, YouTube аккаунты, подтверждены по СМС, привязана дополнительная почта!
Аккаунты Гугл подойдут для большинства задач!


Основные типы аккаунтов в наличии:


✅ Gmail - Аккаунты Отлежка: несколько часов | Будут заблокированы через 3-5 суток

✅ Аккаунты Google Рег IP - MIX Отлежка - от 3-х суток до 6 месяцев! Пол - MIX При входе не просят СМС

✅ Аккаунты Google Рег IP - MIX Отлежка - от 3-х суток до 6 месяцев! Пол - MIX Создан YouTube канал

✅ GOOGLE GMAIL 2FA Пароль приложения Резервные коды Токен Аутентификатора Отлежка: 10 дней и больше Пол - MIX EN интерфейс Вход с IP любой страны! При входе не просят СМС


Общие параметры всех аккаунтов в ассортименте:




  • Происхождение аккаунтов: Аккаунты Google зарегистрированы автоматически
  • При входе с любого нового устройства не просят СМС
  • Интерфейс аккаунтов на английском языке
  • Имена и фамилии написаны на английском (Пример: Alexey Morozov, Alex Brown, Jessica Smith)
  • Привязана Дополнительная почта
  • Аккаунты активированы по СМС
  • Номер удален из профиля
  • Активировано 2FA! Можно заходить с IP любой страны
  • Указан Пароль приложения!
  • Указан Токен Аутентификатора для генерации бесконечных кодов для входа!
  • Указаны Резервные коды для входа!
При входе с любого нового устройства не просят СМС


Формат выдаваемых аккаунтов может меняться в зависимости от покупаемых вами аккаунтов:
Логин:Пароль:Дополнительная Почта (Это базовый формат, большинства аккаунтов)


Купить Гугл, Гмаил, Ютуб аккаунты по лучшей цене в Telegram: @Belich707
Купить Гугл, Гмаил, Ютуб аккаунты на сайте: belich707.com
Купить Гугл, Гмаил, Ютуб аккаунты в боте Telegram: @Belich707Bot

Флейм » Мощные и доступные виртуальные (VPS/VDS) во всех точках мира » Ноя. 22, 2024 08:41:19




Мы выходим из тени

Нам доверяют уже многие клиенты, и ты можешь стать одним из наших доверенных партнеров. Рады представить вам наши быстрые, мощные и доступные виртуальные (VPS/VDS) и выделенные серверы. Наши решения охватывают широкий спектр задач и потребностей, обеспечивая высокую производительность и надежность. Мы премиальный хостинг со всеми удобствами.

Почему стоит выбрать нас

- Аренда серверов по всему миру!
- Самые мощные процессоры: AMD Ryzen 9 7950X3D.
- Лучшая защита от DDoS атак: По всему миру. AntiDDoS-защита на всех серверах.
- Быстрейшие серверы: Высокая производительность и надежность.
- Стабильный коннект: К любой точке мира.
- Быстрая активация: В течение 60 секунд после оплаты.
- Круглосуточная поддержка: 24/7/365. Поможем с установкой и настройкой ПО, решим почти любую проблему.
- Индивидуальный подход: К каждому клиенту индивидуальные условия, все можно обсудить через систему тикетов.
- Удобный личный кабинет: Большое количество платёжных методов, современный интерфейс и лёгкое управление услугами.
- Бонусы и проработанная реферальная программа!

Мы за стабильную работу и долгосрочное сотрудничество.
Будем улучшать инфраструктуру и производительность постоянно, а наши цены не будут меняться в большую сторону.

- Интернет-порт: До 10 Гбит/с в Москве и в Европе.
- Локации VPS: Австрия, Арабские Эмираты, Армения, Бельгия, Бразилия, Великобритания, Германия, Гонконг, Греция, Дания, Ирландия, Испания, Италия, Канада, Латвия, Литва, Македония, Нидерланды, Норвегия, Польша, Португалия, Россия, США, Турция, Украина, Финляндия, Франция, Хорватия, Швейцария, Швеция, Эстония, Япония и другие
- Операционные системы: Windows10, Windows Server 2012/2016/2019/2022, Debian, CentOS, Ubuntu и любую другую из своего ISO-образа.

- Цены:
- Стандартные VPS/VDS от 600р/мес.
- Hi-CPU серверы от 900р/мес.

- Способы оплаты:
- Банковские карты и СБП (Visa/Mastercard/Мир и другие).
- Криптовалюта (Bitcoin, Litecoin, Dogecoin, BTC Cash, USDT и другие).
- Электронные кошельки (ЮMoney, QIWI, PerfectMoney и другие).

Список всех тарифов и автоматический заказ на сайте: plexus.host

Присоединяйтесь к нам и наслаждайтесь качественными услугами!

Базы данных » Помощь с прасингом сайта » Ноя. 17, 2024 21:59:14

Всем доброго времени дня и ночи, очень нужно спарсить данные одного из телграмм каталогов (tg каналы, а еще желательно даты регистрации/добавления их на сайт) https://tg-cat.com Буду безумно благодаерен любой помощи

Python для новичков » Юрий » Ноя. 17, 2024 13:17:18

подскажите материалы, курсы или что то еще для изучение Python с нуля

Python для новичков » Сеть на питон » Окт. 16, 2024 14:37:30

Коллеги добрый день!!!
есть некая простая нейронная сеть(4 входа,1 выход), задача спрогнозировать определенные величины по входным параметрам. Имеется csv файл с данными входными и выходными для обучения.
 import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from tensorflow import keras
from tensorflow.keras import layers
# Создание искусственных данных
data_size = 10000
np.random.seed(42)
# Генерация данных
data = {
    'ti': np.random.randint(0, 24, data_size),  # Вход 1
    'te': np.random.uniform(-30, 50, data_size),  # Вход 2
    'en': np.random.randint(0, 41, data_size),  # Вход 3
    'tem': np.random.uniform(40, 45, data_size),  # Вход 4
    'energy_consumption': None  # Выход
}
# Создание DataFrame
df = pd.DataFrame(data)
# Формирование зависимости: создание искусственных данных для потребления энергии
# На основании простого линейного уравнения с добавлением некоторого шума
df['energy_consumption'] = (
    50 + 20 * df['ti'] + 15 * df['en']
    - 0.5 * df['te '] + 5 * (df['tem'] - 40)
    + np.random.normal(0, 10, data_size)  # добавление случайного шума
)
# Разделение данных на признаки и целевую переменную
X1 = df[['ti', 'te', 'en', 'tem']]
y = df['energy_consumption']
# Разделение данных на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X1, y, test_size=0.2, random_state=42)
# Масштабирование признаков
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Создание модели нейросети
model = keras.Sequential([
    layers.Dense(64, activation='relu', input_shape=(X_train_scaled.shape[1],)),
    layers.Dense(32, activation='relu'),
    layers.Dense(1)  # Выходной слой, так как мы прогнозируем одно значение
])
# Компиляция модели
model.compile(optimizer='adam', loss='mean_squared_error')
# Обучение модели
model.fit(X_train_scaled, y_train, epochs=100, batch_size=32, validation_split=0.2)
# Оценка модели
loss = model.evaluate(X_test_scaled, y_test)
print(f"Тестовая потеря: {loss:.2f}")
# Прогнозирование значений на тестовых данных
y_pred = model.predict(X_test_scaled)
# Вывод первых 5 прогнозируемых значений
print("Первые 5 прогнозируемых значений:")
print(y_pred[:5].flatten())
# Пример использования модели для прогноза
h=[1, 2, 3, 4, 5, 6, 7, 8, 9,1]
t=[10, 20, 30, 40, 30, 30, 20, 20, 20,10]
e=[40, 40, 40, 40, 20, 20, 20, 20, 20,40]
tg=[45, 45, 45, 45, 45, 45, 45, 45, 45,45]
for i in range(10):
    sample_data = np.array([[h[i], t[i], e[i], tg[i]]])
    sample_data_scaled = scaler.transform(sample_data)
    predicted_consumption = model.predict(sample_data_scaled)
    print(f"Прогноз =',{h[i]},'te=',{t[i]},' en=',{e[i]},'tem: {predicted_consumption[0][0]:.2f}")
Обучение на реальных данных подгружаем данные в массивы из файлов, energy_consumption также подгружаем из файла.
1. Как определить размер динамического массива исходя из количества строк в фале( csv или хls в котором все данные будут в столбцах)
2. Процедура обучения остается такой-же ?
3. прикомпиляции выходит ошибка эC:\Users\Vechna\AppData\Local\Programs\Python\Python37\lib\site-packages\sklearn\base.py:451: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names “X does not have valid feature names, but” ?
Что еще можно улучшить в данной программе. Спасибо!
Может посоветуете что либо.

Центр помощи » ЦИКЛЫ. ТАБУЛИРОВАНИЕ ФУНКЦИЙ » Окт. 2, 2024 09:20:27

Помогите, пожалуйста, составить программу табулирования функции с шагом h, используя цикл с предусловием While .

Центр помощи » Помогите срешением проблемы » Сен. 29, 2024 17:08:09

Пытался активировать скрипт бота на питоне и выдает ошибку

Скрипт:
 import sqlite3
from aiogram import Bot, Dispatcher, types
from aiogram.utils import executor
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import FSMContext
from aiogram.contrib.fsm_storage.memory import MemoryStorage
API_TOKEN = 'xxxxx' # Замените на свой токен бота
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot, storage=MemoryStorage())
# Создание базы данных (если еще не создана)
db_name = 'mydatabase.db'
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
cursor.execute('''
    CREATE TABLE IF NOT EXISTS data (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        description TEXT
    )
''')
conn.commit()
conn.close()
# Обработчик команды /start
@dp.message_handler(commands=['start'])
async def start_handler(message: types.Message):
    await message.answer("Привет! Я бот для поиска информации в базе данных.\n\n"
                        "Введите поисковый запрос:")
# Обработчик ввода поискового запроса
@dp.message_handler()
async def search_handler(message: types.Message):
    search_term = message.text
    results = search_data(db_name, search_term)
    if results:
        await message.answer("Результаты поиска:")
        for row in results:
            await message.answer(f"ID: {row[0]}, Название: {row[1]}, Описание: {row[2]}")
    else:
        await message.answer("Ничего не найдено.")
# Функция поиска данных в базе данных
def search_data(db_name, search_term):
    conn = sqlite3.connect(db_name)
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM data WHERE name LIKE ? OR description LIKE ?", ('%' + search_term + '%', '%' + search_term + '%'))
    results = cursor.fetchall()
    conn.close()
    return results
if __name__ == "__main__":
    executor.start_polling(dp, skip_updates=True)

Ошибку которую выдает:
 from aiogram.utils import executor
ImportError: cannot import name 'executor' from 'aiogram.utils'

Python для новичков » Ошибка в Sublime Text » Сен. 26, 2024 12:11:59

Коллеги, добрый день! Начала проходить курсы по Python, выбрала для написания кода Sublime Text, подключила помощник аккорда. После написания кода выскакивает такая ошибка

/usr/local/bin/python3: can't find ‘__main__’ module in ‘/Users/macbookair/Desktop’

[cmd: ]



подскажите, пожалуйста, как ее решить. спасите! спасибо.

Инструментальные средства разработки » Codeum и блокировка  » Сен. 22, 2024 08:06:34

Добрый день товарищи. В pycharm решил установить плагин codium и столкнулся с ситуацией: Plugin “Codiumate - Code, test and review with confidence - by CodiumAI” was not installed: We are sorry, but we are currently unable to provide our products or services to you due to export control regulations.
Судя по всему, для России опять какие-то блокировки. VPN не помогает. Кто-то сталкивался? Может есть какие-то варианты решения этой проблемки.

Python для новичков » Подобие кейлоггера » Сен. 16, 2024 15:59:43

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

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

 from turtle import*
from tkinter import*
def com(event): event.keysym
click =1
def turtlemouv(event):
global click
click+=1
t.config(text = click)
w = Tk()
w.geometry('200x130')
w.bind("<Key>", turtlemouv)
t=Label (w,text="0", font="Arial 35")
t.pack()
w.mainloop()

Центр помощи » Потоки и вставка виджета » Июль 15, 2024 17:24:07

Добрый день!
Столкнулся с такой проблемой, через поток не хочет вставляться виджет (кнопка) в таблицу ListGrease. Помогите решить этот вопрос, спасибо!

 from form_main import Ui_MainWindow
from PyQt6 import QtWidgets, QtCore
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QTableWidgetItem
)
import sys
import time
import threading
class Window_main_form(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.potok1)
        self.pushButton_2.clicked.connect(self.potok2)
    def Timer(self):
        st = 0
        while True:
            time.sleep(0.3)
            win_main_form.lineEdit.setText(str(st))
            st += 1
    def potok1(self):
        thread = threading.Thread(target=self.Timer, daemon=True)
        thread.start()
    def potok2(self):
        thread = threading.Thread(target=self.potok2_2, daemon=True)
        thread.start()
    def potok2_2(self):
        self.ListGrease.setColumnCount(2)
        self.ListGrease.setRowCount(0)
        self.ListGrease.setHorizontalHeaderLabels(["-", "Дата"])
        self.ListGrease.resizeColumnsToContents()
        self.ListGrease.resizeColumnsToContents()
        self.ListGrease.setRowCount(self.ListGrease.rowCount() + 1)
        self.ListGrease.setRowCount(self.ListGrease.rowCount() + 1)
        self.ListGrease.setItem(0, 1, QTableWidgetItem(str("Текст")))
        pushButton = QtWidgets.QPushButton('X')
        pushButton.setMaximumSize(QtCore.QSize(35, 25))
        pushButton.clicked.connect(self.clik)
        self.ListGrease.setCellWidget(1, 0, QTableWidgetItem(pushButton)) # вот здесь ошибка
    def clik(self):
        print("Клик!")
if __name__ == '__main__':
    app = QApplication(sys.argv)
    win_main_form = Window_main_form()
    win_main_form.show()
    sys.exit(app.exec())

Центр помощи » автоматизация входа в инсту через тор » Июль 14, 2024 21:03:45

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

Python для новичков » Не вводится текст в поле запроса в chagpt. » Июнь 28, 2024 21:31:56

Как методом python ввести текст в строку промыта. Такой не работает

# Поиск элемента по его точному ID textarea = wait.until(EC.presence_of_element_located((By.XPATH,
'//*'))) log(“Текстовое поле найдено.”) log(“Атрибуты текстового поля:”) log(f“ID: {textarea.get_attribute('id')}”) log(f“Placeholder: {textarea.get_attribute('placeholder')}”) log(f“Class: {textarea.get_attribute('class')}”)

Python для новичков » pydirectinput не работает если какая то клавиша зажата » Июнь 26, 2024 11:30:02

import time
import pydirectinput
import keyboard
import ctypes
def macro():
user32 = ctypes.windll.user32
screen_width = user32.GetSystemMetrics(0)
screen_height = user32.GetSystemMetrics(1)
x = int(screen_width * 0.2) - 50
y = int(screen_height * 0.3)
pydirectinput.moveTo(x, y)

keyboard.add_hotkey('j', macro, suppress=True)
keyboard.wait()

когда зажата какая то клавиша не работает код,помогите пожалуйста как это можно исправить?

Django » Django publish profile » Май 23, 2024 22:24:32

Всем привет.
Есть запрос на помощь)
Есть шаблон в котором отображаются с разных моделей поля в профайл пользователя. Есть настройки на представления просмотра данных полей сторонним\другим пользователем в этом шаблоне. Поля включаем или выключаем для возможности просмотра другими пользователями.
Как лучше организовать пред просмотр своего профиля от другого пользователя зарегистрированного на сайте ?
Понимаю следующее: можно создать пользователя, по умолчанию выделить место в БД, для проверки, запрашивать его в представлении, через джава скрипт передавать его в шаблон и шаблон будет отображаться, как для стороннего пользователя. Но мне кажется это очень не безопасным с передачей пользователей.)))
Как возможно это организовать лучше? Только начинаю, могу писать много и долго, но безтолкого, к примеру создать ещё шаблон куда можно переходить, но это будет два одинаковых шаблона с разными if and or ==, в будущем будет беда… может есть у кого то какие то мысли на счёт моей просьбы в помощи? Может всё проще реализуется? Много искал, примеров не нашел… Заранее благодарочка)

Python для новичков » Написание цикла для нахождения ближайшей точки из массива » Май 10, 2024 11:38:55

Имеется следующий код:
 current_time = datetime.datetime.now().time() 
class Graph(object):
    def __init__(self, nodes, init_graph):
        self.nodes = nodes
        self.graph = self.construct_graph(nodes, init_graph)
        
    def construct_graph(self, nodes, init_graph):
        '''
        Этот метод обеспечивает симметричность графика. Другими словами, если существует путь от узла A к B со значением V, должен быть путь от узла B к узлу A со значением V.
        '''
        graph = {}
        for node in nodes:
            graph[node] = {}
        
        graph.update(init_graph)
        
        for node, edges in graph.items():
            for adjacent_node, value in edges.items():
                if graph[adjacent_node].get(node, False) == False:
                    graph[adjacent_node][node] = value
                    
        return graph
    
    def get_nodes(self):
        "Возвращает узлы графа"
        return self.nodes
    
    def get_outgoing_edges(self, node):
        "Возвращает соседей узла"
        connections = []
        for out_node in self.nodes:
            if self.graph[node].get(out_node, False) != False:
                connections.append(out_node)
        return connections
    
    def value(self, node1, node2):
        "Возвращает значение ребра между двумя узлами."
        return self.graph[node1][node2]
def dijkstra_algorithm(graph, start_node):
    unvisited_nodes = list(graph.get_nodes())
 
    # Мы будем использовать этот словарь, чтобы сэкономить на посещении каждого узла и обновлять его по мере продвижения по графику 
    shortest_path = {}
 
    # Мы будем использовать этот dict, чтобы сохранить кратчайший известный путь к найденному узлу
    previous_nodes = {}
 
    # Мы будем использовать max_value для инициализации значения "бесконечности" непосещенных узлов   
    max_value = sys.maxsize
    for node in unvisited_nodes:
        shortest_path[node] = max_value
    # Однако мы инициализируем значение начального узла 0  
    shortest_path[start_node] = 0
    
    # Алгоритм выполняется до тех пор, пока мы не посетим все узлы
    while unvisited_nodes:
        # Приведенный ниже блок кода находит узел с наименьшей оценкой
        current_min_node = None
        for node in unvisited_nodes: # Iterate over the nodes
            if current_min_node == None:
                current_min_node = node
            elif shortest_path[node] < shortest_path[current_min_node]:
                current_min_node = node
                
        # Приведенный ниже блок кода извлекает соседей текущего узла и обновляет их расстояния
        neighbors = graph.get_outgoing_edges(current_min_node)
        for neighbor in neighbors:
            tentative_value = shortest_path[current_min_node] + graph.value(current_min_node, neighbor)
            if tentative_value < shortest_path[neighbor]:
                shortest_path[neighbor] = tentative_value
                # We also update the best path to the current node
                previous_nodes[neighbor] = current_min_node
 
        # После посещения его соседей мы отмечаем узел как "посещенный"
        unvisited_nodes.remove(current_min_node)
    
    return previous_nodes, shortest_path
def print_result(previous_nodes, shortest_path, start_node, target_node):
    path = []
    node = target_node
    
    while node != start_node:
        path.append(node)
        node = previous_nodes[node]
 
   # Добавить начальный узел вручную
    path.append(start_node)
    
    result_text = "Найден следующий лучший маршрут с расстоянием {} км".format(shortest_path[target_node])
    result_text += "\n" +  " -> ".join(reversed(path))
    
 
    # Вставить результат в текстовое поле
    text_input.insert(END, result_text + "\n")
 
  
 
nodes = {"Склад": (43.356374, 132.072318), "Некрасовская": (43.128128, 131.910649), "3-я Рабочая": (43.123089, 131.924877), 
         "Центр": (43.115797, 131.885064), "Луговая": (43.128078, 131.940321), "Нивельского": (43.112586, 131.943152), "Нейбута": (43.116441, 131.955245), "ДВФУ": (43.025101, 131.894189)}
valuegor = list(nodes.keys())
etaj = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
 
  
 
#Координаты остановок
storage = (43.356374, 132.072318)
necra = (43.128128, 131.910649)
raboch = (43.123089, 131.924877)
center = (43.115797, 131.885064)
lugovaya = (43.128078, 131.940321)
nivels = (43.112586, 131.943152)
newboot = (43.116441, 131.955245)
DVFU = (43.025101, 131.894189)
 
init_graph = {}
for node in nodes:
    init_graph[node] = {}
 
if current_time < datetime.time(12, 0, 0):
        init_graph["Склад"]["Некрасовская"] = round(GD(nodes["Склад"], nodes["Некрасовская"]).km + 5, 2)
        init_graph["Склад"]["Центр"] = round(GD(nodes["Склад"], nodes["Центр"]).km + 5, 2)
        init_graph["Некрасовская"]["Нивельского"] = round(GD(nodes["Некрасовская"], nodes["Нивельского"]).km + 5, 2)
        init_graph["Некрасовская"]["3-я Рабочая"] = round(GD(nodes["Некрасовская"], nodes["3-я Рабочая"]).km + 5, 2)
        init_graph["3-я Рабочая"]["Нейбута"] = round(GD(nodes["3-я Рабочая"], nodes["Нейбута"]).km + 5, 2)
        init_graph["3-я Рабочая"]["ДВФУ"] = round(GD(nodes["3-я Рабочая"], nodes["ДВФУ"]).km + 5, 2)
        init_graph["3-я Рабочая"]["Луговая"] = round(GD(nodes["3-я Рабочая"], nodes["Луговая"]).km + 5, 2)
        init_graph["ДВФУ"]["Нейбута"] = round(GD(nodes["ДВФУ"], nodes["Нейбута"]).km + 5, 2)
        init_graph["Луговая"]["Нивельского"] = round(GD(nodes["Луговая"], nodes["Нивельского"]).km + 5, 2)
        init_graph["Луговая"]["ДВФУ"] = round(GD(nodes["Луговая"], nodes["ДВФУ"]).km + 5, 2)
elif current_time < datetime.time(18, 0, 0):
        init_graph["Склад"]["Некрасовская"] = round(GD(nodes["Склад"], nodes["Некрасовская"]).km + 6, 2)
        init_graph["Склад"]["Центр"] = round(GD(nodes["Склад"], nodes["Центр"]).km + 5, 2)
        init_graph["Некрасовская"]["Нивельского"] = round(GD(nodes["Некрасовская"], nodes["Нивельского"]).km + 6, 2)
        init_graph["Некрасовская"]["3-я Рабочая"] = round(GD(nodes["Некрасовская"], nodes["3-я Рабочая"]).km + 6, 2)
        init_graph["3-я Рабочая"]["Нейбута"] = round(GD(nodes["3-я Рабочая"], nodes["Нейбута"]).km + 6, 2)
        init_graph["3-я Рабочая"]["ДВФУ"] = round(GD(nodes["3-я Рабочая"], nodes["ДВФУ"]).km + 6, 2)
        init_graph["3-я Рабочая"]["Луговая"] = round(GD(nodes["3-я Рабочая"], nodes["Луговая"]).km + 6, 2)
        init_graph["ДВФУ"]["Нейбута"] = round(GD(nodes["ДВФУ"], nodes["Нейбута"]).km + 6, 2)
        init_graph["Луговая"]["Нивельского"] = round(GD(nodes["Луговая"], nodes["Нивельского"]).km + 6, 2)
        init_graph["Луговая"]["ДВФУ"] = round(GD(nodes["Луговая"], nodes["ДВФУ"]).km + 6, 2)
else:
        init_graph["Склад"]["Некрасовская"] = round(GD(nodes["Склад"], nodes["Некрасовская"]).km + 5, 2)
        init_graph["Склад"]["Центр"] = round(GD(nodes["Склад"], nodes["Центр"]).km + 5, 2)
        init_graph["Некрасовская"]["Нивельского"] = round(GD(nodes["Некрасовская"], nodes["Нивельского"]).km, 2)
        init_graph["Некрасовская"]["3-я Рабочая"] = round(GD(nodes["Некрасовская"], nodes["3-я Рабочая"]).km, 2)
        init_graph["3-я Рабочая"]["Нейбута"] = round(GD(nodes["3-я Рабочая"], nodes["Нейбута"]).km, 2)
        init_graph["3-я Рабочая"]["ДВФУ"] = round(GD(nodes["3-я Рабочая"], nodes["ДВФУ"]).km, 2)
        init_graph["3-я Рабочая"]["Луговая"] = round(GD(nodes["3-я Рабочая"], nodes["Луговая"]).km, 2)
        init_graph["ДВФУ"]["Нейбута"] = round(GD(nodes["ДВФУ"], nodes["Нейбута"]).km, 2)
        init_graph["Луговая"]["Нивельского"] = round(GD(nodes["Луговая"], nodes["Нивельского"]).km, 2)
        init_graph["Луговая"]["ДВФУ"] = round(GD(nodes["Луговая"], nodes["ДВФУ"]).km, 2)
 
 
 
 
 
 
 
 
 
#КОД МЕНЮ
def close_window():
    root.destroy()
 
def save_to_file():
    text_to_save = text_input.get("1.0", END)
    file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
    if file_path:
        try:
            with open(file_path, 'w', encoding='utf-8') as file:
                file.write(text_to_save)
        except Exception as e:
            print(f"An error occurred while saving the file: {e}")
 
def open_file():
    file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")])
    if file_path:
        try:
            with open(file_path, 'r', encoding='utf-8') as file:
                text = file.read()
                text_input.delete(1.0, END)
                text_input.insert(END, text)
        except Exception as e:
            print(f"An error occurred while opening the file: {e}")
 
def change_button_color():
    color = colorchooser.askcolor(title="Choose Button Color")
    if color[1]:  # Check if a color was chosen
        save_button.config(bg=color[1])
        open_button.config(bg=color[1])
        exit_button.config(bg=color[1])
        slovo_button.config(bg=color[1])
        delete_button.config(bg=color[1])
        run_button.config(bg=color[1])
 
def change_menu_color():
    color = colorchooser.askcolor(title="Choose Button Color")
    if color[1]:  # Check if a color was chosen
        text_input.config(bg=color[1])
        text1_input.config(bg=color[1])
        root.config(bg=color[1])
       
def current_time():
    t = time.localtime() 
    current_time = time.strftime("%H:%M:%S", t) 
    text1_input.delete(1.0, END)
    text1_input.insert(END, current_time)
 
#Выбор пункта доставки
selected_value = None
def select_value():
    global selected_value
    selected_value = combo.get()
    print(f"Выбрано значение: {selected_value}")
 
#Выбор этажа
selected_value1 = None
def select_value1():
    global selected_value1
    selected_index = combo1.current()
    selected_value1 = etaj[selected_index]
    print("Selected value:", selected_value1)
 
#Выбор стартовой точки
selected_value2 = None
def select_value2():
    global selected_value2
    selected_value2 = combo2.get()
    print(f"Выбрано значение: {selected_value2}")
 
 
 
def clear_text():
    text_input.delete(1.0, END)
    text1_input.delete(1.0, END)
 
 
 
root = Tk()
root.title("Меню")
root.geometry("1920x1080")
root.option_add("*tearOff", False)
 
main_menu = Menu()
file_menu = Menu()
setting_menu = Menu()
selected_font = tk.StringVar(root)
 
main_menu.add_cascade(label="Файл", menu=file_menu)
main_menu.add_cascade(label="Настройки", menu=setting_menu)
file_menu.add_command(label="Выход", command=close_window)
setting_menu.add_command(label="Выбор цвета кнопок", command = change_button_color)
setting_menu.add_command(label="Выбор цвета меню", command = change_menu_color)
 
 
root.config(menu=main_menu)
 
text_input = Text(root, wrap="word", height=30, width=120, font = ("Arial", 16))  # Указываем высоту и ширину текстового поля
text_input.grid(row=0, column=0, rowspan=3, padx=10, pady=10)
 
#Подпись для обозначения цены
label = Label(root, text="Стоимость доставки", font = ("Arial", 16))
label.place(x = 340, y = 777)
 
text1_input = Text(root, wrap="word", height=1, width=25 , font = ("Arial", 16))  
text1_input.grid(row=4, column=0, rowspan=1, padx=0, pady=0)
 
#ввод этажа для доставки
label1 = Label(root, text="Этаж доставки", font = ("Arial", 16))
label1.place(x = 340, y = 807)
#Выбор этажа
combo1 = ttk.Combobox(root, values=etaj)
combo1['values'] = etaj
combo1.grid(row=5, column=0, padx=0, pady=0)
#кнопка Выбора этажа
button_etaj = Button(root, text="Выбрать этаж", command=select_value1)
button_etaj.place(x = 840, y = 807)
 
 
save_button = Button(root, text="Сохранить", command=save_to_file)
save_button.grid(row=0, column=1, padx=10, pady=5)
 
open_button = Button(root, text="Загрузить", command=open_file)
open_button.grid(row=1, column=1, padx=10, pady=5)
 
#Кнопка выхода
exit_button = Button(root, text="Выход", command=close_window)
exit_button.grid(row=6, column=0, padx=10, pady=5)
 
#Выбор пункта доставки
combo = ttk.Combobox(root, values=valuegor)
combo.grid(row=2, column=2, padx=10, pady=5)
combo.bind("<<ComboboxSelected>>", select_value)
 
 
#Выбор стартовой точки
#combo2 = ttk.Combobox(root, values=nodes)
#combo2.grid(row=3, column=2, padx=10, pady=5)
#combo2.bind("<<Combobox2Selected>>", select_value2)
 
slovo_button = Button(root, text="Выбрать", command=select_value)
slovo_button.grid(row=2, column=1, padx=10, pady=5)
 
#slovo1_button = Button(root, text="Выбрать", command=select_value2)
#slovo1_button.grid(row=3, column=1, padx=10, pady=5)
 
 
delete_button = Button(root, text="Очистить", command=clear_text)
delete_button.grid(row=4, column=1, padx=10, pady=5)
 
 
#Сбор остановок в массив
array = []
def add_value():
    value = combo.get()
    array.append(value)
    #text_input.delete(0, tk.END)
 
def display_array():
    text_input.config(state=tk.NORMAL)
    #text_input.delete(1.0, tk.END)
    text_input.insert(tk.END, "Текущий список остановок: ")
    text_input.insert(tk.END, ', '.join(array))
    #text_input.config(state=tk.DISABLED)
    
 
add_button = tk.Button(root, text="Добавить значение", command=add_value)
add_button.grid(row=0, column=2)
 
display_button = tk.Button(root, text="показать массив", command=display_array)
display_button.grid(row=0, column=3)
#Конец этой части кода
 
 
 
 
#Функция запуска алгоритма Дейкстры
def run_dijkstra():
    global selected_value
    global selected_value1
    global selected_value2
    route_value = 0
 
 
    if selected_value:
      for index, znach in enumerate(array):
        previous_index = index -1
        if index == 0:
            graph = Graph(nodes, init_graph)
            previous_nodes, shortest_path = dijkstra_algorithm(graph=graph, start_node= selected_value)
            print_result(previous_nodes, shortest_path, start_node= selected_value, target_node=znach)
            route_value += shortest_path[znach]
            
 
 
        elif index < len(array):
            previous_znach = array[previous_index]
            graph = Graph(nodes, init_graph)
            previous_nodes, shortest_path = dijkstra_algorithm(graph=graph, start_node= previous_znach)
            print_result(previous_nodes, shortest_path, start_node= previous_znach, target_node=znach)
            route_value += shortest_path[znach]
 
 
 
    
    #Рассчет стоимости
    traffic_value = 150
    if route_value > 30:
        traffic_value = 150 * route_value * selected_value1
        text1_input.insert(END, traffic_value)
    else:
        text1_input.insert(END, traffic_value + 150)
 
    text_input.insert(END, route_value)
    #text_input.insert(END, result_text)
    #Конец рассчета стоимости
 
# Создайте новую кнопку для запуска алгоритма Дейкстры
run_button = Button(root, text="Запустить Дейкстру", command=run_dijkstra)
run_button.grid(row=4, column=2, padx=10, pady=5)
 
root.mainloop()
Весь этот код это реализация алгоритма Дейкстры для нахождения кратчайших маршрутов между остановками. Он сделан таким образом, чтобы в массив array заносился пул остановок, и до каждой из них будет рассчитываться кратчайшее расстояние, а также будут выводится остановки которые лежат на пути к ним.

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

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

Мне нужна помощь с тем как это можно реализовать. Если у вас есть идеи как это можно сделать лучше, с радостью их прочту.