Недавно попалась довольно интересная задача на использование списков в Python, вот в чем она заключается:
Для того чтобы сыграть в лотерею PowerBall, покупают билет, в котором имеются пять чисел от 1 до 69 и число "PowerBall" в диапазоне от 1 до 26. Затем автомат случайно выбирает выигрышный ряд чисел. если все числа совпадают (ряд первых пяти может быть в любом порядке), вы выигрываете джекпот!
Задача заключается в том, чтобы прочитать из текстового файла данные счастливых билетов и проанализировать их по нескольким критериям.
Файл выглядит так:
Найти:
- 10 наиболее распространённых чисел, упорядоченных по частоте
- 10 наименее распространённых чисел, упорядоченных по частоте
- 10 наиболее "созревших" чисел (честно говоря я не совсем понял, что от меня требуется в этом задании, поэтому я нашел числа, которые никогда не попадались)
- Частоту каждого числа от 1 до 69 и частоту каждого PowerBall числа от 1 до 26
Код с объяснением:
Весь исходный код вы можете найти в конце статьи
Функция main():
Для начала необходимо прочитать файл, для того чтобы закинуть его в функцию анализа, именно этим и занимается функция main(), тут все просто)
Функция analysis(file):
Данная функция построчно читает файл ( 7-ая строка) и разбивает ее на два списка:
- file — тут хранятся первые 5 чисел в виде двумерного списка ( в каждой ячейке находятся по 5 чисел строки)
- PowerBallNumber — тут в виде одномерного списка перечислены числа PowerBall, которые находятся в конце каждой строки
Дальше в этой функции перечислены отдельные функции для анализа, их мы рассмотрим ниже...
Функция count_max():
Данная функция получает на вход двумерный список с 'Обычными' числами лотереи.
В самом начале она преобразует двумерный список в одномерный с помощью sum(). Про этот метод я узнал совсем недавно и теперь он меня часто выручает, так что ловите лайфхак!
Затем в строке 29 мы создаем список с уникальными значениями из первоначального перечня. Чуть ниже мы создаем пустые списки в которые будем заносить данные.
После этого производим сам анализ: для этого мы берем уникальное значение из sumbols и добавляем его в список mas_numbers, под этим же индексом добавляем в список mas_count число, которое отражает, как часто встречается данное значение в изначальном списке text (подсчет осуществляем с помощью count())
После этого выводим самые частые значения с помощью такого алгоритма:
Находим индекс самого часто встречающегося элемента. Выводим элемент под этим индексом, а также число, показывающее как часто оно встретилось. После этого мы удаляем этот максимум из списка с числом и его частотой. Так мы повторяем 10 раз, ведь именно столько чисел требуется вывести в задании.
Функция count_min():
Эта функция работает таким же образом, единственное отличие заключается в том, что мы находим индексы самых редких чисел.
Функция count_never():
Данная функция находит числа, которые никогда не встречались, она работает так:
- также как и в прошлых функциях мы создаем одномерный список из двумерного
- Создаем список всех числе, так как числа от 1 до 9 начинаются с 0, то я делаю этот список конкатенацией двух (подробнее об этом можно почитать тут). Этот список я перевожу в список строковых значений с помощью str()
- Далее я произвожу последовательный поиск, если число под индексом x не находится в файле, я добавляю его в массив. Затем я либо вывожу этот массив в виде обычной строки, либо вывожу сообщение что таких чисел нет.
Функция count_frequency_number():
Эта функция подсчитывает как часто "обычное" число находится в файле.
Для этого мы создаем отсортированный список уникальных чисел из изначального массива. После этого мы последовательно изучаем как часто встретилось то или иное число и выводим данные в консоль:
P.s На всякий случай создал два массива как и в предыдущих функциях, но они тут совершенно незачем, их можно удалить и производить анализ прямиком в print()
Функция count_frequency_PowerBall():
Функция аналогична count_frequency_number(), единственное отличие заключается в том, что нам не нужно преобразовывать список в одномерный, ведь он уже является таковым.
Вывод программы:
Работа функций count_max() и count_min():
Работа функции count_never():
Работа функции count_frequency_number():
Работа функции count_frequency_PowerBall():
Исходный код:
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" Тони Гэдиса.