Skip to content

A Python library with time-based pseudo-random number generation. Features a unique mathematical rounding module, distribution diagnostics, and essential utilities.

License

Notifications You must be signed in to change notification settings

n1xsi/PyCustomRand

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PyCustomRand

Python Last Commit Run Tests

PyCustomRand — это Python-библиотека для генерации псевдослучайных чисел, основанная на алгоритме, использующем системное время с наносекундной точностью.

Данный авторский проект создан для изучения алгоритмов и альтернативных подходов к генерации случайных чисел и их округлении. Меня не устраивало, что модуль random в Python генерирует недостаточно случайные числа ( особенно при нескольких последовательных генерациях ), а встроенный в Python модуль round довольно "грубо" округляет числа ( round(1.5) = 2 и в то же время round(2.5) = 2 ), поэтому я решил написать свою библиотеку для генерации псевдослучайных чисел — более простую и с наибольшей энтропией.

Warning

PyCustomRand не является криптографически стойкой библиотекой и не предназначена для использования в системах безопасности! Используйте secrets модуль.

📌 Зачем нужна эта библиотека, если есть уже встроенные в Python random и round?

PyCustomRand писался как альтернатива этим двум встроенным модулям. Вот главные особенности и возможности библиотеки:

  • Данная библиотека проще написана — весь код закомментирован, лёгок и понятен. В основе реализации генератора псевдослучайных чисел лежит несложный алгоритм (использующий системное время) поэтому библиотеку легко кастомизировать/расширять/дополнять под себя.
  • В большинстве своём PyCustomRand выдаёт более "энтропичный" результат при нескольких генерациях подряд по сравнению со встроенным random-модулем.
    • Сравнение с диаграммами

      PyCustomRand демонстрирует на 173% более высокую кучность распределения по сравнению со стандартной библиотекой random в тестах на 1,000,000 итераций.

      Данные для диаграммы брались из тестирования, которое проводилось с помощью встроенного модуля диагностики (check_distribution). По результатам PyCustomRand показал максимальное отклонение в 2.7 раза меньше, чем стандартный random (0.0267% против 0.0730%).

      PyCustomRand Python Built-in
      PyCustomRand Python Built-in
  • Библиотека включает в себя все самые главные функции из оригинальной Python-библиотеки, но только местами улучшенные и упрощённые (например: random_integer может выдавать сгенерированный результат, делимый на заданное число из диапазона; результат функции random_float можно округлять и пр.)
    • Список функций
      • Генерация целых чисел (random_integer, randrange, gen_random_number).
      • Генерация вещественных чисел (random, random_float).
      • Поддержка статистических распределений: Нормальное (Гаусс), Треугольное, Экспоненциальное, Биномиальное.
      • Инструменты для последовательностей: выбор случайного элемента (choice), выборка с весами (choices), перемешивание (shuffle) и выборка уникальных элементов (sample).
      • Инициализация («посев») последовательности генератора псевдослучайных чисел (set_seed, _get_next_seed_state).
  • Также библиотека имеет дополнительные утилиты, полезные для разработки веба/игр: генерация UUID v4, случайных HEX-цветов (например, #ff05a1), случайных байт, случайных булевых значений (True/False) с настраиваемым шансом.
  • Имеется модуль собственного честного округления — true_round. Функция округляет числа привычным математическим способом (0.5 всегда вверх по модулю), а также исправляет погрешности плавающей точки (например, "проблему 2.675").
  • Код покрыт unit-тестами (чему соответствует badge в начале README), также имеется встроенный модуль диагностики (check_distribution), который позволяет в любой момент проверить равномерность распределения генератора.

Да, у проекта всё же имеются некоторые минусы:

  • Рандом, основанный на времени, требует небольшого ожидания (time.sleep() на 0.1 микросекунду), соответственно, при гигантских итерациях PyCustomRand будет уступать встроенному модулю random во времени.
  • Некоторые функции библиотеки PyCustomRand (функции выборки, распределений) настолько просто написаны, что могут быть недостаточно оптимизированными для гигантских выборок (+ добавляется накапливающееся микро-ожидание из-за проблемы выше).

📦 Установка

Установка библиотеки происходит через стандартный менеджер пакетов для Python:

pip install pycustomrand
➕ Альтернативные способы установки
git clone https://github.com/n1xsi/PyCustomRand.git

📚 Документация

Ниже представлено описание всех доступных функций библиотеки с примерами. Для удобства они могут импороваться напрямую из пакета (from pycustomrand import FUNC_NAME).

1. Управление состоянием (Seeding)

Инициализация генератора позволяет получать воспроизводимые последовательности (например, для тестов или сохранения генерации мира).

  • set_seed(seed=None) Устанавливает начальное состояние генератора.

    • seed: Любой объект, который преобразуется в строку — число/строка/список и др. Если None — используется системное время (случайная последовательность).
  • _get_next_seed_state(current_seed) Внутренняя функция для обновления состояния сида (LCG алгоритм).

🧩 Примеры 1
from pycustomrand import set_seed, random

print(random())  # Случайное число, например, 0.3730190220377659

set_seed("test")  # Установление сида для тестов
print(random())   # Первый результат функции после установления сида "test" ВСЕГДА будет 0.1647608190844912
print(random())   # Второй результат функции тоже ВСЕГДА будет 0.943716375817365 (применилась функция _get_next_seed_state(current_seed="test"))

set_seed()       # Обнуление сида
print(random())  # Случайное число, например, 0.2458062256227575

2. Целые числа

  • gen_random_number(length=1) Генерирует число заданной длины length, склеивая случайные цифры.

  • randrange(start, stop=None, step=1) Полный аналог стандартного range — возвращает элемент из range(start, stop, step). Верхняя граница не включается. Можно указывать один агрумент.

  • random_integer(start, end, step=1) (алиас: randint) Возвращает случайное целое число N, такое что start <= N <= end (обе границы включены).

    • step: Шаг генерации. Например, step=2 вернет только чётные (или нечётные) числа. Необязательный аргумент.
🧩 Примеры 2
from pycustomrand import gen_random_number, randrange, random_integer

print(gen_random_number(5))  # Случайное число длиной 5, например: 92103

print(randrange(10))        # Случайное число из диапазона [0, 10)
print(randrange(1, 10))     # Случайное число из диапазона [1, 10)
print(randrange(0, 10, 2))  # Случайное чётное число из диапазона [0, 10)

print(random_integer(1, 10))     # Случайное целое число из диапазона [1, 10]
print(random_integer(0, 10, 2))  # Случайное чётное целое число из диапазона [0, 10]

# randint - алиас для random_integer, работает при "import pycustomrand", "from pycustomrand import *" или "from pycustomrand import randint"
# randint(1, 10) равноценно random_integer(1, 10)

3. Вещественные числа

  • random() Возвращает случайное число float в диапазоне [0.0, 1.0).

  • random_float(start, end, digits=None) Возвращает число float в диапазоне [start, end) или [start, end] в зависимости от округления (при наличии digits).

    • start, end: Начало и конец диапазона, могут быть как целыми числами, так и числами с плавающей точкой.
    • digits: Если число указано, результат будет округлён до этого количества знаков с помощью true_round.
🧩 Примеры 3
from pycustomrand import random, random_float

print(random())  # Случайное число в диапазоне [0, 1), например 0.2260351121787103

print(random_float(0, 10))            # Случайное число с плавающей точкой в диапазоне [0, 10), например 4.014874483651235
print(random_float(0, 10, digits=3))  # То же самое, только с округлением до 3-ёх знаков, например 6.722

4. Последовательности

  • choice(array) Возвращает один случайный элемент из последовательности.

  • choices(array, k, weights=None) Возвращает список из k случайных элементов с возможностью повторений.

    • weights: Список весов (вероятностей) для каждого элемента (соответствует по индексу). Если None — все элементы считаются равными по весу.
  • shuffle(array) Перемешивает изменяемую последовательность (список) на месте (in-place).

  • sample(array, k, counts=None) Возвращает список из k уникальных случайных элементов.

    • counts: Список с количеством повторений для каждого элемента массива (соответствует по индексу).
🧩 Примеры 4
from pycustomrand import choice, choices, shuffle, sample

array = ["apple", "banana", "cherry", "orange"]

print(choice(array))  # Случайный элемент из массива, например "cherry"

print(choices(array, k=2))  # Список из k случайных элементов из массива, например ['apple', 'cherry']
print(choices(array, k=2, weights=[1, 2, 3, 4]))  # Список из k случайных элементов из массива с весами, например ['orange', 'banana']
# "orange" (с весом 4) будет выпдать в четыре раза чаще, чем "apple" (с весом 1)

shuffle(array)  # Перемешивает массив на месте
print(array)    # Например ['cherry', 'banana', 'apple', 'orange']

print(sample(array, k=2))  # Список из k уникальных случайных элементов из массива, например ['cherry', 'apple']
print(sample(array, k=2, counts=[1, 2, 3, 4]))  # Список из k уникальных случайных элементов из массива с весами, например ['banana', 'orange']
# "orange" (с количеством в массиве 4) будет выпдать в четыре раза больше, чем "apple" (количество в массиве 1)

5. Вероятностные распределения

Эти функции используются для моделирования реальных процессов (физика, экономика, игры).

  • triangular(low=0.0, high=1.0, mode=None) — Треугольное распределение. Генерирует число в диапазоне [low, high], но чаще всего выпадает число mode (вершина треугольника). Используется в простом моделировании и играх. Пример: Урон мечом от 5 до 15, но чаще всего бьёт на 10 — triangular(5, 15, 10).

  • gauss(mu=0.0, sigma=1.0) — Нормальное распределение (Колокол Гаусса). Большинство значений группируется вокруг среднего (mu), а sigma (стандартное отклонение) показывает разброс. Используется для моделирования природных явлений. Примеры: Рост людей, IQ, ошибки измерений, разброс пуль при стрельбе).

    • mu: Среднее значение (центр).
    • sigma: Стандартное отклонение (разброс).
  • expovariate(lambd=1.0) — Экспоненциальное распределение. Описывает время между событиями в процессе Пуассона. Часто выпадают маленькие значения, редко — большие (длинный хвост). Используется в таймерах. Примеры: Время между приходом автобусов. В игре спавн монстров — обычно они лезут часто, но иногда случаются долгие затишья.

    • lambd: Интенсивность событий (должна быть > 0).
  • binomialvariate(n=1, p=0.5) — Биномиальное распределение (алиас: binomial). Количество успехов в серии из n независимых испытаний с вероятностью успеха p. Используется в моделировании финансов и математике. Примеры: Сколько раз сейчас выпадет орёл, если подбросить монету 10 раз — binomialvariate(n=10, p=0.5).

🧩 Примеры 5
from pycustomrand import triangular, gauss, expovariate, binomialvariate

print(triangular(low=0.0, high=1.0, mode=0.5))  # Случайное число с плавающей точкой из треугольного распределения (диапазон [0.0, 1.0])
# Чаще всего выпадает значение ±0.5, например: 0.6508330793068139

print(gauss(mu=0.0, sigma=1.0))  # Случайное число с плавающей точкой из нормального "колокольного" распределения (общий диапазон 0.0 ± ~3.0)
# Чаще всего выпадает значение 0.0 ± 1.0, например: 1.0665809173007805 или -1.650128903962443

print(expovariate(lambd=1.0))  # Случайное число с плавающей точкой из экспоненциального распределения (общий диапазон 0.0 ± ~4.0)
# Чаще всего выпадает наименьшее значение от 0.0 до 1.0, например: 0.405175514533143

print(binomialvariate(n=10, p=0.5))  # Случайное число из биномиального распределения (диапазон [0, 10]), например: 5
# Чем меньше вероятность p - тем чаще будет выпадать число из первой половины диапазона [0, 10], больше - большее из второй половины

# binomial - алиас для binomialvariate, работает при "import pycustomrand", "from pycustomrand import *" или "from pycustomrand import binomial"
# binomial(n=10, p=0.5)) равноценно binomialvariate(n=10, p=0.5)

6. Утилиты (Extras)

  • random_bytes(count): Генерация случайных байт в количестве count.

  • random_uuid4(): Генерация уникального идентификатора (UUID v4).

  • random_color_hex(): Случайный цвет в формате HEX.

  • random_bool(true_chance=0.5): Возвращает True или False c вероятностью true_chance.

🧩 Примеры 6
from pycustomrand import random_bytes, random_uuid4, random_color_hex, random_bool

print(random_bytes(10))    # Случайные 10 байтов, например: b'\x8b\x91\x19\xe42\xcd\x80\x82b\xba'

print(random_uuid4())      # Случайный UUID v4, например: '0e1d2eeb-1627-4cfa-8130-afe74e1c5ce9'

print(random_color_hex())  # Cлучайный цвет в формате hex, например: '#0ca3e7'

print(random_bool())       # Случайное значение True/False, например: True

🎯 О модуле true_round

Модуль решает проблему "банковского округления" в Python 3, где round(x.5) округляется до ближайшего чётного числа. true_round использует честное математическое округление (отсюда и название "true" — истинное/честное).

Для удобства модуль может быть импортирован напрямую из пакета (from pycustomrand import true_round).

Число Стандартный round() PyCustomRand true_round() Примечание
2.5 2 3 Математическое округление (0.5 → вверх)
3.5 4 4 Совпадает
2.675 (до 2-ух знаков) 2.67 2.68 Исправление погрешности Floating Point Error
1.005 (до 2-ух знаков) 1.0 1.01 Корректная обработка граничных значений
0.00049 (до 3-ёх знаков) 0.0 0.001 Точность при работе с малыми числами

📂 Структура репозитория

Проект имеет следующую файловую структуру:

PyCustomRand/                # Корень репозитория
├── .github/
│   └── workflows/
│       └── python-app.yml   # Конфигурация GitHub Actions: автоматический запуск тестов при каждом Push/PR
│
├── pycustomrand/            # Исходный код пакета
│   ├── __init__.py            # Точка входа: инициализация пакета и алиасы функций
│   ├── custom_round.py        # Реализация алгоритма математического округления (true_round)
│   ├── diagnostics.py         # Декоратор для проверки равномерности распределения чисел
│   └── random_generator.py    # Ядро библиотеки: класс PseudoRandom и вся логика генерации
│
├── tests/                   # Набор Unit-тестов
│   ├── __init__.py            # Пустой файл (чтобы тесты видели друг друга)
│   ├── test_random.py         # Тесты для генератора, seed, диапазонов и утилит
│   └── test_round.py          # Тесты для проверки корректности округления
│
├── .gitignore               # Правила исключения файлов из Git (venv, кэш, логи)
├── LICENSE                  # Текст лицензии MIT
├── pyproject.toml           # Конфигурационный файл сборки пакета для PyPI
└── README.md                # Документация проекта

🤝 Вклад в проект (Контрибуция)

Приветствуется любая помощь в развитии библиотеки. Если у вас есть идеи по улучшению алгоритмов, оптимизации кода или вы нашли ошибку — смело создавайте Issue/Pull Request.

Как внести свой вклад:

  1. Сделайте Fork репозитория;
  2. Создайте новую ветку для вашей фичи (git checkout -b feature/SomeFeature);
  3. Внесите изменения;
  4. Запустите тесты, чтобы убедиться, что ваши изменения ничего не сломали:
    python -m unittest discover tests
  5. Запушьте изменения (git push origin feature/SomeFeature);
  6. Откройте Pull Request.

📄 Лицензия

Этот проект является программным обеспечением с открытым исходным кодом и распространяется под лицензией MIT License.

Copyright © 2025 Ivan (n1xsi)

Данная лицензия разрешает любому лицу получать копию данного программного обеспечения и сопутствующей документации бесплатно,
использовать его без ограничений, включая право копировать, модифицировать, публиковать и распространять копии ПО.

Полный текст лицензии доступен в файле LICENSE.

About

A Python library with time-based pseudo-random number generation. Features a unique mathematical rounding module, distribution diagnostics, and essential utilities.

Topics

Resources

License

Stars

Watchers

Forks

Languages