- •Об авторе
- •О научных редакторах
- •Благодарности
- •От издательства
- •Введение
- •Для кого эта книга?
- •Почему Python?
- •План книги
- •Версия Python, платформа и IDE
- •Установка Python
- •Запуск Python
- •Использование виртуальной среды
- •Вперед!
- •Глава 1. Спасение моряков с помощью теоремы Байеса
- •Теорема Байеса
- •Проект #1. Поиск и спасение
- •Стратегия
- •Установка библиотек Python
- •Код для теоремы Байеса
- •Время сыграть
- •Итоги
- •Дополнительная литература
- •Усложняем проект. Более грамотный поиск
- •Усложняем проект. Поиск лучшей стратегии с помощью MCS
- •Усложняем проект. Вычисление вероятности обнаружения
- •Глава 2. Установление авторства с помощью стилометрии
- •Проект #2: «Собака Баскервилей», «Война миров» и «Затерянный мир»
- •Стратегия
- •Установка NLTK
- •Корпусы текстов
- •Код стилометрии
- •Итоги
- •Дополнительная литература
- •Практический проект: охота на собаку Баскервилей с помощью распределения
- •Практический проект: тепловая карта пунктуации
- •Усложняем проект: фиксирование частотности
- •Глава 3. Суммаризация текста с помощью обработки естественного языка
- •Стратегия
- •Веб-скрапинг
- •Код для «У меня есть мечта»
- •Установка gensim
- •Код для суммаризации речи «Заправляйте свою кровать»
- •Проект #5. Суммаризация речи с помощью облака слов
- •Модули Word Cloud и PIL
- •Код для создания облака слов
- •Итоги
- •Дополнительная литература
- •Усложняем проект: ночные игры
- •Усложняем проект: суммаризация суммаризаций
- •Глава 4. Отправка суперсекретных сообщений с помощью книжного шифра
- •Одноразовый блокнот
- •Шифр «Ребекка»
- •Проект #6. Цифровой ключ к «Ребекке»
- •Стратегия
- •Код для шифрования
- •Отправка сообщений
- •Итоги
- •Дополнительная литература
- •Глава 5. Поиск Плутона
- •Проект #7. Воссоздание блинк-компаратора
- •Стратегия
- •Данные
- •Код блинк-компаратора
- •Использование блинк-компаратора
- •Проект #8. Обнаружение астрономических транзиентов путем дифференцирования изображений
- •Стратегия
- •Код для детектора транзиентов
- •Использование детектора транзиентов
- •Итоги
- •Дополнительная литература
- •Практический проект: представление орбитальной траектории
- •Практический проект: найди отличия
- •Усложняем проект: сосчитаем звезды
- •Глава 6. Победа в лунной гонке с помощью «Аполлона-8»
- •Цель миссии «Аполлон-8»
- •Траектория свободного возврата
- •Задача трех тел
- •Проект #9. На Луну с «Аполлоном-8»!
- •Использование модуля turtle
- •Стратегия
- •Код программы для расчета свободного возврата «Аполлона-8»
- •Выполнение симуляции
- •Итоги
- •Дополнительная литература
- •Практический проект: симуляция шаблона поисков
- •Практический проект: запусти меня!
- •Практический проект: останови меня!
- •Усложняем проект: симуляция в истинном масштабе
- •Усложняем проект: реальный «Аполлон-8»
- •Глава 7. Выбор мест высадки на Марсе
- •Посадка на Марс
- •Карта MOLA
- •Проект #10. Выбор посадочных мест на Марсе
- •Стратегия
- •Код для выбора мест посадки
- •Результаты
- •Итоги
- •Дополнительная литература
- •Практический проект: убедимся, что рисунки становятся частью изображения
- •Практический проект: визуализация профиля высот
- •Практический проект: отображение в 3D
- •Практический проект: совмещение карт
- •Усложняем проект: три в одном
- •Усложняем проект: перенос прямоугольников
- •Глава 8. Обнаружение далеких экзопланет
- •Транзитная фотометрия
- •Проект #11. Симуляция транзита экзопланеты
- •Стратегия
- •Код для транзита
- •Эксперименты с транзитной фотометрией
- •Проект #12. Получение изображений экзопланет
- •Стратегия
- •Код для пикселизатора
- •Итоги
- •Дополнительная литература
- •Практический проект: обнаружение инопланетных мегаструктур
- •Практический проект: обнаружение транзита астероидов
- •Практический проект: добавление эффекта потемнения к краю
- •Практический проект: обнаружение пятен на звездах
- •Практический проект: обнаружение инопланетной армады
- •Практический проект: обнаружение планеты с луной
- •Практический проект: измерение продолжительности экзопланетного дня
- •Усложняем проект: генерация динамической кривой блеска
- •Глава 9. Как различить своих и чужих
- •Обнаружение лиц на фотографиях
- •Проект #13. Программирование робота-часового
- •Стратегия
- •Результаты
- •Обнаружение лиц в видеопотоке
- •Итоги
- •Дополнительная литература
- •Практический проект: размытие лиц
- •Усложняем проект: обнаружение кошачьих мордочек
- •Глава 10. Ограничение доступа по принципу распознавания лиц
- •Распознавание лиц с помощью LBPH
- •Схема распознавания лиц
- •Извлечение гистограмм локальных бинарных шаблонов
- •Проект #14. Ограничение доступа к инопланетному артефакту
- •Стратегия
- •Поддержка модулей и файлов
- •Код для захвата видео
- •Код для обучения алгоритма распознавания лиц
- •Код для прогнозирования лиц
- •Результаты
- •Итоги
- •Дополнительная литература
- •Усложняем проект: добавление пароля и видеозахвата
- •Усложняем проект: похожие лица и близнецы
- •Усложняем проект: машина времени
- •Глава 11. Создание интерактивной карты побега от зомби
- •Проект #15. Визуализация плотности населения с помощью хороплетной карты
- •Стратегия
- •Библиотека анализа данных
- •Библиотеки bokeh и holoviews
- •Установка pandas, bokeh и holoviews
- •Работа с данными по уровню безработицы и плотности населения в округах и штатах
- •Разбираем код holoviews
- •Код для отрисовки хороплетной карты
- •Планирование маршрута
- •Итоги
- •Дополнительная литература
- •Усложняем проект: отображение на карте изменения численности населения США
- •Глава 12. Находимся ли мы в компьютерной симуляции?
- •Проект #16. Жизнь, Вселенная и пруд черепахи Йертл
- •Код симуляции пруда
- •Следствия симуляции пруда
- •Измерение затрат на пересечение строк или столбцов сетки
- •Результаты
- •Стратегия
- •Итоги
- •Дополнительная литература
- •Дополнение
- •Усложняем проект: поиск безопасного места в космосе
- •Усложняем проект: а вот и Солнце
- •Усложняем проект: взгляд глазами собаки
- •Усложняем проект: кастомизированный поиск слов
- •Усложняем проект: что за сложную паутину мы плетем
- •Усложняем проект: идем вещать с горы
- •Решения для практических проектов
- •Глава 2. Определение авторства с помощью стилометрии
- •Охота на собаку Баскервилей с помощью распределения
- •Тепловая карта пунктуации
- •Глава 4. Отправка суперсекретных сообщений с помощью книжного шифра
- •Составление графика символов
- •Отправка секретов шифром времен Второй мировой войны
- •Глава 5. Поиск Плутона
- •Представление орбитальной траектории
- •Глава 6. Победа в лунной гонке с помощью «Аполлона-8»
- •Симуляция шаблона поисков
- •Заведи меня!
- •Останови меня!
- •Глава 7. Выбор мест высадки на Марсе
- •Убеждаемся, что рисунки становятся частью изображения
- •Визуализация профиля высоты
- •Отображение в 3D
- •Совмещение карт
- •Глава 8. Обнаружение далеких экзопланет
- •Обнаружение инопланетных мегаструктур
- •Обнаружение транзита астероидов
- •Добавление эффекта потемнения к краю
- •Обнаружение инопланетной армады
- •Обнаружение планеты с луной
- •Измерение продолжительности экзопланетного дня
- •Глава 9. Как различить своих и чужих
- •Размытие лиц
- •Глава 10. Ограничение доступа по принципу распознавания лиц
- •Усложняем проект: добавление пароля и видеозахвата
Глава4.Отправкасуперсекретныхсообщенийспомощьюкнижногошифра 355
punct_by_author = dict()
for author in strings_by_author:
tokens = nltk.word_tokenize(strings_by_author[author]) punct_by_author[author] = ([token for token in tokens
if token in PUNCT_SET]) print("Number punctuation marks in {} = {}"
.format(author, len(punct_by_author[author]))) return punct_by_author
def convert_punct_to_number(punct_by_author, author):
"""Возвращаем список знаков препинания, преобразованных в численные значения."""
heat_vals = []
for char in punct_by_author[author]: if char == ';':
value = 1 else:
value = 2 heat_vals.append(value)
return heat_vals
if __name__ == '__main__': main()
Глава 4. Отправка суперсекретных сообщений с помощью книжного шифра
Составление графика символов
practice_barchart.py
"""Рисуем столбчатую диаграмму символов из файла текста.""" import sys
import os import operator
from collections import Counter import matplotlib.pyplot as plt
def load_file(infile):
"""Считываем и возвращаем файл текста в виде строки символов в нижнем регистре."""
with open(infile) as f: text = f.read().lower()
return text
def main():
infile = 'lost.txt'
if not os.path.exists(infile):
print("File {} not found. Terminating.".format(infile), file=sys.stderr)
sys.exit(1)
356 Решения для практических проектов
text = load_file(infile)
#Создаем диаграмму символов в тексте и их частотности. char_freq = Counter(text)
char_freq = Counter(text)
char_freq_sorted = sorted(char_freq.items(), key=operator.itemgetter(1), reverse=True)
x, y = zip(*char_freq_sorted) # * для разделения ('распаковки')
итераторов.
fig, ax = plt.subplots() ax.bar(x, y)
fig.show()
if __name__ == '__main__': main()
Отправка секретов шифром времен Второй мировой войны
practice_WWII_words.py
"""Книжный шифр, использующий роман "Затерянный мир". Для слов, отсутствующих в книге, пишется их первая буква.
Отмечайте 'режим первой буквы', заключая слова между чередующимися
'a a' и 'the the'.
Реализация: Эрик Т. Мортенсон
"""
import sys import os import random import string
from collections import defaultdict, Counter
def main():
message = input("Enter plaintext or ciphertext: ") process = input("Enter 'encrypt' or 'decrypt': ") shift = int(input("Shift value (1-365) = ")) infile = input("Enter filename with extension: ")
if not os.path.exists(infile):
print("File {} not found. Terminating.".format(infile), file=sys.stderr)
sys.exit(1)
word_list = load_file(infile) word_dict = make_dict(word_list, shift)
letter_dict = make_letter_dict(word_list)
if process == 'encrypt':
ciphertext = encrypt(message, word_dict, letter_dict) count = Counter(ciphertext)
encryptedWordList = [] for number in ciphertext:
encryptedWordList.append(word_list[number - shift])
Глава4.Отправкасуперсекретныхсообщенийспомощьюкнижногошифра 357
print("\nencrypted word list = \n {} \n"
.format(' '.join(encryptedWordList))) print("encrypted ciphertext = \n {}\n".format(ciphertext))
# Проверяем шифрование, расшифровывая криптограмму. print("decrypted plaintext = ")
singleFirstCheck = False
for cnt, i in enumerate(ciphertext):
if word_list[ciphertext[cnt]-shift] == 'a' and \ word_list[ciphertext[cnt+1]-shift] == 'a':
continue
if word_list[ciphertext[cnt]-shift] == 'a' and \ word_list[ciphertext[cnt-1]-shift] == 'a':
singleFirstCheck = True continue
if singleFirstCheck == True and cnt<len(ciphertext)-1 and \ word_list[ciphertext[cnt]-shift] == 'the' and \
word_list[ciphertext[cnt+1]-shift] == 'the':
continue
if singleFirstCheck == True and \ word_list[ciphertext[cnt]-shift] == 'the' and \
word_list[ciphertext[cnt-1]-shift] == 'the': singleFirstCheck = False
print(' ', end='', flush=True) continue
if singleFirstCheck == True:
print(word_list[i - shift][0], end = '', flush=True) if singleFirstCheck == False:
print(word_list[i - shift], end=' ', flush=True)
elif process == 'decrypt':
plaintext = decrypt(message, word_list, shift) print("\ndecrypted plaintext = \n {}".format(plaintext))
def load_file(infile):
"""Считываем и возвращаем текстовый файл в виде списка слов в нижнем регистре."""
with open(infile, encoding='utf-8') as file:
words = [word.lower() for line in file for word in line.split()] words_no_punct = ["".join(char for char in word if char not in \
string.punctuation) for word in words]
return words_no_punct
def make_dict(word_list, shift):
"""Возвращаем словарь символов в качестве ключей и смещенные индексы в качестве значений."""
word_dict = defaultdict(list)
for index, word in enumerate(word_list): word_dict[word].append(index + shift)
return word_dict
358 Решения для практических проектов
def make_letter_dict(word_list): firstLetterDict = defaultdict(list) for word in word_list:
if len(word) > 0:
if word[0].isalpha(): firstLetterDict[word[0]].append(word)
return firstLetterDict
def encrypt(message, word_dict, letter_dict):
"""Возвращаем список индексов, представляющих символы в сообщении.""" encrypted = []
# Удаляем пунктуацию из слов сообщения. messageWords = message.lower().split()
messageWordsNoPunct = ["".join(char for char in word if char not in \ string.punctuation) for word in messageWords]
for word in messageWordsNoPunct: if len(word_dict[word]) > 1:
index = random.choice(word_dict[word])
elif len(word_dict[word]) == 1: # Random.choice дает сбой, если есть всего 1 выбор.
index = word_dict[word][0]
elif len(word_dict[word]) == 0: # Слова нет в word_dict. encrypted.append(random.choice(word_dict['a'])) encrypted.append(random.choice(word_dict['a']))
for letter in word:
if letter not in letter_dict.keys():
print('\nLetter {} not in letter-to-word dictionary.'
.format(letter), file=sys.stderr) continue
if len(letter_dict[letter])>1:
newWord =random.choice(letter_dict[letter]) else:
newWord = letter_dict[letter][0] if len(word_dict[newWord])>1:
index = random.choice(word_dict[newWord]) else:
index = word_dict[newWord][0] encrypted.append(index)
encrypted.append(random.choice(word_dict['the'])) encrypted.append(random.choice(word_dict['the'])) continue
encrypted.append(index) return encrypted
def decrypt(message, word_list, shift):
"""Расшифровываем строку криптограммы и возвращаем строку слов в виде открытого текста.
Здесь отображается, как выглядит открытый текст до извлечения первых букв.
"""
plaintextList = []