Kodomo

Пользователь

Учебная страница курса биоинформатики,
год поступления 2019

Python, материалы к занятию 3

Подключение модулей

>>> dir(math)

Смысл конкретной функции (например, exp из модуля math) можно посмотреть командой

>>> help(math.exp)

Правда, с константами так не получается :(. Зато получается с самими модулями

>>> help(math)

В описании модуля обычно указывают и значения констант.

from math import sin, cos

...
a = cos(x) + sin(x)
...

Если же понадобится много чего, то так:

import math

...
a = math.cos(x) + math.sin(x)
...

Кроме модуля math, вам понадобится модуль random. В модуле random имеется функция, которая возвращает случайный элемент списка. Найдите её сами с помощью dir и help. Если вам нужно случайное целое число из заданного диапазона, можно применить ту же функцию к результату встроенной функции range (хотя есть и другой способ: в модуле random имеется соответствующая функция).

Желательно все подключения из модулей делать в самом начале программы.

Список доступных модулей см. https://docs.python.org/3/library/index.html .

Аргументы командной строки

Чтобы принимать данные из командной строки, нужно вставить в начало файла с программой строку

from sys import argv

При запуске программы в переменную argv записывается список, в который попадают аргументы командной строки, то есть те слова, которые введены в командную строку после имени файла с программой. При этом первый аргумент имеет индекс 1 (а индекс 0 имеет само имя файла с программой). Например, пусть файл example.py содержит следующие строки:

from sys import argv

indata = open(argv[1], "r")
for line in indata:
    sline = line.strip()
    print(sline)
indata.close()

Если теперь запустить программу, указав в командной строке имя файла:

python3 example.py test.txt

то программа напечатает все строки файла test.txt.

Обработка ошибок в Python. Exception

Во время выполнения программы может возникнуть непредвиденный случай — "Exception". Если это никак не предусмотрено программистом, то программа, выдав исключение, аварийно завершает работу. Иногда данный сценарий для нас неприемлем: допустим, мы обрабатываем независимые файлы одной программой и время обработки каждого файла достаточно велико. В таком случае мы заинтересованы в том, чтобы программа в случае ошибки (например, отсутствие какого-то файла), не "падала", а продолжала работу с другими файлами, выдав предупреждение пользователю в консоль.

Для данной задачи в Python существует конструкция try .. except

try:
    #do some code
except:
    print("Error occurred")

Если в случае ошибки ничего делать не надо, в блок после except нужно поставить "пустой оператор" pass:

try:
    #do some code
except:
    pass

pass вообще ничего не делает, просто обозначает место, чтобы не нарушался синтаксис конструкции.

Дополнительная информация: в except можно указывать, что именно мы хотим перехватить — например, у нас возникает ошибка ValueError. Тогда вместо "except:" пишем "except ValueError:.

Хорошим стилем в Python считается "ловить то, что ловишь", то есть указывать в except имя именно той ошибки, которую вы хотите обработать. К сожалению, для этого надо знать точное имя ошибки, что не всегда удобно.

Часто можно встретить такой стиль написания:

try:
    <всё, что хотелось сделать>
except:
    print("Some error occurred, I don't care about")

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

Чтобы не писать так, можно импортировать из sys функцию exit. Например, если нужно сначала проверить, задано ли имя входного файла и если да, открывается ли файл с таким именем:

from sys import argv, exit
if len(argv) < 2:
    print("No argument provided")
    exit(1)
try:
    inf = open(argv[1], "r")
except:
    print("File {} is unavailable".format(argv[1]))
    exit(2)
<всё, что хотелось сделать> 

Измерение времени работы вашей программы (дополнительные сведения)

from time import time

start = time()
# run your code
end = time()
print("Time: ", end - start)

А еще есть модуль timeit, с помощью которого это делается еще проще. Можете изучить его самостоятельно.

PEP8 (дополнительные сведения)

Создатели языка имеют строгие рекомендации к написанию кода — как лучше писать его, какие действия приемлемы, а какие — нет.

Все это изложено в PEP8: https://www.python.org/dev/peps/pep-0008/

Основные требования к стилю кода такие.

Doc-string в начале программы

Программа на Python должна начинаться с комментария, объясняющего, что она делает. Желательно, чтобы в комментарии была информация о том, как эту программу запускать. Такой комментарий (в отличие от комментариев к отдельным строчкам, который пишется после знака #) пишется в тройных кавычках.

Названия переменных

Не стоит называть переменные, кроме индексов, одной буквой. Это мешает пониманию кода и скорее всего приведет к ошибкам.

Переменные типа cat1, cat2, cat3 и т.д хороши только в обучающих примерах.

Названия переменных должно содержать только маленькие буквы, цифры и символ подчеркивания "_" . Например, great_job — правильное название, GreatJob — неправильное название для переменной.

Названия констант (типа числа π) следует писать большими заглавными буквами и _, например, THIS_VERY_IMPORTANT_CONSTANT. Модуль math не следует этому правилу, как Вы могли заметить.

Все объявленные переменные должны использоваться. Вместо переменных, значения которых не используются, но которые приходится писать, надо ставить "пустую переменную" '_'

for _ in range(100):
    print("Hello")

Отступы

По PEP8 в качестве отступов надо использовать 4 пробела. Можно настроить ваш редактор так, чтобы он автоматически вставлял вместо нажатого таба 4 пробела.

Пустые строчки

Между участками кода допустима одна пустая линия, предназначенная для разделения смысловых частей программы. Между user-defined функциями, которые будут разобраны на следующим занятии, необходимо ставить две пустые строки.

Присваивание переменным значений другого типа

Так делать в Python можно технически, но чаще всего это неоправданно и вызывает ошибки. То есть не стоит писать, например:

my_line = my_line.split()

чтобы "превратить строку в список"; для хранения списка надо завести другую переменную.

Проверка, является ли строка/список/словарь пустым

Функция len возвращает длину объекта. В связи с этим возникает искушение написать что-то типа

if len(items) > 0:
    do something

Однако вызов функции len оправдан только тогда, когда вам нужна именно длина, а не проверка на пустоту (например, нужно проверить, что в вашем списке меньше пяти элементов). Для тех же случаев, когда нужна проверка объекта на пустоту, достаточно написать:

if items:
    do something

или

if not items:
    do something

Дело в том, что в Python списки, строки и некоторые другие объекты при их наличии в условии автоматически конвертируются в False, если они пустые, и в True, если они непустые.

Кроме просто вопроса эстетики, использование такого синтаксиса работает быстрее. Подробнее — здесь: https://stackoverflow.com/questions/43121340/why-is-the-use-of-lensequence-in-condition-values-considered-incorrect-by-pyli