Найти тему
Bednyakov

Python с нуля. Эксперимент с вероятностями в игре "Орёл и решка".

Привет. Извиняюсь за не самое очевидное название статьи, лаконичнее и информативнее придумать не смог. Как до этого не мог придумать и решение простой, на первый взгляд, задачки:

  1. Создать симуляцию 10 000 подбрасываний монеты.
  2. Записать полученные результаты.
  3. Найти в результатах определенные последовательности. Например, сколько раз за 10 000 подбрасываний решка или орел выпадали по 7 раз подряд.

Использовать модуль рандома и с помощью цикла записать результаты случайных значений из имеющихся двух вариантов я догадался. А вот с третьим пунктом зашел в тупик. Пытался создавать циклы в цикле, использовать строковые и списковые методы, но рабочую схему найти так и не смог. Гуглить не стал и просто оставил решение. Пока не узнал про чудо чудесное...

Регулярные выражения в Python - это мощь. Я, конечно, сначала этого не понял, а потом как понял. И сразу вспомнил о нерешенной задаче с "Орёл и решка". Решение пришло за секунды, еще минута понадобилась записать эти несколько строчек кода и проверить его работу. Как и ожидалось, регулярные выражения работают в подобных случаях на отличненько.

И так, для решения нам понадобятся два модуля: названный выше "random", который будет отвечать за генерацию случайных значений, и модуль "re", предназначенный для работы с регулярными выражениями. Импортируем их.

Далее создадим две переменные. Переменная count будет счетчиком, отсчитывающим количество "бросков". Изначально ей будет присвоено значение ноль. А переменная result, изначально содержащая пустую строку, будет содержать все результаты, выпавшие в результате "подбрасывания" монеты.

-2

Теперь создаем простейший цикл, на каждом витке которого с помощью функции random.randint будет генерироваться значение 0 или 1, и записываться в переменную result. А счетчик count будет увеличивать значение на единицу, вплоть до 10 000. Как только это число будет достигнуто, цикл while завершится.

-3

После отработки цикла переменная result будет содержать строку из десяти тысяч нулей и единиц, которую необходимо обработать, и найти нужные нам вхождения, т.е. "0000000" и "1111111". Т.к. они символизируют семикратное выпадение подряд орла и решки. Делать это будем с помощью функции re.compile(), в которую поместим искомый шаблон, и метода findall. Последний будет искать переданный шаблон в строке result.

И так, создадим две переменные, которым передадим значения с искомыми шаблонами, т.е. "0000000" и "1111111".

-4

Полагаю, тут всё очевидно. Но эти строчки лучше исправить на более короткие. Вместо того чтобы печатать в искомой строке нужное количество знаков, мы можем просто указать количество символов в фигурных скобках. Поэтому записать лучше так, как показано ниже.

-5

Что касается символа r, r'строка' - это необработанная (сырая) строка. Нужна для того, чтобы слеш не вызывал экранирование символов. В нашем случае r'строка' используется просто для наглядности.

Почти всё. Осталось лишь применить метод fiindall, обнаружить все вхождения семи нулей и семи единиц в строку result, а полученные данные присвоить новым переменным, например sum1 и sum2.

-6

Обе этих переменные теперь ссылаются на списки. Один список должен состоять из объектов в виде искомых семи нулей, второй из семи единиц. Но так как мы искали по формам (0){7} и (1){7}, списки состоят из однозначных объектов, которые подразумевают семизначные (простите, если запутал). Для наглядности выведем содержимое списков вместе с искомым результатом.

-7

На экране мы увидим что-то похожее на результаты нижней картинки.

-8

Наверное это лишнее, но если что, количество нужных вхождений мы узнали посчитав число объектов в списках с помощью функции len. Вот и всё решение.

Конечно, регулярные выражения в Python- это мощнейший инструмент, прелесть которого в этом примере раскрыта лишь на 0,00001%. Но оцените, какой крохотной получилась программа, осталось лишь обернуть её в функцию, которой можно передавать различные искомые значения, и применять в других, совершенно бесполезных программах.

И всё же мне до сих пор интересно, как можно решить эту же задачу, но без регулярных выражений. Если кто соображает, подскажите, пожалуйста.

Общий вид получившейся программы
Общий вид получившейся программы