Учебная страница курса биоинформатики,
год поступления 2019
Python, материалы к занятию 4
Python
Чтение веб-ресурса
Веб-ресурс — это файл на удалённом компьютере, который сделан доступным через Интернет. Адресом веб-ресурса является его URL. Например, "https://kodomo.fbb.msu.ru/wiki/2019/1/hints9" — URL этой страницы.
Простейший способ работать с веб-ресурсом из программы на Python — открыть его функцией urlopen из модуля urrlib.request
from urllib.request import urlopen myres = urlopen("https://www.uniprot.org/uniprot/P08008.fasta") for bline in myres: line = bline.decode().strip('\n') <do something with line> myres.close()
Обратите внимание, что строки ресурса читаются не в виде обычных строк, а в виде так называемых b-строк, и прежде чем работать с ними как с обычными строками, их надо "декодировать" методом decode().
Словари
Словарь (dict) — тип данных, предназначенный для хранения информации о соответствии каких-либо данных некоторому набору "ключей". Внешне использование словаря похоже на использование списка:
adic = dict() adic[0] = "a" adic[1] = "b"
Здесь 0 и 1 — ключи, а "a" и "b" — значения, соответсвующие этим ключам. Каждому ключу соответствует ровно одно значение.
Отличие словаря от списка в том, что ключами словаря могут быть не только целые неотрицательные числа, но и любые другие числа, а также строки и кортежи (см. ниже). Даже если это целые неотрицательные числа, они не обязательно идут подряд.
Значениями словаря могут быть любые объекты, в том числе другие словари. Ключами словаря не могут быть списки и словари (потому что это так называемые "изменяемые" объекты).
Ключи словаря уникальны, а значения могут повторяться.
Словарь — ОЧЕНЬ удобный инструмент языка Python, его стоит освоить.
Кортежи
Часто нужно, чтобы ключом словаря была не одна величина или строка, а несколько (например, имя, отчество и фамилия человека, или номер дома и номер квартиры). Поскольку списки не могут быть ключами, придуман неизменяемый аналог списка — кортеж (tuple). В отличие от списка, кортеж записывается в круглых скобках:
>>> at = (7, 8, 0, 1) >>> len(at) 4 >>> at[1] 8 >>> at[1:3] (8, 0) >>> at[1:2] (8,) >>> list(at) [7, 8, 0, 1] >>> sorted(at) [0, 1, 7, 8]
(Функция sorted готова принимать на вход кортеж вместо списка, но возвращает всё равно список). Впрочем, ничего не стоит сделать из списка кортеж:
>>> tuple(["a", "b", "c"]) ('a', 'b', 'c') >>> tuple(sorted((7, 8, 0, 1))) (0, 1, 7, 8)
Функции и собственные модули
Функция определяется словом "def". В следующем примере "newfunction" — это название функции (любое слово, кроме ключевых слов языка, например, нельзя называть функцию "for"), а x и y — аргументы функции (здесь аргументов два, но их может быть сколько угодно, например, 0).
def newfunction(x, y): <вычисления> return <значение функции>
Функции "собственного изготовления" используются точно так же, как встроенные:
z = newfunction(x, y)
При этом в переменную z попадёт значение, находящееся в теле функции после оператора return. В приниципе, функция может содержать несколько операторов return, пример:
def sign(x): if x > 0: return 1 if x == 0: return 0 if x < 0: return -1
Эта функция возвращает знак своего аргумента.
После выполнения оператора return выполнение функции прекращается, и возобновляется выполнение той программы, что вызвала функцию. Поэтому если просто поставить два return один за другим, безо всяких условий, то выполняться будет только первый.
За исключением особо простых случаев (как в приведённом выше примере функции sign) рекомендую, чтобы не запутаться, иметь в функции ровно один return, в самом конце.
Собственный модуль — это файл с расширением .py, содержащий описание одной или нескольких функций (и/или классов, но об этом потом). При этом (в нормальной ситуации) этот файл не содержит ничего, кроме описания функций, так что попытка его исполнить не будет иметь никакого эффекта. Собственные модули можно использовать так же, как встроенные. Например, пусть файл mymodule.py содержит, кроме прочего, описание функции sign (см. выше). Тогда, если файл mymodule.py лежит в текущей директории, можно вызвать python в интерактивном режиме и написать:
>>> from mymodule import sign >>> sign(5) 1 >>> sign(33**33 - 32**34) -1
Обратите внимание, что при подключении функции из собственного модуля имя этого модуля используется без расширения ".py".
Цикл while
Тело цикла while выполняется, пока выполнено некоторое условие. Синтаксис:
while <условие>: ... <тело цикла> ... <возможно, что-то ещё>
Здесь условие — это выражение, возвращающее булевское значение (или другое значение: как и в случае if, это значение будет преобразовано к булевскому). В отличие от if, тело цикла может выполняться много раз, оно будет выполняться снова и снова, пока условие возвращает True. Тем самым, чтобы цикл не стал бесконечным, условие должно включать переменную, которая меняется в теле цикла. Пример (эмуляция цикла for x in plist, где plist — список):
i = 0 while i < len(plist): x = plist[i] <что-то делаем с x> i = i + 1
Цикл while более гибок, чем цикл for, но требует большей внимательности от программиста.
Операторы break и continue
Вкратце: break — это преждевременное прерывание цикла (и переход к тому, что идёт после цикла), а contunue — преждевременное прерывание текущего тела цикла (и переход к следующей итерации цикла).
Примеры.
Поиск первой встречи слова "word" в файле filename.txt и печать номера строки с этим словом.
indata = open("filename.txt", "r") count = 0 found = False for line in indata: count = count + 1 if "word" in line: found = True break # завершаем цикл indata.close() if found: print(count) else: print("Not found")
После того, как мы нашли требуемую строку, просматривать файл дальше не нужно, поэтому break.
Подсчёт числа букв "a" в последовательностях, хранящихся в файле "sequences.fasta" в fasta-формате (нам нужно игнорировать строки, начинающиеся с ">"):
infasta = open("sequences.fasta", "r") count_a = 0 for line in infasta: if line.startswith(">"): continue # переходим к следующей строке файла, остаток тела цикла не выполняется for c in line: if c == 'a': count_a = count_a + 1 infasta.close() print(count_a)
PDB и Uniprot
PDB
В банке PDB (Protein Data Bank) хранятся пространственные структуры белков и других макромолекул, а также их комплексов друг с другом и с малыми органическими молекулами.
Каждая запись PDB имеет уникальный идентификатор — PDB-код. Он состоит из четырёх символов, первый из которых — цифра. Традиционно в PDB, в том числе в PDB-кодах, использовались только заглавные буквы, но сейчас один и тот же код может быть записан с использованием как заглавных, так и строчных букв.
Получить список нескольких PDB-кодов можно, например, так: зайдите на сайт PDB и наберите в строке поиска английское название какого-нибудь белка (например, "albumin").
Данные в PDB хранятся в виде текстового файла, доступного по адресу http://files.rcsb.org/view/<код>.pdb, например http://files.rcsb.org/view/1WBA.pdb. Собственно структура содержится в этом файле в строках, начинающихся с "ATOM ", в виде координат центров атомов. Структура такой строки описана здесь. При работе с PDB-файлами из программы на Python не забывайте, что позициям, например, 18–20 соответствует срез строки [17:20].
Uniprot
В банке Uniprot хранятся последовательности (они же "первичные структуры", но так сейчас говорят редко) белков.
Каждая запись Uniprot имеет два идентификатора: ID и AC (зачем так, будет рассказано во втором семестре). Для нас сейчас важен AC: accession number, или код доступа. По нему в Интернете можно получить два файла: в fasta-формате, с кратким описанием, по адресу https://www.uniprot.org/uniprot/<код>.fasta, и в специальном Uniprot-формате, с подробным описанием, по адресу https://www.uniprot.org/uniprot/<код>.txt. Кроме того, по адресу https://www.uniprot.org/uniprot/<код> находится та же информация в виде гипертекста.
Набрав в строке поиска Uniprot английское название какого-нибудь белка, можно получить таблицу, в которой в первом столбце (озаглавленном Entry) будут стоять коды доступа (AC) разных последовательностей.