Найти в Дзене
Путь в Data Science

Лотерея PowerBall на Python

Оглавление

Недавно попалась довольно интересная задача на использование списков в Python, вот в чем она заключается:

Для того чтобы сыграть в лотерею PowerBall, покупают билет, в котором имеются пять чисел от 1 до 69 и число "PowerBall" в диапазоне от 1 до 26. Затем автомат случайно выбирает выигрышный ряд чисел. если все числа совпадают (ряд первых пяти может быть в любом порядке), вы выигрываете джекпот!

Задача заключается в том, чтобы прочитать из текстового файла данные счастливых билетов и проанализировать их по нескольким критериям.

Файл выглядит так:

Файл с данными лотереи
Файл с данными лотереи

Найти:

  1. 10 наиболее распространённых чисел, упорядоченных по частоте
  2. 10 наименее распространённых чисел, упорядоченных по частоте
  3. 10 наиболее "созревших" чисел (честно говоря я не совсем понял, что от меня требуется в этом задании, поэтому я нашел числа, которые никогда не попадались)
  4. Частоту каждого числа от 1 до 69 и частоту каждого PowerBall числа от 1 до 26

Код с объяснением:

Весь исходный код вы можете найти в конце статьи

Функция main():

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

Функция main() 1-3 строки кода
Функция main() 1-3 строки кода

Функция analysis(file):

Данная функция построчно читает файл ( 7-ая строка) и разбивает ее на два списка:

  1. file тут хранятся первые 5 чисел в виде двумерного списка ( в каждой ячейке находятся по 5 чисел строки)
  2. PowerBallNumber тут в виде одномерного списка перечислены числа PowerBall, которые находятся в конце каждой строки
Часть функции analysis, которая отвечает на разбиение по спискам (строки 4, 5 пусты для удобства чтения)
Часть функции analysis, которая отвечает на разбиение по спискам (строки 4, 5 пусты для удобства чтения)

Дальше в этой функции перечислены отдельные функции для анализа, их мы рассмотрим ниже...

-5

Функция count_max():

Данная функция получает на вход двумерный список с 'Обычными' числами лотереи.

В самом начале она преобразует двумерный список в одномерный с помощью sum(). Про этот метод я узнал совсем недавно и теперь он меня часто выручает, так что ловите лайфхак!

Затем в строке 29 мы создаем список с уникальными значениями из первоначального перечня. Чуть ниже мы создаем пустые списки в которые будем заносить данные.

-6

После этого производим сам анализ: для этого мы берем уникальное значение из sumbols и добавляем его в список mas_numbers, под этим же индексом добавляем в список mas_count число, которое отражает, как часто встречается данное значение в изначальном списке text (подсчет осуществляем с помощью count())

-7

После этого выводим самые частые значения с помощью такого алгоритма:

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

-8

Функция count_min():

Эта функция работает таким же образом, единственное отличие заключается в том, что мы находим индексы самых редких чисел.

-9

Функция count_never():

Данная функция находит числа, которые никогда не встречались, она работает так:

  1. также как и в прошлых функциях мы создаем одномерный список из двумерного
  2. Создаем список всех числе, так как числа от 1 до 9 начинаются с 0, то я делаю этот список конкатенацией двух (подробнее об этом можно почитать тут). Этот список я перевожу в список строковых значений с помощью str()
  3. Далее я произвожу последовательный поиск, если число под индексом x не находится в файле, я добавляю его в массив. Затем я либо вывожу этот массив в виде обычной строки, либо вывожу сообщение что таких чисел нет.
-10

Функция count_frequency_number():

Эта функция подсчитывает как часто "обычное" число находится в файле.

Для этого мы создаем отсортированный список уникальных чисел из изначального массива. После этого мы последовательно изучаем как часто встретилось то или иное число и выводим данные в консоль:

-11

P.s На всякий случай создал два массива как и в предыдущих функциях, но они тут совершенно незачем, их можно удалить и производить анализ прямиком в print()

Функция count_frequency_PowerBall():

Функция аналогична count_frequency_number(), единственное отличие заключается в том, что нам не нужно преобразовывать список в одномерный, ведь он уже является таковым.

-12

Вывод программы:

Работа функций count_max() и count_min():

-13

Работа функции count_never():

-14

Работа функции count_frequency_number():

P.s. Все числа не вмещаются в экран(
P.s. Все числа не вмещаются в экран(

Работа функции count_frequency_PowerBall():

-16

Исходный код:

def main():
file = open('pbnumbers.txt', 'r')
analysis(file)


def analysis(file):
file = file.readlines()
PowerBallNumber = []
# print(file)
for line in range(len(file)):
file[line] = file[line].rstrip('\n')
file[line] = file[line].split()
PowerBallNumber.append(file[line][5])
del file[line][5]
# print(file)
# print(PowerBallNumber)
print('\nНаиболее частые числа (топ 10):')
count_max(file)
print('\nНаиболее редкие числа (топ 10):')
count_min(file)
print('\nЧисла, которые никогда не встричались:')
count_never(file)
print('\nКак часто встречается то или иное регулярное число (в порядке убывания):')
count_frequency_number(file)
print('\nКак часто встречается то или иное PowerBall число (в порядке убывания):')
count_frequency_PowerBall(PowerBallNumber)


def count_max(text):
text = sum(text, []) # преобразование двумерного списка в одномерный
sumbols = list(set(text))
mas_numbers = []
mas_count = []
for i in range(len(sumbols)):
mas_numbers.append(sumbols[i])
mas_count.append(int(text.count(sumbols[i])))
for x in range(10):
maximum = mas_count.index(max(mas_count))
print(mas_numbers[maximum], 'встретилось', mas_count[maximum], 'раз')
del mas_count[maximum]
del mas_numbers[maximum]


def count_min(text):
text = sum(text, []) # преобразование двумерного списка в одномерный
sumbols = list(set(text))
mas_numbers = []
mas_count = []
for i in range(len(sumbols)):
mas_numbers.append(sumbols[i])
mas_count.append(int(text.count(sumbols[i])))
for x in range(10):
minimum = mas_count.index(min(mas_count))
print(mas_numbers[minimum], 'встретилось', mas_count[minimum], 'раз')
del mas_count[minimum]
del mas_numbers[minimum]


def count_never(text):
text = sum(text, []) # преобразование двумерного списка в одномерный
mass = []
list_of_numbers = ['01', '02', '03', '04', '05', '06', '07', '08', '09'] + list(range(10, 70))
for x in range(len(list_of_numbers)):
list_of_numbers[x] = str(list_of_numbers[x])

for x in range(69):
if list_of_numbers[x] not in text:
mass.append(list_of_numbers[x])
if len(mass) > 0:
print(''.join(mass))
else:
print('Таких чисел нет(')


def count_frequency_number(text):
text = sum(text, []) # преобразование двумерного списка в одномерный
sumbols = sorted(list(set(text)))
mas_numbers = []
mas_count = []
for i in range(len(sumbols)):
mas_numbers.append(sumbols[i])
mas_count.append(int(text.count(sumbols[i])))
print(mas_numbers[i], 'встретилось', mas_count[i], 'раз')


def count_frequency_PowerBall(text):
sumbols = sorted(list(set(text)))
mas_numbers = []
mas_count = []
for i in range(len(sumbols)):
mas_numbers.append(sumbols[i])
mas_count.append(int(text.count(sumbols[i])))
print(mas_numbers[i], 'встретилось', mas_count[i], 'раз')


main()

Итог:

Надеюсь эта задача вам понравилась, мне уж точно! Довольно интересный пример, который требует от вас неплохого знания базовых инструментов работы с строковыми данными (подробнее о них можно почитать тут)

P.s Данная задача находится под номером 13 из главы №8 книги: "Начинаем программировать на Python" Тони Гэдиса.

Наука
7 млн интересуются