Главная страница

Сборник. Сборник упражнений


Скачать 1.68 Mb.
НазваниеСборник упражнений
Дата18.02.2023
Размер1.68 Mb.
Формат файлаpdf
Имя файлаСборник.pdf
ТипСборник
#942935
страница8 из 14
1   ...   4   5   6   7   8   9   10   11   ...   14

Глава
7
Файлы и исключения
Все программы, которые вы писали до сих пор, считывали данные с кла- виатуры. В связи с этим пользователю необходимо было повторять ввод каждый раз, когда программа запускалась. Но это бывает не слишком удобно, особенно если речь идет о большом массиве входных данных.
Также все ваши предыдущие программы выводили результаты исключи- тельно на экран. Это нормально, если дело касается нескольких строчек, предназначенных для пользователя программы. Но если выходных дан- ных будет много или они могут потребоваться в дальнейшем для анализа в другой программе, вариант с выводом на экран просто не подойдет.
Эффективная работа с файлами решит обе перечисленные проблемы.
Файлы можно назвать относительно постоянным местом хранения ин- формации. Данные, которые записываются в файл в процессе выполнения программы, остаются в нем после завершения ее работы и даже после выключения компьютера. Это позволяет хранить в файлах информацию, которая может быть необходимой на протяжении определенного перио- да времени или служить источником данных для сторонних программ, запус каемых многократно. Вы наверняка сталкивались в работе с тексто- выми файлами, электронными таблицами, изображениями и видео. Да и сами программы на языке Python хранятся в файлах.
Файлы обычно делятся на текстовые и двоичные, или бинарные. В тек- стовых файлах хранятся исключительно последовательности битов, пред- ставляющие собой символы в определенной кодировке, например ASCII или UTF-8. Подобные файлы можно просматривать и редактировать при помощи текстовых редакторов. Все программы, которые вы писали до сих пор, сохранялись на диске в виде текстовых файлов.
Подобно текстовым, двоичные файлы также хранят последовательность битов, представляющую определенные данные. Отличие состоит в том, что эти данные не ограничиваются одними только символами. Файлы, содержащие изображения, звук или видео, являются типичными приме- рами двоичных файлов. В данной книге мы ограничимся работой с текс- товыми файлами, поскольку их легко создавать и просматривать в ва-

126
Упражнения шем любимом редакторе. При этом большинство действий и принципов, применяемых к текстовым файлам, прекрасно работают и в отношении двоичных файлов.
7.1. о
ткрытие
файлов
Чтобы начать процесс чтения данных из файла, его предварительно следу- ет открыть. То же самое необходимо сделать и перед записью информации в файл. Открыть файл в Python можно при помощи функции open.
Функция open принимает два аргумента. Первый из них указывает имя файла, который необходимо открыть. Второй аргумент также является текстовым и характеризует режим доступа (access mode) к файлу. Мы бу- дем работать с тремя режимами доступа к файлу: на чтение (r), запись (w) и добавление (a).
В качестве выходного значения функция open возвращает файловый
объект (file object). При этом функция с аргументами обычно указывается справа от знака присваивания, а переменная, характеризующая файловый объект, – слева, как показано ниже.
inf = open("input.txt", "r")
После открытия файла к соответствующему ему файловому объекту можно применять методы, позволяющие извлекать информацию. То же самое можно сказать и о записи данных в файл – методы будут другие, а принципы те же. Эти методы мы подробно рассмотрим в следующих разделах главы. После завершения чтения или записи файл должен быть закрыт, для чего применяется соответствующий метод close.
7.2. ч
тение
из
файла
Существуют разные методы для чтения данных из открытого ранее файла.
Все они могут применяться только при условии, что файл открыт в режиме чтения. Попытка прочитать данные из файла, который открыт на запись или добавление, приведет к возникновению ошибки.
Метод readline позволяет считать одну строку из открытого файла и вер- нуть ее в качестве строкового значения – подобно тому, как функция input считывает пользовательский ввод с клавиатуры. Каждый очередной вы- зов метода readline будет возвращать следующую строку из файла. При достижении конца файла метод вернет пустую строку.
Представьте, что у вас есть файл, в котором на каждой строке распо- лагаются числа. В следующем фрагменте кода мы подсчитаем их сумму.

Файлы и исключения

127
# Запрашиваем у пользователя имя файла и открываем его fname = input("Введите имя файла: ")
inf = open(fname, "r")
# Инициализируем сумму total = 0
# Подсчитываем сумму line = inf.readline()
while line != "":
total = total + float(line)
line = inf.readline()
# Закрываем файл inf.close()
# Отображаем результат print("Сумма значений в файле", fname, "равна", total)
В начале программы мы запрашиваем у пользователя имя файла, ко- торый необходимо открыть. После этого указанный файл открывается в режиме чтения, а ссылка на него возвращается в переменную inf. За- тем инициализируем общую сумму нулем и считываем первую строку из файла.
В цикле while указано условное выражение, пропускающее в тело цикла только в случае, если считанная строка не является пустой. В самом теле считанная из файла строка преобразуется в число с плавающей запятой и добавляется к общей сумме. После этого из файла считывается следую- щая строка, и управление снова передается условному выражению цикла.
По достижении конца файла метод readline вернет пустую строку, кото- рая будет сохранена в переменной line. Это приведет к тому, что условное выражение вернет значение False, и цикл завершится. После закрытия файла на экран выводится общая сумма.
Иногда бывает полезно считать все данные из файла за один заход, а не построчно. Это можно сделать при помощи методов read и readlines.
При этом метод read возвращает все содержимое файла как одну длинную строку, которую при дальнейшей обработке приходится вручную разби- вать на составляющие элементы. Метод readlines, в свою очередь, возвра- щает содержимое файла в виде списка строк. После завершения чтения можно пройти по созданному списку при помощи цикла и на каждой ите- рации извлекать по одной строке. В следующем фрагменте кода демон- стрируется метод readlines для подсчета суммы значений из исходного файла. Здесь происходит полное считывание содержимого файла вместо получения каждой отдельной строки в цикле.
# Запрашиваем у пользователя имя файла и открываем его fname = input("Введите имя файла: ")

128
Упражнения inf = open(fname, "r")
# Инициализируем сумму total = 0
lines = inf.readlines()
# Подсчитываем сумму for line in lines:
total = total + float(line)
# Закрываем файл inf.close()
# Отображаем результат print("Сумма значений в файле", fname, "равна", total)
7.3. с
имволы
конца
строки
В следующем примере метод readline используется для последовательно- го вывода всех строк из файла. Каждой строке будет предшествовать ее порядковый номер и двоеточие.
# Запрашиваем у пользователя имя файла и открываем его fname = input("Введите имя файла для отображения: ")
inf = open(fname, "r")
# Инициализируем порядковый номер строки num = 1
# Отображаем строки из файла, предваряя их порядковыми номерами line = inf.readline()
while line != "":
print("%d: %s" % (i, line))
# Увеличиваем номер строки и считываем следующую строку num = num + 1
line = inf.readline()
# Закрываем файл inf.close()
При запуске данной программы вы будете удивлены тем, что она вы- ведет – после каждой строки будет следовать еще одна строка, пустая.
Причина этого в том, что каждая строка в текстовом файле оканчивается одним или несколькими символами конца строки.

Файлы и исключения

129
Примечание. Символы конца строки и их количество отличаются в разных опера- ционных системах. К счастью, в Python существует автоматическая поддержка этих различий, и текстовый файл, созданный в любой операционной системе, может быть корректно прочитан в Python.
Символы конца строки необходимы для того, чтобы любая программа, считывающая файл, могла без труда определить, где заканчивается одна строка и начинается другая. Если бы не эти символы, при любом считыва- нии данных все содержимое файла оказывалось бы в вашей переменной, а при открытии файла в текстовом редакторе все строки были бы нераз- рывно связаны.
Маркер окончания строки может быть удален после чтения из файла при помощи метода rstrip. Этот метод, который может быть применен к абсолютно любой строке, избавляет ее от всех примыкающих справа
пробельных символов (whitespace character), в число которых входят про- бел, символ табуляции и маркеры конца строки. Метод возвращает копию исходной строки без этих специальных символов в конце строки.
Обновленный фрагмент кода программы представлен ниже. Здесь ис- пользуется метод rstrip для удаления символов конца строки, что по- зволило избавиться от пустых строк при выводе содержимого файла на экран.
# Запрашиваем у пользователя имя файла и открываем его fname = input("Введите имя файла для отображения: ")
inf = open(fname, "r")
# Инициализируем порядковый номер строки num = 1
# Отображаем строки из файла, предваряя их порядковыми номерами line = inf.readline()
while line != "":
# Удаляем символы конца строки и отображаем строку на экране
line = line.rstrip() print("%d: %s" % (i, line))
# Увеличиваем номер строки и считываем следующую строку num = num + 1
line = inf.readline()
# Закрываем файл inf.close()

130
Упражнения
7.4. з
апись
в
файл
Когда файл открывается в режиме записи, происходит создание нового файла. В случае если файл с таким именем уже существует, он будет пред- варительно удален, а все данные, содержащиеся в нем, будут потеряны.
Если открыть существующий файл в режиме добавления, любые данные, которые будут записываться в него, будут добавляться в конец файла. При отсутствии на диске файла попытка его открытия в режиме добавления приведет к созданию нового файла с таким именем.
Для пополнения информацией файла, предварительно открытого на запись или добавление, можно использовать метод write. Этот метод при- нимает в качестве входного параметра строку, которая будет записана в открытый файл. Данные других типов могут быть преобразованы в стро- ковый тип при помощи функции str. Несколько значений могут быть за- писаны в файл путем их предварительного склеивания в одну длинную строку или посредством многократного вызова метода write.
В отличие от функции print, метод write автоматически не вставляет символ перевода строки при записи в файл. Таким образом, разработчику необходимо самому позаботиться о том, чтобы значения, которые должны находиться в файле на разных строках, были явно разделены символами конца строки. В языке Python используется сочетание символов \n для обозначения маркера конца строки. Эти символы, входящие в список es-
cape­последовательностей (escape sequence), могут присутствовать в стро- ке сами по себе или как ее составная часть.
В следующем фрагменте кода мы запишем числа от единицы до вве- денного пользователем значения в файл. Операция конкатенации и es- cape-последовательность \n используются так, чтобы числа располагались строго на своих строках.
# Запрашиваем имя файла у пользователя и открываем его на запись fname = input("В каком файле сохранить последовательность чисел? ")
outf = open(fname, "w")
# Запрашиваем максимальное значение limit = int(input("Введите максимальное число: "))
# Пишем числа в файл – каждое в своей строке for num in range(1, limit + 1):
outf.write(str(num) + "\n")
# Закрываем файл outf.close()

Файлы и исключения

131
7.5. а
ргументы
командной
строки
Обычно компьютерные программы запускаются путем двойного щелчка по соответствующему ярлыку. Но программы также могут быть запущены из командной строки путем ввода соответствующей команды в окно тер- минала или окно управления командной строкой. Например, во многих операционных системах программу на Python, сохраненную в файле test.
py
, можно запустить, написав test.py или python test.py в соответствую- щем окне.
Запуск программы из командной строки открывает дополнительные возможности для передачи ей параметров. Значения, необходимые про- грамме для выполнения своей задачи, могут быть переданы непосред- ственно в запускающей строке после расширения файла .py. Такая воз- можность бывает очень полезна при написании скриптов, запускающих другие программы с целью автоматизации каких-либо процессов, а также при создании программ, которые должны запускаться по определенному расписанию.
Все аргументы командной строки, передаваемые в программу, сохраня- ются во внутренней переменной argv, располагающейся в модуле sys. По своей сути эта переменная является списком, и каждый входной параметр размещается в нем в виде отдельного строкового элемента. При этом лю- бой элемент из списка может быть преобразован в нужный тип данных при помощи стандартных функций вроде int и float. Первым элементом списка argv является имя файла Python, который в данный момент за- пущен. Следом за ним идут переданные посредством командной строки параметры.
На примере следующей программы мы продемонстрируем доступ к ар- гументам командной строки непосредственно из кода. Программа начи- нается с вывода на экран количества элементов в переменной argv и име- ни запущенного файла. После этого на экран выводятся все переданные программе параметры. Если программа была запущена без параметров, будет показано соответствующее сообщение.
# Для доступа к переменным командной строки необходимо импортировать модуль sys import sys
# Отображаем количество аргументов (включая название файла .py)
print("Программа насчитывает", len(sys.argv), \
"аргументов командной строки.")
# Выводим на экран имя файла .py print("Имя запущенного файла .py: ", sys.argv[0])
# Определяем, есть ли другие переданные параметры if len(sys.argv) > 1:

132
Упражнения
# Отображаем все переданные параметры, за исключением имени файла print("Остальные аргументы:")
for i in range(1, len(sys.argv)):
print(" ", sys.argv[i])
else:
print("Дополнительных аргументов нет.")
Аргументы командной строки можно использовать для передачи про- грамме любых входных значений, которые можно физически ввести в ко- мандную строку, то есть строк, целочисленных значений и чисел с плава- ющей запятой. Эти значения могут быть использованы в программе, как и любые другие. Взгляните на обновленный пример программы, сумми- рующей перечисленные в строках числа. Здесь имя файла мы не будем за- прашивать у пользователя, а передадим посредством командной строки.
# Импортируем системный модуль import sys
# Отслеживаем, чтобы программа обязательно запускалась с одним переданным параметром if len(sys.argv) != 2:
print("Имя файла необходимо передать в качестве", \
"аргумента.")
quit()
# Открываем на чтение файл, имя которого было передано в командной строке inf = open(sys.argv[1], "r")
# Инициализируем сумму нулем total = 0
# Суммируем значения в файле line = inf.readline()
while line != "":
total = total + float(line)
line = inf.readline()
# Закрываем файл inf.close()
# Выводим результат print("Сумма значений в файле", sys.argv[1], "составляет", total)
7.6. и
сключения
Во время выполнения программы много что может пойти не так: пользо- ватель может ввести строковое значение вместо числового, может возник- нуть ошибка деления на ноль, пользователь может запросить на открытие

Файлы и исключения

133
файл, которого не существует, да мало ли что. Все подобные ошибки на- зываются исключениями (exception). По умолчанию программы, написан- ные на языке Python, прекращают свое выполнение при возникновении исключений. Но мы всегда можем предотвратить такое поведение, если заранее предпримем ряд мер.
Разработчик имеет возможность указать программе, в каком месте мо- жет возникнуть исключение, чтобы была возможность его перехватить и соответствующим образом обработать, тем самым защитив программу от аварийного завершения. Для этого в языке Python предусмотрено два ключевых слова, с которыми мы раньше не сталкивались: это try и except.
Код, который может вызвать возникновение исключения, предусмотри- тельно помещается в блок try, следом за которым располагается альтерна- тивный блок except. Когда в блоке try возникает исключение, выполнение программы немедленно переносится в соответствующий блок except без выполнения оставшихся инструкций в блоке try.
В каждом блоке except может быть явно указан тип исключения, для перехвата которого предназначен этот блок. Это можно сделать, указав необходимый тип исключения непосредственно после ключевого слова except
. В этом случае только указанный тип исключения будет обрабаты- ваться при помощи данного блока. Без указания конкретного типа ис- ключения блок except будет перехватывать все возникающие исключения, которые ранее не были обработаны другими блоками except, принадле- жащими тому же блоку try. Необходимо четко понимать, что инструкции из блока except будут выполнены только в случае возникновения исклю- чения. Если же выполнение блока try пройдет нормально, следующие за ним блоки except будут просто пропущены, и выполнение программы продолжится с первой строки кода, следующей за последним блоком ex- cept соответствующего блока try.
Все программы, которые мы писали до сих пор в этой главе, аварийно завершали свою работу при вводе пользователем несуществующего имени файла. Это объясняется тем, что в данный момент возникало исключение
FileNotFoundError
, которое не было перехвачено. В следующем фрагменте кода мы исправим это упущение и обработаем данное исключение с вы- водом соответствующего сообщения. После указанного фрагмента можно добавить любой код для обработки информации из открытого файла.
# Запрашиваем имя файла у пользователя fname = input("Введите имя файла: ")
# Попытка открыть файл try:
inf = open(fname, "r")
except FileNotFoundError:
# Показываем сообщение и выходим из программы, если возникла проблема при открытии
# файла

134
Упражнения print("Невозможно открыть файл '%s'. Выходим...")
quit()
Данная версия программы будет аккуратно закрываться с предупреж- дением, если файл, к которому хочет обратиться пользователь, не сущест- вует по указанному адресу. И хотя иногда такое поведение программы будет приемлемым, чаще мы захотим дать пользователю возможность повторно ввести имя файла для открытия. При этом и со второй попытки у него может не получиться ввести правильное имя файла. Организуем цикл, успешный выход из которого возможен только после ввода коррект- ного имени файла. Обратите внимание, что оба блока – try и except – на- ходятся внутри цикла while.
# Запрашиваем имя файла у пользователя fname = input("Введите имя файла: ")
file_opened = False while file_opened == False:
# Попытка открыть файл try:
inf = open(fname, "r")
file_opened = True except FileNotFoundError:
# Показываем сообщение и запрашиваем имя файла повторно print("Файл '%s' не найден. Попробуйте еще.")
fname = input("Введите имя файла: ")
В начале программы у пользователя запрашивается имя файла. После этого переменной file_opened присваивается значение False, и цикл запус- кается в первый раз. В теле цикла размещается блок try с двумя строками кода. В первой из них выполняется попытка открытия файла. Если файла нет, будет сгенерировано исключение типа FileNotFoundError, в результате чего выполнение программы продолжится в соответствующем блоке ex- cept
, тогда как вторая строка в блоке try так и останется невыполненной.
В блоке except на экран выводится сообщение об ошибке и производится повторный запрос имени файла у пользователя.
Выполнение программы возвращается к первой строке цикла, где про- исходит проверка условия file_opened == False. Это условие возвращает истину, и программа вновь входит в блок try, пытаясь открыть файл, имя которого пользователь ввел повторно. Если и такого файла не сущест- вует, все повторится согласно описанному выше алгоритму. Если же файл найти удалось, исключения не возникает, и выполнение программы пе- реходит ко второй строке в блоке try, где переменной file_opened при- сваивается значение True. В результате блок except пропускается, цикл возвращается на начало и тут же завершается, поскольку условие цикла не выполняется.

Файлы и исключения

135
Концепция, описанная в данной главе, может быть использована для идентификации и обработки всех возможных исключений, которые могут возникать в процессе выполнения программы. Наличие блоков try и ex- cept позволит вам уберечь свою программу от аварийного завершения и должным образом обрабатывать все возникающие ошибки.
7.7. у
пражнения
В большинстве упражнений из данной главы вам придется работать с фай- лами. В каких-то из них содержание файлов будет не важно, в других вам придется заранее создать и заполнить их при помощи любого текстового редактора. Будут в этой главе и упражнения на чтение конкретных дан- ных, таких как список слов, имен или химических элементов. Эти наборы данных можно скачать с сайта автора по следующей ссылке: http://www.
cpsc.ucalgary.ca/

bdstephe/PythonWorkbook
Упражнение 149. Отображаем начало файла
(Решено. 40 строк)
В операционных системах на базе Unix обычно присутствует утилита с на- званием head. Она выводит первые десять строк содержимого файла, имя которого передается в качестве аргумента командной строки. Напиши- те программу на Python, имитирующую поведение этой утилиты. Если файла, указанного пользователем, не существует, или не задан аргумент командной строки, необходимо вывести соответствующее сообщение об ошибке.
Упражнение 150. Отображаем конец файла
(Решено. 35 строк)
Продолжая тему предыдущего упражнения, в тех же операционных систе- мах на базе Unix обычно есть и утилита с названием tail, которая отобра- жает последние десять строк содержимого файла, имя которого пере- дается в качестве аргумента командной строки. Реализуйте программу, которая будет делать то же самое. Так же, как и в упражнении 149, в случае отсутствия файла, указанного пользователем, или аргумента командной строки вам нужно вывести соответствующее сообщение.
Данную задачу можно решить сразу несколькими способами. Напри- мер, можно все содержимое файла целиком загрузить в список и затем выбрать из него последние десять элементов. А можно дважды прочи- тать содержимое файла: первый раз, чтобы посчитать количество строк, а второй – чтобы отобразить последние десять из них. При этом оба пере-

136
Упражнения численных подхода нежелательны, если речь идет о файлах достаточного объема. Существует решение, требующее единственного чтения файла и сохранения всех десяти строк за раз. В качестве дополнительного за- дания разработайте такой алгоритм.
Упражнение 151. Сцепляем файлы
(Решено. 28 строк)
Продолжаем тему операционных систем на базе Unix, в которых обычно также есть утилита с названием cat, что является сокращением от concat- enate (сцепить). Эта утилита выводит на экран объединенное содержимое нескольких файлов, имена которых передаются ей в качестве аргументов командной строки. При этом файлы сцепляются в том порядке, в котором указаны в аргументах.
Напишите программу на Python, имитирующую работу этой утилиты.
В процессе работы программа должна выдавать сообщения о том, какие файлы открыть не удается, и переходить к следующим файлам. Если про- грамма была запущена без аргументов командной строки, на экран долж- но быть выведено соответствующее сообщение об ошибке.
Упражнение 152. Нумеруем строки в файле
(23 строки)
Напишите программу, которая будет считывать содержимое файла, до- бавлять к считанным строкам порядковый номер и сохранять их в таком виде в новом файле. Имя исходного файла необходимо запросить у поль- зователя, так же, как и имя целевого файла. Каждая строка в созданном файле должна начинаться с ее номера, двоеточия и пробела, после чего должен идти текст строки из исходного файла.
Упражнение 153. Самое длинное слово в файле
(39 строк)
В данном упражнении вы должны написать программу, которая будет находить самое длинное слово в файле. В качестве результата программа должна выводить на экран длину самого длинного слова и все слова такой длины. Для простоты принимайте за значимые буквы любые непробель- ные символы, включая цифры и знаки препинания.
Упражнение 154. Частота букв в файле
(43 строки)
Одна из техник декодирования простейших алгоритмов шифрования за- ключается в применении частотного анализа. Иными словами, вы просто

Файлы и исключения

137
анализируете зашифрованный текст, подсчитывая частоту употребления всех букв. Затем можно использовать операции подстановки для замены наиболее популярных символов на часто используемые в языке буквы
(в английском это, например, буквы E и T).
Напишите программу, которая будет способствовать дешифрации тек- ста путем вывода на экран частоты появления разных букв. При этом пробелы, знаки препинания и цифры должны быть проигнорированы.
Также не должен учитываться регистр, то есть символы a и A должны вос- приниматься как одна буква. Имя файла для анализа пользователь должен передавать программе посредством аргумента командной строки. Если программе не удастся открыть файл для анализа или аргументов команд- ной строки будет слишком много, на экране должно быть отображено соответствующее сообщение об ошибке.
Упражнение 155. Частота слов в файле
(37 строк)
Разработайте программу, которая будет показывать слово (или слова), чаще остальных встречающееся в текстовом файле. Сначала пользователь должен ввести имя файла для обработки. После этого вы должны открыть файл и проанализировать его построчно, разделив при этом строки по словам и исключив из них пробелы и знаки препинания. Также при под- счете частоты появления слов в файле вам стоит игнорировать регистры.
Подсказка. Возможно, при решении этого задания вам поможет код, реализованный вами в упражнении 117.
Упражнение 156. Сумма чисел
(Решено. 26 строк)
Напишите программу, которая будет суммировать все числа, введенные пользователем, игнорируя при этом нечисловой ввод. Выводите на экран текущую сумму чисел после каждого очередного ввода. Ввод пользовате- лем значения, не являющегося числовым, должен приводить к появлению соответствующего предупреждения, после чего пользователю должно быть предложено ввести следующее число. Выход из программы будет осуществ- ляться путем пропуска ввода. Удостоверьтесь, что ваша программа коррект- но обрабатывает целочисленные значения и числа с плавающей запятой.
Подсказка. В данном упражнении вам придется поработать не с файлами, а с ис- ключениями.

138
Упражнения
Упражнение 157. Буквенные и числовые оценки
(106 строк)
Напишите программу, выполняющую перевод из буквенных оценок в чис- ловые и обратно. Программа должна позволять пользователю вводить несколько значений для перевода – по одному в каждой строке. Для на- чала предпримите попытку сконвертировать введенное пользователем значение из числового в буквенное. Если возникнет исключение, попро- буйте выполнить обратное преобразование – из буквенного в числовое.
Если и эта попытка окончится неудачей, выведите предупреждение о том, что введенное значение не является допустимым. Пусть ваша програм- ма конвертирует оценки до тех пор, пока пользователь не оставит ввод пустым. При решении данного задания вам могут помочь наработки из упражнений 52 и 53.
Упражнение 158. Удаляем комментарии
(Решено. 53 строки)
Как вы знаете, в языке Python для создания комментариев в коде исполь- зуется символ #. Комментарий начинается с этого символа и продолжает- ся до конца строки – без возможности остановить его раньше.
В данном упражнении вам предстоит написать программу, которая будет удалять все комментарии из исходного файла с кодом на языке
Python. Пройдите по всем строкам в файле на предмет поиска символа
#. Обнаружив его, программа должна удалить все содержимое, начиная с этого символа и до конца строки. Для простоты не будем рассматривать ситуации, когда знак решетки встречается в середине строки. Сохраните новое содержимое в созданном файле. Имена файла источника и фай- ла назначения должны быть запрошены у пользователя. Удостоверьтесь в том, что программа корректно обрабатывает возможные ошибки при работе с обоими файлами.
Упражнение 159. Случайный пароль из двух слов
(Решено. 39 строк)
Создание пароля посредством генерирования случайных символов может обернуться сложностью в запоминании полученной относительно надеж- ной последовательности. Некоторые системы создания паролей рекомен- дуют сцеплять вместе два слова на английском языке, тем самым упрощая запоминание заветного ряда символов – правда, в ущерб его надежности.
Напишите программу, которая будет открывать файл со списком слов, случайным образом выбирать два из них и сцеплять вместе для получения итогового пароля. При создании пароля исходите из следующего требо- вания: он должен состоять минимум из восьми символов и максимум из

Файлы и исключения

139
десяти, а каждое из используемых слов должно быть длиной хотя бы в три буквы. Кроме того, сделайте заглавными первые буквы обоих слов, чтобы легко можно было понять, где заканчивается одно и начинается другое.
По завершении процесса полученный пароль должен быть отображен на экране.
Упражнение 160. Странные слова
(67 строк)
Ученикам, желающим запомнить правила написания слов в английском языке, часто напоминают следующее рифмованное одностишие: «I before
E except after C» (I перед E, если не после C). Это правило позволяет за- помнить, в какой последовательности писать буквы I и E, идущие в слове одна за другой, а именно: буква I должна предшествовать букве E, если непосредственно перед ними не стоит буква C. Если стоит – порядок глас- ных будет обратным. Примеры слов, на которые действует это правило: believe, chief, fierce, friend, ceiling и receipt. Но есть и исключения из этого правила, и одним из них является слово weird (странный).
Напишите программу, которая будет построчно обрабатывать тексто- вый файл. В каждой строке может присутствовать много слов, а может и не быть ни одного. Слова, в которых буквы E и I не соседствуют друг с другом, обработке подвергать не следует. Если же такое соседство присутствует, необходимо проверить, соответствует ли написание анализируемого сло- ва указанному выше правилу. Создайте и выведите на экран два списка.
В первом должны располагаться слова, следующие правилу, а во втором – нарушающие его. При этом списки не должны содержать повторяющиеся слова. Также отобразите на экране длину каждого списка, чтобы пользо- вателю было понятно, сколько слов в файле не отвечает правилу.
Упражнение 161. Что за химический элемент?
(59 строк)
Напишите программу, которая будет считывать файл, содержащий ин- формацию о химических элементах, и сохранять ее в более подходящей для этого структуре данных. После этого пользователь должен ввести зна- чение. Если введенное значение окажется целочисленным, программа должна вывести на экран обозначение и название химического элемента с введенным количеством протонов. При вводе пользователем строки не- обходимо отобразить количество протонов элемента с введенным поль- зователем обозначением или названием. Если введенное пользователем значение не соответствует ни одному из элементов в файле, необходимо вывести соответствующее сообщение об ошибке. Позвольте пользователю вводить значения до тех пор, пока он не оставит ввод пустым.

140
Упражнения
Упражнение 162. Книги без буквы E
(Решено. 50 строк)
Истории литературы известен случай написания романа объемом около
50 тыс. слов, в котором ни разу не была употреблена самая популярная в английском алфавите буква E. Название его – «Gadsby».
Напишите программу, которая будет считывать список слов из файла и собирать статистику о том, в каком проценте слов используется каждая буква алфавита. Выведите результат для всех 26 букв английского алфа- вита и отдельно отметьте букву, которая встречалась в словах наиболее редко. В вашей программе должны игнорироваться знаки препинания и регистр символов.
Примечание. Липограмма представляет собой литературный прием, состоящий в на- писании текста без использования одной из букв (или группы букв). Часто отвергнутой буквой является одна из распространенных гласных, хотя это условие и не обязатель- но. Например, в стихотворении Эдгара Аллана По «Ворон» («The Raven»), состоящем из более тысячи слов, ни разу не встречается буква Z, что делает его полноценной ли- пограммой. Еще одним примером липограммы является роман «Исчезание» («La Dis- parition»). Во французской и английской версиях этого произведения общим объемом примерно в 300 страниц не употребляется буква E, за исключением фамилии автора.
Упражнение 163. Популярные детские имена
(Решено. 54 строки)
Набор данных, содержащий детские имена, состоит более чем из 200 фай- лов, в каждом из которых, помимо сотни имен, указано количество на- званных тем или иным именем детей. При этом файлы отсортированы по убыванию популярности имен. Для каждого года присутствует по два файла: в одном перечислены мужские имена, в другом – женские. Со- вокупный набор данных содержит информацию для всех лет, начиная с 1900-го и заканчивая 2012-м.
Напишите программу, которая будет считывать по одному все файлы из набора данных и выделять имена, которые были лидерами по частоте использования как минимум в одном году. На выходе должно получиться два списка: в одном из них будут присутствовать наиболее популярные имена для мальчиков, во втором – для девочек. При этом списки не долж- ны содержать повторяющиеся имена.
Упражнение 164. Универсальные имена
(56 строк)
Некоторые имена, такие как Бен, Джонатан и Эндрю, подходят только для мальчиков, другие – Ребекка или Флора – только для девочек. Но есть

Файлы и исключения

141
и универсальные имена наподобие Крис или Алекс, которые могут носить и мальчики, и девочки.
Напишите программу, которая будет выводить на экран имена, ис- пользованные для мальчиков и девочек в указанном пользователем году. Если в этом году универсальных имен не было, нужно известить об этом пользователя. Кроме того, если за указанный пользователем год не было данных по именам, выведите соответствующее сообщение об ошибке. Дополнительные детали по хранению имен в файлах – в упраж- нении 163.
Упражнение 165. Самые популярные имена за период
(76 строк)
Напишите программу, которая будет определять самые популярные имена для детей в выбранном пользователем периоде. Используйте базу данных из упражнения 163. Позвольте пользователю выбрать первый и последний год анализируемого диапазона. В результате программа должна вывести на экран мужское и женское имена, которые были чаще остальных даны детям в заданный период времени.
Упражнение 166. Имена без повторов
(41 строка)
Продолжаем использовать базу имен из упражнения 163. Проходя по фай- лам, выберите имена без дублирования отдельно для мальчиков и для девочек и выведите их на экран. Разумеется, повторяющихся имен в этих списках быть не должно.
Упражнение 167. Проверяем правильность написания
(Решено. 58 строк)
Автоматическая проверка орфографии не помешала бы многим из нас.
В данном упражнении мы напишем простую программу, сверяющую сло- ва из текстового файла со словарем. Неправильно написанными будем считать все слова, которых не нашлось в словаре.
Имя файла, в котором требуется выполнить орфографическую проверку, пользователь должен передать при помощи аргумента командной стро- ки. В случае отсутствия аргумента должна выдаваться соответствующая ошибка. Сообщение об ошибке также должно появляться, если не удается открыть указанный пользователем файл. Используйте свои наработки из упражнения 117 при решении данной задачи, чтобы знаки препинания не мешали вам проводить орфографический анализ текста. Также вам следует игнорировать регистр символов при выполнении проверки.

142
Упражнения
Подсказка. Конечно, вы могли бы загрузить все слова из текста в список и анализи- ровать их при помощи функции оператора in. Но эта операция будет выполняться довольно долго. Гораздо быстрее в Python выполняется проверка на наличие опре- деленного ключа в словаре или значения в наборе. Если вы остановитесь на вариан- те со словарем, ключами должны стать слова, а значениями – ноль или любое другое число, поскольку их мы в данном случае использовать не будем.
Упражнение 168. Повторяющиеся слова
(61 строка)
Проверка орфографии – лишь составная часть расширенного текстового анализа на предмет наличия ошибок. Одной из самых распространенных ошибок в текстах является повторение слов. Например, автор может по ошибке дважды подряд написать одно слово, как в следующем примере:
At least one value must be entered
entered in order to compute the average.
Некоторые текстовые процессоры умеют распознавать такой вид оши- бок при выполнении текстового анализа.
В данном упражнении вам предстоит написать программу для опреде- ления наличия дублей слов в тексте. При нахождении повтора на экран должен выводиться номер строки и дублирующееся слово. Удостоверь- тесь, что программа корректно обрабатывает случаи, когда повторяющие- ся слова находятся на разных строках, как в предыдущем примере. Имя файла для анализа должно быть передано программе в качестве един- ственного аргумента командной строки. При отсутствии аргумента или невозможности открыть указанный файл на экране должно появляться соответствующее сообщение об ошибке.
Упражнение 169. Редактирование текста в файле
(Решено. 52 строки)
Перед публикацией текста или документа обычно принято удалять или изменять в них служебную информацию.
В данном упражнении вам необходимо написать программу, которая будет заменять все служебные слова в тексте на символы звездочек (по количеству символов в словах). Вы должны осуществлять регистрозави- симый поиск служебных слов в тексте, даже если эти слова входят в состав других слов. Список служебных слов должен храниться в отдельном файле.
Сохраните отредактированную версию исходного файла в новом файле.
Имена исходного файла, файла со служебными словами и нового файла должны быть введены пользователем.

Файлы и исключения

143
Примечание. Вам может пригодиться метод replace для работы со строками при решении этого задания. Информацию о работе данного метода можно найти в ин- тернете.
В качестве дополнительного задания расширьте свою программу таким образом, чтобы она выполняла замену служебных слов вне зависимости от того, какой регистр символов используется в тексте. Например, если в спис- ке служебных слов будет присутствовать слово exam, то все следую щие вари- анты слов должны быть заменены звездочками: exam, Exam, ExaM и EXAM.
Упражнение 170. Пропущенные комментарии
(Решено. 48 строк)
При написании функций хорошей практикой считается предварение ее блоком комментариев с описанием назначения функции, ее входных па- раметров и возвращаемого значения. Но некоторые разработчики просто не пишут комментарии к своим функциям. Другие честно собираются на- писать их когда-нибудь в будущем, но руки так и не доходят.
Напишите программу, которая будет проходить по файлу с исходным кодом на Python и искать функции, не снабженные блоком комментариев.
Можно принять за аксиому, что строка, начинающаяся со слова def, сле- дом за которым идет пробел, будет считаться началом функции. И если функция документирована, предшествующая строчка должна начинаться со знака #. Перечислите названия всех функций, не снабженных коммен- тариями, вместе с именем файла и номером строки, с которой начинается объявление функции.
Одно или несколько имен файлов с кодом на языке Python пользователь должен передать в функцию в качестве аргументов командной строки.
Для файлов, которые не существуют или не могут быть открыты, должны выдаваться соответствующие предупреждения, после чего должна быть продолжена обработка остальных файлов.
Упражнение 171. Строки фиксированной длины
(45 строк)
Ширина окна терминала обычно составляет 80 символов, хотя есть бо- лее широкие и узкие терминалы. Это затрудняет отображение текстов, разбитых на абзацы. Бывает, что строки в исходном файле оказываются слишком длинными и автоматически переносятся, тем самым затрудняя чтение, или слишком короткими, что приводит к недостаточному запол- нению свободного места на экране.
Напишите программу, которая будет открывать файл и выводить его на экран с постоянной длиной строк. Если в исходном файле строка ока-

144
Упражнения зывается слишком длинной, «лишние» слова должны быть перенесены на следующую строку, а если слишком короткой, слова со следующей строки должны перекочевать в конец текущей до полного ее заполнения. Напри- мер, следующий отрывок из «Алисы в Стране чудес»:
Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, "and what is the use of a book," thought Alice, "without pictures or conversations?" в отформатированном виде с длиной строки в 50 символов будет выгля- деть так:
Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, "and what is the use of a book," thought Alice, "without pictures or conversations?"
Убедитесь, что ваша программа корректно обрабатывает тексты, в ко- торых присутствуют абзацы. Идентифицировать конец одного абзаца и начало другого можно по наличию пустой строки в тексте после удале- ния символа конца строки.
Подсказка. Используйте константу для задания максимальной ширины строк. Это позволит вам легко адаптировать программу под любые окна.
Упражнение 172. Слова с шестью гласными в ряд
(56 строк)
Существует как минимум одно слово в английском языке, содержащее все гласные буквы в том порядке, в котором они расположены в алфавите, а именно A, E, I, O, U и Y. Напишите программу, которая будет просматри- вать текстовый файл на предмет поиска и отображения таких слов. Имя исходного файла должно быть запрошено у пользователя. Если имя файла окажется неверным или возникнут иные ошибки при чтении файла, вы- ведите соответствующее сообщение об ошибке.

1   ...   4   5   6   7   8   9   10   11   ...   14


написать администратору сайта