Кир Булычев начал писать книги про Алису Селезневу в 1965 году. Со временем Алиса стала "вечным героем", пережившим и автора и многих своих поклонников. Часть приключений девочки, с которой ничего не случится, происходит на Земле и даже в прошлом. Но автор Алисы все же писатель-фантаст и большинство поклонников воспринимают истории о ней, как космические приключения.
Мне стало интересно с помощью Python изучить книги про Алису, посмотреть с какими планетами и перемещениями по вселенной связаны события ее жизни. И установить, где в космосе побывала сама Алиса.
Я нашел в интернете файлы, где собраны все (или большинство) рассказов про Алису, соединил их в один файл .txt и использовал для анализа.
Я использовал библиотеку re, которая является встроенным модулем Python для работы с регулярными выражениями, что позволяет искать текстовые паттерны. Поскольку я собирал итоговый текст из разных файлов, мне понадобилась библиотека chardet для автоматического определения кодировки файла. Я использовал collections для подсчёта частоты элементов и defaultdict для словарей со значениями по умолчанию.
Я решил найти все планеты, которые упоминаются в тексте вообще. Сначала я искал слово планета в разных падежах через конструкцию "планета" с вариантами окончаний "аыеуы".
def find_planets_after_word(text): if text is None: return [], [] pattern_planet_name = r''' (?<![\.\!\?\n]) (планет[аыеуы]?|планет) \s+ ([А-ЯЁ][а-яё]+) pattern_sentence_start = r'[\.\!\?]\s+([А-ЯЁ][а-яё]+)' found_planets = [] all_matches = [] for match in re.finditer(pattern_planet_name, text, re.IGNORECASE | re.VERBOSE): full_match = match.group(0) planet_word = match.group(1) planet_name = match.group(2)
Но сразу решить эту задачу оказалось не так легко.
Сначала код нашел мне слишком много лишнего, в выводе было 663 планеты. Это слишком много. Проблема была в том, что использовался флаг re.IGNORECASE, который делал поиск регистронезависимым. Код находил не только названия планет, но и любые слова после слова "планета" включая прилагательные "другая", "новая", "эта" и так далее.
Пришлось изменить код, чтобы после слова "планета" находились только слова с заглавной буквы. Также пришлось сделать список стоп-слов и добавить проверку на минимальную длину слова, чтобы в вывод не попадали союзы и предлоги.
Были еще добавлены существительные "система", "звезда", "орбита", "атмосфера", которые могут встречаться после слова "планета", но не являются названиями. Проверка осуществляется через оператор in который проверяет вхождение слова в множество стоп-слов.
И также пришлось исключить заглавные буквы в начале предложений.
В итоге у меня получился список из 281 планеты, которые связаны с приключениями Алисы.

И посчитал самые часто упоминаемые планеты.

Но это, скажем так, вообще все планеты, упомянутые в рассказах и повестях про Алису Селезневу. Некоторые из них описаны в книгах явно "для контекста". Например, планета Самора упоминается в текстах только однажды, некий житель этой неизвестной планеты выиграл в викторине гарнитур орехового дерева в книге "Путешествие Алисы". Мне стало интересно посмотреть и посчитать, на каких из этого множества миров была сама Алиса.
Я использовал анализ контекста. Моя гипотеза была в том, что просто упоминание планеты не означает что Алиса там была. Нужно найти подтверждение посещения через имя героини вместе с глаголами путешествия вблизи названия планеты. Я создал список с шестью вариантами имени по падежам через регулярные выражения. И создал список с более чем двадцатью глаголами. Каждый глагол представлен как регулярное выражение с границами слова через r и b для точного совпадения. Для каждого упоминания планеты я определил определяется контекст в 100 символов до и после слова.
def find_alisa_visited_planets(text, planets_list): if text is None: return [], [] alisa_patterns = [ r'\bалиса\b', r'\bалисы\b', r'\bалисе\b', r'\bалису\b', r'\bалисой\b', r'\bалисою\b' ] travel_verbs = [ r'\bприлетела\b', r'\bприлетели\b', r'\bприлетел\b', r'\bприземлилась\b', r'\bприземлились\b', r'\bпосетила\b', r'\bпосетили\b', r'\bпосетил\b', r'\bулетела\b', r'\bулетели\b', r'\bулетел\b', r'\bбыла\b', r'\bбыли\b', r'\bбыл\b', r'\bпобывала\b', r'\bпобывали\b', r'\bотправилась\b', r'\bотправились\b', r'\bдобралась\b', r'\bдобрались\b', r'\bдолетела\b', r'\bдолетели\b', r'\bприбыла\b', r'\bприбыли\b', r'\bнаходилась\b', r'\bнаходились\b', r'\bпутешествовала\b', r'\bпутешествовали\b', r'\bоказалась\b', r'\bоказались\b' ] visited_planets = [] all_planet_checks = [] for match in re.finditer(planet_pattern, text, re.IGNORECASE): position = match.start() context_start = max(0, position - 100) context_end = min(len(text), position + 100) context = text[context_start:context_end].replace('\n', ' ') alisa_found = False for alisa_pattern in alisa_patterns: if re.search(alisa_pattern, context, re.IGNORECASE): alisa_found = True break verb_found = False matched_verb = None for verb_pattern in travel_verbs: verb_match = re.search(verb_pattern, context, re.IGNORECASE) if verb_match: verb_found = True matched_verb = verb_match.group() break is_visited = alisa_found and verb_found visit_data = { 'planet': planet_name, 'position': position, 'context': context, 'alisa_found': alisa_found, 'verb_found': verb_found, 'matched_verb': matched_verb, 'is_visited': is_visited } planet_visits.append(visit_data) visited = any(v['is_visited'] for v in planet_visits) visit_count = sum(1 for v in planet_visits if v['is_visited']) all_planet_checks.append({ 'planet': planet_name, 'total_mentions': len(planet_visits), 'visited_mentions': visit_count, 'is_visited': visited, 'examples': [v for v in planet_visits if v['is_visited']][:3] # Первые 3 примера }) if visited: visited_planets.append({ 'planet': planet_name, 'total_mentions': len(planet_visits), 'visited_mentions': visit_count, 'examples': [v for v in planet_visits if v['is_visited']][:3] }) return visited_planets, all_planet_checks
Всего получилось, что из большого количества известных человечеству на тот момент разных планет, Алиса бывала на 12 из них. Наверное, это не так мало, учитывая что на момент описываемых событий девочке было 10 лет и кроме путешествий по космосу, ей нужно было еще успевать учиться.
Далее я использовал библиотеку plotly для визуализации. Вот какая карта путешествий Алисы Селезневой в космосе у меня получилась.

И так же посчитал, как часто Алиса бывала на тех или иных планетах своей Вселенной.

