Привет. Извиняюсь за не самое очевидное название статьи, лаконичнее и информативнее придумать не смог. Как до этого не мог придумать и решение простой, на первый взгляд, задачки:
- Создать симуляцию 10 000 подбрасываний монеты.
- Записать полученные результаты.
- Найти в результатах определенные последовательности. Например, сколько раз за 10 000 подбрасываний решка или орел выпадали по 7 раз подряд.
Использовать модуль рандома и с помощью цикла записать результаты случайных значений из имеющихся двух вариантов я догадался. А вот с третьим пунктом зашел в тупик. Пытался создавать циклы в цикле, использовать строковые и списковые методы, но рабочую схему найти так и не смог. Гуглить не стал и просто оставил решение. Пока не узнал про чудо чудесное...
Регулярные выражения в Python - это мощь. Я, конечно, сначала этого не понял, а потом как понял. И сразу вспомнил о нерешенной задаче с "Орёл и решка". Решение пришло за секунды, еще минута понадобилась записать эти несколько строчек кода и проверить его работу. Как и ожидалось, регулярные выражения работают в подобных случаях на отличненько.
И так, для решения нам понадобятся два модуля: названный выше "random", который будет отвечать за генерацию случайных значений, и модуль "re", предназначенный для работы с регулярными выражениями. Импортируем их.
Далее создадим две переменные. Переменная count будет счетчиком, отсчитывающим количество "бросков". Изначально ей будет присвоено значение ноль. А переменная result, изначально содержащая пустую строку, будет содержать все результаты, выпавшие в результате "подбрасывания" монеты.
Теперь создаем простейший цикл, на каждом витке которого с помощью функции random.randint будет генерироваться значение 0 или 1, и записываться в переменную result. А счетчик count будет увеличивать значение на единицу, вплоть до 10 000. Как только это число будет достигнуто, цикл while завершится.
После отработки цикла переменная result будет содержать строку из десяти тысяч нулей и единиц, которую необходимо обработать, и найти нужные нам вхождения, т.е. "0000000" и "1111111". Т.к. они символизируют семикратное выпадение подряд орла и решки. Делать это будем с помощью функции re.compile(), в которую поместим искомый шаблон, и метода findall. Последний будет искать переданный шаблон в строке result.
И так, создадим две переменные, которым передадим значения с искомыми шаблонами, т.е. "0000000" и "1111111".
Полагаю, тут всё очевидно. Но эти строчки лучше исправить на более короткие. Вместо того чтобы печатать в искомой строке нужное количество знаков, мы можем просто указать количество символов в фигурных скобках. Поэтому записать лучше так, как показано ниже.
Что касается символа r, r'строка' - это необработанная (сырая) строка. Нужна для того, чтобы слеш не вызывал экранирование символов. В нашем случае r'строка' используется просто для наглядности.
Почти всё. Осталось лишь применить метод fiindall, обнаружить все вхождения семи нулей и семи единиц в строку result, а полученные данные присвоить новым переменным, например sum1 и sum2.
Обе этих переменные теперь ссылаются на списки. Один список должен состоять из объектов в виде искомых семи нулей, второй из семи единиц. Но так как мы искали по формам (0){7} и (1){7}, списки состоят из однозначных объектов, которые подразумевают семизначные (простите, если запутал). Для наглядности выведем содержимое списков вместе с искомым результатом.
На экране мы увидим что-то похожее на результаты нижней картинки.
Наверное это лишнее, но если что, количество нужных вхождений мы узнали посчитав число объектов в списках с помощью функции len. Вот и всё решение.
Конечно, регулярные выражения в Python- это мощнейший инструмент, прелесть которого в этом примере раскрыта лишь на 0,00001%. Но оцените, какой крохотной получилась программа, осталось лишь обернуть её в функцию, которой можно передавать различные искомые значения, и применять в других, совершенно бесполезных программах.
И всё же мне до сих пор интересно, как можно решить эту же задачу, но без регулярных выражений. Если кто соображает, подскажите, пожалуйста.