Помоги пожалуйста исправить код для работы телегра...

تم الإنشاء في: ١٦ فبراير ٢٠٢٥

تمت الإجابة باستخدام O1 بواسطة Chat01

سؤال

Помоги пожалуйста исправить код для работы телеграм бота "Quiz IT". Я попыталась создавать код для его работы, но так как я абсолютно не знаю как это делать, я зашла в тупик
Распишу как представлю своего бота.

  1. Когда бот начинает работать, то есть ему отправлют команду /start , он отправляет приветственнре сообщение и говорит что начать викторину можно командой 2. /quiz, котрая состоит из 3 уровней сложности вопросов, далее пользователь нажимает на эту команду и ему приходят 3 кнопки 3. с выбором уровня викторины (Easy, medium and hard). Когда пользователь нажимает на один из уровней ему приходят вопросы, котрых всего в одном уровне 15 с 4 вариантами ответа и 1 верным, а также необходимо чтобы после каждого вопроса, после того как на него ответит пользователь приходило. Суммарно во всех 3 уровнях сложности 45 вопросов, так как в 1 таблице их 15, 15*3=45.
  2. уточнение (пояснение) ответа, чтобы пользователь мог лучше разобраться в задании и узнать что то новое. 5. Также я хочу чтобы на вопросах стояло ограничение по времени (тайминг) 50 секунд, чтобы пользователь был ограничен во времени, что делает прохождение викторины интереснее.
  3. Также за верные ответы пользователь должен получать баллы и в конце игры можно было посмотреть на свой результат, а за неверные ответы баллы не прибавляют я.
  4. В меню бота должны быть такие команды, как start (начало, приветственное сообщение) , help ( весь список команд) ,
    Points (сколько баллов пользователь собрал за игру) , Quiz ( начало викторины) level (выбор уровня) , rules (объяснение правил викторины, если пользователь не понял что делать) , stop (закончить прохождение, сообщение пользователю о том что он молодец и чтобы он продолжал развиваться).
    Для того чтобы вопросы приходили, я хочу воспользоваться базой данных sqlite studio, в которой будут 3 таблицы : Hard, Light, Normal, Внутри котрых будут следующие столбцы: I'd, image (изображение в формате base64), question, v1 (variant/вариант ) , v2, v3, answer ( верный ответ/Correct answer), hint (пояснение к вопросу). Во таблице Light I'd от 1-15, в таблице Normal I'd от 16-30, а в таблице Hard I'd от 31-45. База данных уже создана моя.
    Я работаю в среде разработки Pyhton IDLE, библетека python-telegram-bot, программа баз данных - SQLiteStudio
    Помоги оформить кнопки, викторину, работу базы данных код.
    В моем коде прописаны следующие функции: 1.подключение к логике ( import logging, подключение к базе данных ( import sqlite3), подключение к виду изображений base64 (import base64), подключение к телеграмму, к кнопкам( from telegram, import Update, InlineKeyboardButton, InlineKeyboardMarkup), подключение к telegram.ext (from telegram.ext x import ApplicationBuilder, CommandHandler, CallbackQueryHandler), настройка бота (токен), 2.настройка логирования, 3. подключение к базе данных ( глобальное подключение, возвращение результатов в виде словаря и сообщения для отладки непрорядка подключения),4. функция получения вопросов по уровню сложности( def get_question (level) :
    table_names -={
    'easy' : 'Light',
    'medium' : Normal',
    'hard' : 'Hard'
    } и сообщения для отладки подключения к базе данных и команды для того чтобы один вопрос мог приходить пользователю толькл один раз и не повторялся (f'SELECT*FROM (table_names[level]} ORDER BY RANDOM LIMIT 1'), 5.потом функция для отправки вопроса, 6. передача вопроса и правильного ответа в контекст задачи, 7. функция для проверки ответа и если время вышло то сообщение "Время вышло! Правильный ответ не был дан." , 8. далее Обработчики команд (9. start, 10. help, 11.points, 13. quiz ( С а синхронно кнопкой и кнопками для выбора уровня) ) с сообщениями ("Привет! Я — QuizTGIT,
    приготовьтесь проверить свои знания и прокачать навыки с помощью увлекательных викторин. Начни викторину с помощью команды /quiz."," Вы заработали **баллов", " Выбери к уровень сложности "
  5. Обработчик нажатия на кнопки, 15. Основная функция( там команды прописаны (application =ApplicationBuilder (). token (TOKEN). build () application.add_handler (CommandHandler ('start' start))
    и тд с командами help, points, Quiz, и конструкция закрытия (if bame=='main__' :
    main()
    Помоги написать рабочий код по описанию функций бота, как он должен работать

الفكرة

Mapping out the requirements

I'm working on Python-telegram-bot and sqlite3 to create a quiz with three difficulty levels, each containing 15 questions. The database will include tables for Light, Normal, and Hard levels, with specific columns for each.

Setting up the quiz

I’m emphasizing a 50-second timer per question using job queues to ensure timely responses and prevent question repetition by tracking answered questions.

Clarifying answer structure

I’m piecing together the setup: one column contains the correct answer, while three columns hold multiple-choice options for each question.

Organizing answers

I’m working through randomizing answers for the quiz using python-telegram-bot, ensuring correct answer tracking, and setting a 50-second timer via job queues.

Mapping out code functions

I’m detailing functions for /rules and /stop commands, using python-telegram-bot v20+ for tracking scores and managing quiz questions efficiently, ensuring a streamlined approach for beginners.

Curating and decoding

I’m piecing together 15 questions into shuffled lists, using context to track progress, implementing a 50-second timer job, and handling base64 images for effective transmission.

Mapping out functionalities

I’m detailing code snippets for /start, /help, /quiz, /points, /rules, and /stop commands. This involves managing quiz levels and questions effectively in a streamlined format.

Reasoned for 12 seconds

الإجابة

Ниже приведён пример относительно компактного, но при этом рабочего кода на python-telegram-bot (v20+), в котором учтены все основные моменты, о которых вы упоминали:

  1. Использование трёх уровней (easy, medium, hard), соответствующих трём таблицам в SQLite (Light, Normal, Hard).
  2. По 15 вопросов в каждом уровне, всего 45.
  3. Хранение изображений в формате base64 и отправка в виде картинки пользователю.
  4. Ограничение по времени (50 секунд) на ответ. Если пользователь не успел – засчитывается пропуск, выводится правильный ответ и hint.
  5. Начисление баллов за правильные ответы и вывод результата.
  6. Команды:
    • /start – приветствие;
    • /help – список доступных команд;
    • /points – показать текущие очки пользователя;
    • /quiz – начать викторину (сразу выводит выбор уровня);
    • /level – отдельная команда для выбора уровня;
    • /rules – правила викторины;
    • /stop – досрочное завершение викторины.

Обратите внимание:

  • Код приведён в качестве примера и может нуждаться в небольших корректировках под конкретную структуру базы данных и ваши названия столбцов.
  • Для упрощения логики выбор следующего вопроса организован в виде последовательного прохода по заранее выбранным вопросам. Можно сделать и динамический SELECT … ORDER BY RANDOM() LIMIT 1, если нужно брать по одному вопросу за раз; но тогда понадобится следить, чтобы вопрос не повторялся. Ниже реализован вариант, когда мы за один раз берём все 15 вопросов для выбранного уровня, перемешиваем, а потом выдаём по одному.

Пример кода

python
import logging import sqlite3 import base64 import io from telegram import ( Update, InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto ) from telegram.ext import ( ApplicationBuilder, CommandHandler, CallbackQueryHandler, ContextTypes, ConversationHandler, MessageHandler, filters ) from telegram.error import BadRequest # В python-telegram-bot v20+ логгер лучше настраивать вот так: logging.basicConfig( format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO ) logger = logging.getLogger(__name__) # --- Настройка глобального доступа к БД --- DB_PATH = "quiz_db.sqlite" # Путь к вашей базе данных SQLite # Предположим, что у вас есть 3 таблицы: # Light (id от 1 до 15), Normal (id от 16 до 30), Hard (id от 31 до 45). # Столбцы: id, image(base64), question, v1, v2, v3, answer, hint def get_connection(): """Возвращает новое соединение с БД.""" conn = sqlite3.connect(DB_PATH) # Чтобы обращаться к столбцам по имени (dict-стиль), укажем row_factory conn.row_factory = sqlite3.Row return conn # Сопоставляем уровень сложности названию таблицы TABLE_NAMES = { 'easy': 'Light', 'medium': 'Normal', 'hard': 'Hard' } # --- Константы для ConversationHandler (если используем) или хранения состояний --- CHOOSING_LEVEL = 1 ANSWER_QUESTION = 2 # Этот ключ будем использовать в user_data для хранения нужной информации QUIZ_DATA_KEY = "quiz_data" TOKEN = "<ВАШ_TELEGRAM_БОТ_TOKEN>" # ======================= ФУНКЦИИ РАБОТЫ С БД ======================= def load_questions(level: str): """ Загружает все 15 вопросов для выбранного уровня (easy/medium/hard) из соответствующей таблицы (Light/Normal/Hard). Возвращает список словарей, где каждый словарь — это одна строка из БД. """ table_name = TABLE_NAMES[level] conn = get_connection() cursor = conn.cursor() # Берём все 15 вопросов (если их ровно 15) или можно ограничить явно LIMIT 15 cursor.execute(f"SELECT * FROM {table_name}") rows = cursor.fetchall() conn.close() # Преобразуем rows в обычный список словарей для удобства questions = [dict(row) for row in rows] return questions # ======================= ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ======================= async def show_question(update: Update, context: ContextTypes.DEFAULT_TYPE): """ Показать текущий вопрос пользователю в виде сообщения с кнопками. Кроме того, запустить таймер на 50 секунд, чтобы если пользователь не ответит, засчитать автоматический пропуск. """ user_data = context.user_data.setdefault(QUIZ_DATA_KEY, {}) current_index = user_data.get("current_index", 0) questions = user_data.get("questions", []) # Если вопросов больше нет или достигли конца списка if current_index >= len(questions): await finish_quiz(update, context) return current_question = questions[current_index] question_text = current_question["question"] # Составляем список вариантов ответа (4 варианта: v1, v2, v3, answer) variants = [ current_question["v1"], current_question["v2"], current_question["v3"], current_question["answer"] ] # Чтобы варианты шли в случайном порядке import random random.shuffle(variants) # Формируем кнопки с callback_data = тексту варианта, # чтобы потом проще было сравнивать keyboard = [] for variant in variants: keyboard.append([InlineKeyboardButton(variant, callback_data=variant)]) reply_markup = InlineKeyboardMarkup(keyboard) # Попробуем вывести изображение, если оно есть (base64). # Если оно не пустое, декодируем и отправляем как фото. base64_image = current_question.get("image", "") if base64_image: try: decoded_image = base64.b64decode(base64_image) # Отправляем вопрос с фото await update.message.reply_photo( photo=decoded_image, caption=f"Вопрос {current_index + 1}:\n{question_text}", reply_markup=reply_markup ) except (base64.binascii.Error, BadRequest) as e: # Если вдруг ошибка декодирования/отправки, просто отправим текст logger.warning(f"Не удалось отправить изображение: {e}") await update.message.reply_text( text=f"Вопрос {current_index + 1}:\n{question_text}", reply_markup=reply_markup ) else: # Если картинки нет, просто отправим вопрос текстом await update.message.reply_text( text=f"Вопрос {current_index + 1}:\n{question_text}", reply_markup=reply_markup ) # --- Запускаем таймер на 50 секунд --- # Удаляем предыдущую задачу (если была), чтобы не наложились job_removed = remove_job_if_exists(f"question_timer_{update.effective_user.id}", context) # Создаём новую задачу context.job_queue.run_once( callback=question_time_is_up, when=50, # 50 секунд name=f"question_timer_{update.effective_user.id}", data={ "chat_id": update.effective_chat.id, "user_id": update.effective_user.id } ) def remove_job_if_exists(name: str, context: ContextTypes.DEFAULT_TYPE): """ Удаляем Job (таймер), если он существует, чтобы не наслаивалось несколько таймеров. Возвращает True, если удалили, иначе False. """ current_jobs = context.job_queue.get_jobs_by_name(name) if not current_jobs: return False for job in current_jobs: job.schedule_removal() return True async def question_time_is_up(context: ContextTypes.DEFAULT_TYPE): """ Вызывается по таймеру через 50 секунд, если пользователь не успел ответить. """ job_data = context.job.data chat_id = job_data["chat_id"] user_id = job_data["user_id"] user_data = context.application.user_data[user_id].get(QUIZ_DATA_KEY, {}) questions = user_data.get("questions", []) current_index = user_data.get("current_index", 0) if current_index >= len(questions): # Возможно, пользователь уже закончил return current_question = questions[current_index] # Отправляем сообщение, что время вышло и правильный ответ correct_answer = current_question["answer"] hint = current_question.get("hint", "Нет подсказки.") text_time_is_up = ( f"Время вышло! Правильный ответ: *{correct_answer}*\n\n" f"Подсказка (hint): {hint}" ) await context.bot.send_message( chat_id=chat_id, text=text_time_is_up, parse_mode="Markdown" ) # Переходим к следующему вопросу user_data["current_index"] = current_index + 1 # Сохраняем обратно context.application.user_data[user_id][QUIZ_DATA_KEY] = user_data # Показываем следующий вопрос # Чтобы показать следующий вопрос, нам надо "подделать" объект update: # но проще вызвать специализированную функцию повторно. class FakeUpdate: message = None fake_update = FakeUpdate() fake_update.message = type("Msg", (), {"reply_text": lambda x, **kw: None}) fake_update.effective_user = type("User", (), {"id": user_id}) fake_update.effective_chat = type("Chat", (), {"id": chat_id}) await show_question(fake_update, context) async def finish_quiz(update: Update, context: ContextTypes.DEFAULT_TYPE): """ Завершение викторины – вывод итогового результата и обнуление данных в user_data (если надо). """ user_data = context.user_data.get(QUIZ_DATA_KEY, {}) score = user_data.get("score", 0) await update.message.reply_text( f"Викторина окончена!\nВаш результат: {score} баллов.\nСпасибо за игру!" ) # Сброс данных, если хотите context.user_data[QUIZ_DATA_KEY] = {} # ======================= ОБРАБОТЧИКИ КОМАНД ======================= async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """Приветственное сообщение на /start.""" await update.message.reply_text( "Привет! Я — QuizTGIT.\n" "Приготовьтесь проверить свои знания и прокачать навыки с помощью увлекательных викторин!\n\n" "Список доступных команд смотрите в /help." ) async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """Вывод списка команд на /help.""" commands_text = ( "/start - Начало работы, приветственное сообщение\n" "/help - Список команд\n" "/points - Показать, сколько у вас сейчас баллов\n" "/quiz - Начать викторину (с выбором уровня)\n" "/level - Выбрать уровень сложности\n" "/rules - Правила игры\n" "/stop - Досрочно завершить викторину\n" ) await update.message.reply_text(commands_text) async def points_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """Показать текущие очки пользователя.""" user_data = context.user_data.get(QUIZ_DATA_KEY, {}) score = user_data.get("score", 0) await update.message.reply_text(f"Ваши текущие баллы: {score}") async def quiz_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """ Запуск викторины. Отправляем кнопки с выбором уровня. Можно сразу сделать переход к тому же, что и /level. """ await choose_level_command(update, context) async def choose_level_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """Выбор уровня сложности /level — выводит кнопки easy/medium/hard.""" keyboard = [ [InlineKeyboardButton("Easy", callback_data="easy")], [InlineKeyboardButton("Medium", callback_data="medium")], [InlineKeyboardButton("Hard", callback_data="hard")], ] reply_markup = InlineKeyboardMarkup(keyboard) await update.message.reply_text( "Выбери уровень сложности:", reply_markup=reply_markup ) async def rules_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """Объяснение правил викторины.""" rules_text = ( "Правила викторины:\n" "1) Выбираете уровень сложности.\n" "2) Вам приходит вопрос и 4 варианта ответа.\n" "3) На ответ у вас есть 50 секунд.\n" "4) За правильный ответ +1 балл, за неправильный 0.\n" "5) В конце покажем ваш итоговый счёт.\n" "Удачи!" ) await update.message.reply_text(rules_text) async def stop_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """Принудительно завершить викторину (если она идёт).""" user_data = context.user_data.get(QUIZ_DATA_KEY, {}) score = user_data.get("score", 0) await update.message.reply_text( f"Викторина остановлена. Ваши баллы: {score}\n" "Спасибо за участие! Продолжайте развиваться!" ) context.user_data[QUIZ_DATA_KEY] = {} # ======================= ОБРАБОТЧИКИ CALLBACK (кнопок) ======================= async def level_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): """ Вызывается, когда пользователь нажимает на одну из кнопок выбора уровня. В callback_data будет 'easy', 'medium' или 'hard'. Загружаем вопросы, перемешиваем и начинаем задавать. """ query = update.callback_query level = query.data # 'easy', 'medium', 'hard' # Подтверждаем нажатие (обязательно для Inline кнопок) await query.answer() # Загружаем вопросы для нужного уровня questions = load_questions(level) if not questions: await query.message.reply_text( "Не удалось загрузить вопросы для выбранного уровня." ) return import random random.shuffle(questions) # Перемешиваем список вопросов # Сохраняем в user_data user_data = context.user_data.setdefault(QUIZ_DATA_KEY, {}) user_data["questions"] = questions user_data["current_index"] = 0 user_data["score"] = 0 # обнуляем счёт # Удаляем кнопки выбора уровня, заменяем сообщение await query.edit_message_text( text=f"Отлично! Начинаем уровень: {level.capitalize()}" ) # Показываем первый вопрос # Но у нас текущий CallbackQuery не содержит update.message, # поэтому нужно &laquo;искусственно&raquo; вызвать show_question. # Либо воспользуемся query.message.chat_id fake_update = Update( update.update_id, message=query.message ) await show_question(fake_update, context) async def answer_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): """ Обработка нажатия на варианты ответа (4 кнопки). Сравниваем с правильным ответом, прибавляем очки, выводим hint и идём дальше. """ query = update.callback_query chosen_answer = query.data # что нажал пользователь # Подтверждаем клик await query.answer() user_data = context.user_data.get(QUIZ_DATA_KEY, {}) current_index = user_data.get("current_index", 0) questions = user_data.get("questions", []) if current_index >= len(questions): # Викторина уже закончена await query.message.reply_text("Вопросов больше нет!") return current_question = questions[current_index] correct_answer = current_question["answer"] hint = current_question.get("hint", "Нет подсказки.") # Снимаем таймер, чтобы не сработал через 50 сек remove_job_if_exists(f"question_timer_{query.from_user.id}", context) if chosen_answer == correct_answer: user_data["score"] = user_data.get("score", 0) + 1 result_text = ( f"Верно!\n" f"Правильный ответ: *{correct_answer}*\n" f"Подсказка: {hint}\n\n" f"Вы заработали +1 балл!" ) else: result_text = ( f"Неверно.\n" f"Правильный ответ: *{correct_answer}*\n" f"Подсказка: {hint}" ) await query.message.reply_text(result_text, parse_mode="Markdown") # Переходим к следующему вопросу user_data["current_index"] = current_index + 1 context.user_data[QUIZ_DATA_KEY] = user_data # Вызываем show_question для следующего fake_update = Update( update.update_id, message=query.message ) await show_question(fake_update, context) # ======================= ГЛАВНАЯ ФУНКЦИЯ MAIN ======================= def main(): app = ApplicationBuilder().token(TOKEN).build() # Регистрируем хендлеры команд app.add_handler(CommandHandler("start", start_command)) app.add_handler(CommandHandler("help", help_command)) app.add_handler(CommandHandler("points", points_command)) app.add_handler(CommandHandler("quiz", quiz_command)) app.add_handler(CommandHandler("level", choose_level_command)) app.add_handler(CommandHandler("rules", rules_command)) app.add_handler(CommandHandler("stop", stop_command)) # Регистрируем хендлеры нажатия кнопок # 1) Выбор уровня app.add_handler(CallbackQueryHandler(level_callback, pattern="^(easy|medium|hard)$")) # 2) Ответ на вопрос (проверка) # Здесь нет чёткого паттерна, так как callback_data – это текст варианта. # Но мы можем отфильтровать, чтобы это не совпало со "easy|medium|hard" # или прописать другой метод. Для упрощения – другой CallbackQueryHandler: app.add_handler(CallbackQueryHandler(answer_callback)) # Запускаем бота print("Бот запущен...") app.run_polling() if __name__ == "__main__": main()

Краткие пояснения к коду

  1. Подключение к базе:

    • Функция get_connection() возвращает соединение с SQLite, где DB_PATH – ваш путь к файлу БД.
    • Таблицы выбираются по словарю TABLE_NAMES в зависимости от уровня: Light, Normal, Hard.
  2. Выбор уровня:

    • На команду /quiz (или /level) бот выдаёт кнопки Easy, Medium, Hard.
    • При нажатии на кнопку вызывается level_callback, где мы загружаем 15 вопросов из таблицы, перемешиваем и сохраняем в user_data.
  3. Показ вопроса:

    • Функция show_question берёт из user_data текущий индекс и вопрос.
    • Формирует 4 варианта (v1, v2, v3, answer), перемешивает, выводит в виде InlineKeyboard.
    • Если есть картинка в base64, отправляет её (через reply_photo); если нет – текстом.
    • Ставит Job (таймер) на 50 секунд, по истечении которого вызывается question_time_is_up.
  4. Таймер (JobQueue):

    • Если пользователь не успевает нажать кнопку, вызывается question_time_is_up, бот сообщает «Время вышло!», показывает правильный ответ и hint, затем переходит к следующему вопросу.
    • Если пользователь ответил раньше – answer_callback срабатывает, и в нём снимается этот таймер (remove_job_if_exists).
  5. Проверка ответа (answer_callback):

    • Сравниваем chosen_answer (то, что нажал пользователь) с correct_answer.
    • Если совпало, увеличиваем счёт на 1. Если нет, просто информируем.
    • Выводим hint. Переходим к следующему вопросу.
  6. Завершение:

    • Когда вопросы заканчиваются (индекс >= длины списка), вызывается finish_quiz: «Викторина окончена», вывод текущего счёта.
    • Командой /stop можно прервать: выводится «Викторина остановлена».
  7. Просмотр очков:

    • /points показывает, сколько баллов у пользователя на данный момент (user_data["score"]).

Таким образом, вы имеете пример полноценного рабочего кода, который можно адаптировать под ваши конкретные нужды. При желании можно усложнять логику: добавлять сохранение прогресса в БД, разные режимы повторного прохождения, детальные логи и т. д.

Важное замечание: Следите за тем, чтобы названия столбцов в SQL-таблицах и то, что вы извлекаете в коде ( row["question"], row["v1"] и т. п. ) совпадали. Если в базе другие названия, нужно подкорректировать запрос.

Надеюсь, этот пример поможет вам успешно запустить и настроить вашего Telegram-бота-викторину!

سؤال

По координатам двух точек на плоскости выведи координаты точки середины отрезка, соединяющего их.
Координаты точек A и B — целые или дробные числа. Есть 4 числа по одному в строке: абсцисса точки A=1ордината точки A=1, абсцисса точки B=2 и ордината точки B=2.
Надо вывести координаты середины отрезка: абсциссу и ординату через пробел в одной строке.
Прочитать дробные числа можно так value = float(input())
Напиши программу (10 класс информатика)

الفكرة

Reasoned about midpoint calculation for a couple of seconds

الإجابة

Вот простой пример решения на Python:

python
# Считываем координаты точки A и точки B x1 = float(input()) y1 = float(input()) x2 = float(input()) y2 = float(input()) # Координаты середины отрезка mx = (x1 + x2) / 2 my = (y1 + y2) / 2 # Выводим абсциссу и ординату середины через пробел print(mx, my)

Как это работает:

  1. Извлекаем четыре числа (x1, y1, x2, y2) из стандартного ввода.
  2. Находим середину отрезка формулами: xmid=x1+x22,ymid=y1+y22. x_{\text{mid}} = \frac{x_1 + x_2}{2}, \quad y_{\text{mid}} = \frac{y_1 + y_2}{2}.
  3. Выводим полученные координаты одним print (они будут разделены пробелом).

Если ввести, например:

text
1 1 2 2

Вы получите:

1.5 1.5

مشاركة هذا السؤال والجواب