Транскрипция и сборка базовых операций
Соберём изученное в маленький набор инструментов: длина, состав, комплемент, транскрипция — кирпичики для всего дальнейшего.
Транскрипция в коде — преобразование строки ДНК в строку мРНК заменой каждого тимина (T) на урацил (U).
По отдельности базовые операции мы уже видели. Этот урок показывает, как их связать в осмысленный конвейер и аккуратно учесть, что у ДНК две нити — а значит, транскрибировать можно с любой из них.
Транскрипция в коде
Если ген на плюс-нити, мРНК — это просто ДНК с заменой T→U. Но клетка синтезирует РНК по матричной (template) нити, и итоговая мРНК совпадает с кодирующей нитью. Для нас на уровне строк важно одно правило: T→U на кодирующей нити.
def transcribe(dna):
return dna.upper().replace("T", "U")
coding = "ATGGCCTAA"
print("Кодирующая ДНК:", coding)
print("мРНК: ", transcribe(coding))Вывод:
Кодирующая ДНК: ATGGCCTAA мРНК: AUGGCCUAA
Транскрипция с матричной нити
Если вам дана матричная (template) нить, мРНК — это её обратный комплемент с U вместо T. Учтём это явно, чтобы не запутаться, какая нить дана.
pairs = {"A": "U", "T": "A", "G": "C", "C": "G"}
def mrna_from_template(template):
# мРНК синтезируется комплементарно матричной нити
return "".join(pairs[b] for b in reversed(template))
template = "TTAGGCCAT"
print("Матричная нить:", template)
print("мРНК: ", mrna_from_template(template))Вывод:
Матричная нить: TTAGGCCAT мРНК: AUGGCCUAA
Обе дороги привели к одной мРНК AUGGCCUAA — потому что матричная нить была обратным комплементом кодирующей. Понимание этой симметрии спасает от путаницы.
Мини-инструментарий
Сложим базовые функции вместе — это «швейцарский нож» для последовательностей, на который мы будем опираться дальше.
rc_table = str.maketrans("ATGC", "TACG")
def length(seq):
return len(seq)
def gc(seq):
s = seq.upper()
return (s.count("G") + s.count("C")) / len(s) * 100
def reverse_complement(seq):
return seq.upper().translate(rc_table)[::-1]
def transcribe(seq):
return seq.upper().replace("T", "U")
dna = "ATGCGTACG"
print("Длина: ", length(dna))
print("GC-состав: ", f"{gc(dna):.1f}%")
print("Обратный комплемент:", reverse_complement(dna))
print("мРНК: ", transcribe(dna))Вывод:
Длина: 9 GC-состав: 55.6% Обратный комплемент: CGTACGCAT мРНК: AUGCGUACG
Как работает под капотом: одна нить — два смысла
Каждый участок генома можно прочитать в шести «рамках»: три на плюс-нити и три на минус-нити (через обратный комплемент). Поэтому при поиске генов всегда рассматривают обе нити. Наш reverse_complement — ровно тот инструмент, что даёт доступ ко второй нити; рамки считывания разберём в следующем разделе.
Полезно отрефлексировать, что мы только что собрали мини-библиотеку, и оценить её устойчивость. Все четыре функции принимают строку и возвращают строку или число — они чистые (без побочных эффектов), а значит, легко тестируются и комбинируются. Но у них есть скрытое допущение: вход состоит только из ATGC. Функция reverse_complement на базе str.translate устойчива — неизвестные символы она просто оставит как есть, — а вот вариант со словарём упал бы по KeyError на букве N. В продакшен-коде такие допущения делают явными: либо валидируют вход на границе системы (как мы делали в разделе про строки), либо расширяют таблицы, чтобы корректно обрабатывать N и IUPAC-символы. Привычка с самого начала думать «а что если на входе грязь» отличает учебный код от рабочего.
Частые ошибки
- Транскрибировать, не определив нить. Дана кодирующая или матричная? От этого зависит, нужен ли обратный комплемент.
- Оставить T в мРНК. После транскрипции T быть не должно.
- Смешивать алфавиты. В функциях для РНК таблица пар использует U, в ДНК — T.
Связав воедино транскрипцию, GC-состав и обратный комплемент, мы фактически реализовали в миниатюре то, что делают «солдатские» утилиты биоинформатики вроде пакета EMBOSS или модулей Biopython: дай последовательность — получи её базовые характеристики и преобразования. Разница в том, что промышленные инструменты обрабатывают терабайты, поддерживают десятки форматов и учитывают тысячу краевых случаев. Но идейно внутри них — ровно те же строковые операции, что мы написали на двух десятках строк stdlib. Это важный вывод раздела: биоинформатика не магия, а аккуратная инженерия над строками; поняв базовые кирпичики, вы понимаете и то, что прячут готовые библиотеки, и можете при необходимости заглянуть внутрь или собрать своё.
Итог
- Транскрипция кодирующей нити — замена T→U; с матричной нити — обратный комплемент с U.
- Обе пути дают одну мРНК, потому что нити комплементарны.
- Базовые функции (длина, GC, обратный комплемент, транскрипция) образуют переиспользуемый инструментарий.
- Любой участок читается в шести рамках (две нити × три сдвига) — основа поиска генов.