Для генератора целых чисел достаточно random.randint и двух границ диапазона. Мы добавим окно Tkinter, кнопку и понятную проверку ввода. Число будет выбираться вместе с обеими границами: от 1 до 6 означает, что могут выпасть и 1, и 6.
Такой проект кажется игрушечным, но в нём встречаются почти все базовые шаги программы: получить текст из интерфейса, преобразовать его в числа, проверить условие, вызвать функцию библиотеки и показать результат. Если разделить эти шаги, генератор легко тестировать и расширять. Например, позже можно добавить историю выпадений, генерацию нескольких чисел или режим кубика.
Берём нижнюю и верхнюю границы из двух полей.
Разрешаем только целые числа и требуем минимум не больше максимума.
Передаём готовый диапазон в randint и обновляем одну метку.
Как устроен диапазон случайного числа
В окне будут два Entry для границ, кнопка «Сгенерировать» и Label для ответа. Интерфейс передаёт строки в функцию pick_number. Эта функция ничего не знает про Tkinter: она превращает строки в int, проверяет порядок и возвращает число. Благодаря такой границе ошибку можно проверить отдельно от кнопки и оформления.
| Часть | Пример | Что происходит |
|---|---|---|
| Минимум | 1 | Первое допустимое число |
| Максимум | 100 | Последнее допустимое число |
| Проверка | 1 ≤ 100 | Диапазон не перевёрнут |
| Результат | 57 | Одно целое число из диапазона |
Главное правило: текст из поля ещё не число. Сначала int и проверка порядка, только затем randint. Тогда каждая ошибка возникает в понятном месте.

От двух строк к результату. Проверка выполняется до генерации
Пишем генератор с окном и кнопкой
Создайте файл random_number_gui.py. Модуль random входит в стандартную библиотеку Python, поэтому pip не нужен. Функция pick_number отвечает только за расчёт, show_number переводит исключение в сообщение, а build_app собирает окно. Защита if __name__ позволяет импортировать функцию в тестах без открытия интерфейса.
import random
import tkinter as tk
from tkinter import ttk
def pick_number(min_text: str, max_text: str) -> int:
minimum = int(min_text.strip())
maximum = int(max_text.strip())
if minimum > maximum:
raise ValueError("Минимум не может быть больше максимума")
return random.randint(minimum, maximum)
def build_app() -> tk.Tk:
root = tk.Tk()
root.title("Случайное число")
root.resizable(False, False)
minimum = tk.StringVar(value="1")
maximum = tk.StringVar(value="100")
result = tk.StringVar(value="Нажмите кнопку")
frame = ttk.Frame(root, padding=24)
frame.grid()
ttk.Label(frame, text="От").grid(row=0, column=0, sticky="w")
ttk.Entry(frame, textvariable=minimum, width=12).grid(
row=1, column=0, padx=(0, 12)
)
ttk.Label(frame, text="До").grid(row=0, column=1, sticky="w")
ttk.Entry(frame, textvariable=maximum, width=12).grid(row=1, column=1)
def show_number() -> None:
try:
number = pick_number(minimum.get(), maximum.get())
result.set(f"Выпало: {number}")
except ValueError as error:
result.set(str(error) if str(error) else "Введите целые числа")
ttk.Button(
frame,
text="Сгенерировать",
command=show_number,
).grid(row=2, column=0, columnspan=2, sticky="ew", pady=18)
ttk.Label(frame, textvariable=result, font=("Arial", 18, "bold")).grid(
row=3, column=0, columnspan=2
)
return root
if __name__ == "__main__":
app = build_app()
app.mainloop()Диапазон от 1 до 6 возвращает только числа от 1 до 6 включительно. Отрицательные границы работают без отдельной ветки. Пустое поле и текст дают сообщение, а не traceback. После ошибки можно исправить значение и нажать кнопку ещё раз.

Разница находится в правой границе. Сравнение показывает, какой вариант легче поддерживать и проверять.
Что именно делает random.randint
random.randint(a, b) выбирает целое число N так, что a ≤ N ≤ b. В этом его отличие от random.randrange(a, b), где верхняя граница b не входит в диапазон. Для учебного кубика randint(1, 6) читается естественно. Генератор псевдослучайный: последовательность строится алгоритмом, а не физическим источником шума. Для игры, жеребьёвки в интерфейсе или тестовых данных этого достаточно.
| Выражение | Возможный минимум | Возможный максимум |
|---|---|---|
| randint(1, 6) | 1 | 6 |
| randrange(1, 6) | 1 | 5 |
| randint(-3, 3) | -3 | 3 |
| randint(10, 10) | 10 | 10 |
Не используйте random для паролей, токенов, кодов восстановления и других секретов. Документация Python прямо отделяет обычный псевдослучайный генератор от модуля secrets, который предназначен для криптографических задач. Здесь результат показывается пользователю и не защищает доступ, поэтому random подходит. Не вызывайте random.seed с постоянным числом в готовом приложении: одинаковый seed специально воспроизводит одну и ту же последовательность.
Практика: проверяем границы и ошибки
Проверяйте не только красивый диапазон от 1 до 100. Граница из одного значения, отрицательные числа, пробелы, перевёрнутый диапазон и повторные клики быстро показывают, отделена ли логика от интерфейса. Для функции pick_number можно временно вызвать random.seed(7), чтобы получить воспроизводимую последовательность во время теста, а затем убрать эту строку из приложения.
- Запустите
python random_number_gui.pyи сгенерируйте пять чисел от 1 до 6. - Введите одинаковые границы 10 и 10: результат всегда должен быть 10.
- Проверьте диапазон от -5 до 5 и убедитесь, что отрицательные числа принимаются.
- Поменяйте границы местами: 100 и 1. Окно должно показать понятную ошибку.
- Очистите одно поле, нажмите кнопку, затем исправьте значение без перезапуска.
- Измените начальный диапазон в StringVar и запустите файл повторно.
Обе границы входят в диапазон. Одинаковые границы не вызывают ошибку. Неверный ввод не закрывает окно. Каждый повторный клик обновляет только результат.

До оформления и дополнительных режимов. Пройдите все четыре сценария перед публикацией проекта.
Доводим генератор до готового мини-приложения
Когда базовый сценарий устойчив, можно добавить количество чисел и историю последних результатов. Не смешивайте это сразу с основной функцией. Пусть pick_number по-прежнему возвращает одно число, а отдельная функция повторяет вызов нужное количество раз. Для режима без повторов используйте random.sample и заранее проверяйте, что размер выборки не больше диапазона. Так расширения не ломают понятное ядро.
randrange и randint работают по-разному. Для включённого максимума используйте randint.
Текст «10» меньше текста «2» по другому правилу. Сначала преобразуйте обе границы.
Ловите ValueError, иначе опечатка в коде превратится в ложную ошибку ввода.
Для секретов нужен модуль secrets, а не учебный генератор.
Что получится в итоге

Готовое окно принимает две границы, показывает новое число по кнопке и остаётся рабочим после ошибочного ввода.
Входит ли максимум в randint?
Да. randint(1, 6) может вернуть и 1, и 6.
Нужно ли устанавливать random через pip?
Нет. random входит в стандартную библиотеку Python.
Подходит ли random для паролей?
Нет. Для секретов используйте модуль secrets.
Как понять, что проект готов?
Повторите основной сценарий несколько раз, затем проверьте пустой ввод, граничные значения и повторный запуск. Ошибка должна объяснять, что исправить, а не закрывать программу.
Можно ли скопировать код целиком?
Можно использовать его как стартовую точку. После первого запуска измените хотя бы один параметр и объясните себе, где хранятся данные, где выполняется действие и где появляется результат.
Числа, условия, функции и исключения можно закрепить в курсе Python. Если int не принимает текст, откройте разбор ValueError.
Для проекта с похожим окном соберите калькулятор на Tkinter, а для безопасной генерации секретов используйте генератор паролей. В Кодике функцию pick_number удобно проверить отдельно от GUI.