-
Notifications
You must be signed in to change notification settings - Fork 45
Create amino acid sequences analysis toolbox #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Update mrna, find seq, find res funcs
…te_isoelectric_point functions
Add two functions and update README.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Комментарии к работе:
- Комментарии к коммитам в большинстве своем не удались. Например, Add two def - не информативный комментарий. Лучше писать, что была добавлена такая и такая функции.
- README достаточно подробный, но по примерам непонятно, что делает программа. Здорово, что сделали блок "Common problems".
- В README нигде не сказано, как должна подаваться трехбуквенная аминокислотная последовательность. Я разобралась только читая уже сам код.
- Мне понравилось, как вы сделали главную функцию.
- Молодцы, что использовали константы.
- Достаточно часто ваш код перегружен, либо присутствует повторение одного и того же кода. Обратите внимание на комментарии, они будут полезны.
- Старайтесь не использовать конкатенацию строк, лучше добавлять элементы в список.
Так как вы написали большое количество функций, я выбрала лучшие 5 (+ главная функция) для оценивания: calculate_protein_mass, calculate_isoelectric_point, get_mrna, find_res, calculate_average_hydrophobicity. Но функции я проверила все.
Баллы:
- README - 2.2 балла (-0.5 за неинформативные примеры).
- calculate_protein_mass - 1.5 балла
- calculate_isoelectric_point - 1.5 балла
- get_mrna - 1 балл (-0.5 за конкатенацию строк)
- find_res - 1.3 балла (-0.2 за нейминг функции)
- calculate_average_hydrophobicity - 1.4 (-0.1 за отсутствие округления)
- общие штрафы: нейминг переменных -0.5 балла, большое количество повторяющегося кода -1 балл, комментарии к коммитам -0.5 балла = -2 балла.
Итого: 6.9 баллов
else: | ||
registr.append('Lower') | ||
for el in seq_new: | ||
if (len(el) != res_length): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (len(el) != res_length): | |
if len(el) != res_length: |
for el in seq_new: | ||
if (len(el) != res_length): | ||
raise TypeError('Wrong sequence format') | ||
elif (res_length == 1): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
elif (res_length == 1): | |
elif res_length == 1: |
for el in seq: | ||
if el.isupper(): | ||
registr.append('Upper') | ||
else: | ||
registr.append('Lower') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вот эту часть кода лучше было вынести в отдельную функцию. А так идет нагромождение в функции и ненужное повторение кода в if/else.
registr.append('Upper') | ||
else: | ||
registr.append('Lower') | ||
res_seq += seq |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Конкатенация строк - это долгий и затраты процесс. Лучше добавлять элементы в список
if query == 'three': | ||
trans_res_seq = str() | ||
for i in range(len(res_seq)): | ||
if i != len(res_seq) - 1: | ||
for three, one in RESIDUES_NAMES.items(): | ||
if one == (res_seq[i].upper()): | ||
trans_res_seq += three + ' ' | ||
break | ||
else: | ||
for three, one in RESIDUES_NAMES.items(): | ||
if one == res_seq[i].upper(): | ||
trans_res_seq += three | ||
break | ||
res_with_reg = str() | ||
temp_trans = [trans_res_seq[i:i + 4] for i in range(0, len(trans_res_seq), 4)] | ||
for res, reg in zip(temp_trans, registr): | ||
if (reg == 'Upper'): | ||
res_with_reg += res.upper() | ||
if (reg == 'Lower'): | ||
res_with_reg += res.lower() | ||
result += res_with_reg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вот эту часть кода крайне сложно понять. Тут у меня есть несколько замечаний:
- if i != len(res_seq) - 1. Я понимаю, почему вы сделали иттерацию для последнего элемента отдельно, НО этого бы делать не нужно было, если бы вы записывали ответ в список, а потом просто бы сделали ' '.join(trans_res_seq).
- for three, one in RESIDUES_NAMES.items(). Не самая удачна яидея иттерироваться по словарю. Словари и хороши тем, что поиск элемента проходит за O(1), а вы делаете поиск O(n). Лучше завести второй словарь, где ключами будет однобуквенная запись аминокислотных остатков, а значения - трехбуквенными. Это ускорит ваш код, сократит его и сделает более читаемым. P.S. если вы еще не сталкивались с О, то не переживайте, вам расскажут это на дискретной математике.
- if (reg == 'Upper'). Скобки не нужны.
- for i in range(len(res_seq)). Лучше не i, а idx.
- temp_trans = [trans_res_seq[i:i + 4] for i in range(0, len(trans_res_seq), 4)]. И вот эта строка странная, потому что вы делаете дополнительный перевод строки в список. С учетом того, что до этого вы делали конкатенацию строк выше.
elif ind == len(seq): | ||
sum_pka += RESIDUES_CHARACTERISTICS[res][1][0] | ||
pka_amount += 1 | ||
pi = sum_pka / pka_amount |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Лучше округлять значения.
for aa in b_turn_set: | ||
count += seq.upper().count(aa) | ||
b_turn_exp = str(count / protein_length * 100) | ||
res_for_seq += ['b-turn amino acids in protein' + ' is ' + b_turn_exp + '%'] | ||
count = 0 | ||
for aa in b_sheet_set: | ||
count += seq.upper().count(aa) | ||
b_sheet_exp = str(count / protein_length * 100) | ||
res_for_seq += ['b-sheet amino acids in protein' + ' is ' + b_sheet_exp + '%'] | ||
count = 0 | ||
for aa in alpha_helix_set: | ||
count += seq.upper().count(aa) | ||
alpha_helix_exp = str(count / protein_length * 100) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 цикла for - это очень неоптимально. Если вам дадут длинную аминокислотную последовательность, то код будет долго работать. Лучше сделать 1 for и написать проверку:
for aa in seq.upper():
if aa in b_turn_set:
counter_b_turn += 1
elif aa in b_sheet_set:
counter_b_sheet += 1
elif aa in counter_alpha_helix:
counter_alpha_helix += 1
function_names = {'change_residues_encoding': [change_residues_encoding, 2], | ||
'is_protein': [is_protein, 1], | ||
'get_seq_characteristic': [get_seq_characteristic, 1], | ||
'find_res': [find_res, 2], | ||
'find_site': [find_site, 2], | ||
'calculate_protein_mass': [calculate_protein_mass, 1], | ||
'calculate_average_hydrophobicity': [calculate_average_hydrophobicity, 1], | ||
'get_mrna': [get_mrna, 1], | ||
'calculate_isoelectric_point': [calculate_isoelectric_point, 1], | ||
'analyze_secondary_structure': [analyze_secondary_structure, 1]} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Интересно сделали реализацию через словари. 👍
seqs = [change_residues_encoding(seq) for seq in args[:-1 * (function_names[procedure][1])]] | ||
for idx, seq in enumerate(seqs): | ||
if not is_protein(seq): | ||
processed_result.append(f'Sequence number {idx + 1} is not available for operations! Skip it.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Лучше не записывать в ответ строку с ошибкой, а выводить print() на экран, так будет нагляднее.
return result | ||
|
||
|
||
def run_protein_analysis(*args: str) -> Union[List[str], str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вы не всегда возвращаете список строк или строку. Иногда вы возвращаете float и int, или их списки.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Привет всем,
Попросили чекнуть тут баллы.
1) README
README в целом выглядит хорошо, хорошая структура и отдельно здорово что есть секции про установку и проблемы. Тем не менее, есть несколько моментов. Во-первых, здорово что есть примеры, но не хватает результатов работы этих примеров. То есть в идеале я могу прогнать этот код у себя и сравнить с вашим ответом. Тут я так не могу сделать. Также в примерах вы пишете вызов внутренних функций, хотя по идее пользователь ипортирует только главную и работает через неё. Также согласен с комментарием про то, что не очень ясен формат в котором требуется ввод. Такие вещи лучше было бы вынести где-то в начало. Хотя то что хотя бы в секции трабл-шутинга есть - уже ок. Я бы тут поставил не 2/2.5, а 2.3/2.5 + 0.2 за фото. Но все упомянутые вещи обязательно надо исправить.
2) Функции
get_mrna
- согласен что лучше делать список чем конкатенацию строк, но все же тут у нас нет цели прям оптимизировать процесс. Код выглядит аккуратно и работает правильно, мне кажется этого пока достаточно. Но важно чтобы вы все равно знали об этом. Во-втором семестре у нас будут домашки, где вы сталкнетесь с этим, но пока для нас это не самое главное. Так что я бы поставил 1.5/1.5
calculate_average_hydrophobicity
- я бы не стал снимать 0.1 балл за отсутсвие округления. Дейсвительно, может быть эти результаты вы используете при каких-то расчетах далее, и тогда вам не нужно округлять. Округление можно делать непосресдтвенно перед печатью в print. 1.5/1.5.
**3) Нейминги **
С замечаниями по неймингам переменных и функций согласен. С find_res
и переменной res
, конечно, мы сейчас понимаем что вы могли иметь ввиду residue. Но все таки res
это максимально распространенное сокращение для result
, поэтому такие штуки к содалению могут быть confusing. Так что функция find_res
звучит в голове как "найди результат"
find_residue_position
гораздо информативнее, вроде что-то такое Саша и предложила
**4) Общие замечания **
Со всеми замечаниями согласен. Прокомментирую структуру коммитов. Действительно, все выглядит неплохо, но все таки есть замечения:
- Сообщения коммитов (например, Add useful functions, Add two def). Есть небольшая неконсистентность, например Add modification into README и Update README.md. Коммит Remade mrna, find seq, find site funcs тоже не очень дает представление о содержании. Вы же не с нуля переписали эти функции, а просто что-то пофиксили. Ну и сообщения типа Update хороши для README, потому что там в целом просто текст. А в коде важно содержание кода, так что коммиты типа Update function хоть и кажутся ок, но информативности в них не много
- Содержание коммитов. Например, есть коммиты где за раз добавляется много всего. Если в коммитах по типу Add is_protein function and fix case-sensitive features кажется еще ок, т.к. информативное сообщение, то тот же Add useful functions оч перегружен.
- Где то содержание не соотвествует сообщению. В целом вообще правильно когда сообщение коммита строго равно его содержанию. Иногда, ладно, не страшно если заодно с коммитом исправили опечатку в другой части кода. Но у вас, нарпимер, в create templates добавлены докстринги, а в Add docstrings какой-то код пишете. В Create project structure вы сделали шаблоны функций (что круто!) но вместе с этим написаны константые словари (что тоже круто!). И то и то в принципе ок добавить в этот коммит. Но бедный словарь RESIDUES_CHARACTERISTICS
был добавлен в этот коммит прямо в процессе своего появления на этот свет:)
- А еще вы видимо когда делали pull-request, решили его назвать. Тут это как раз не очень надо, так как по названиям пулл-реквестов мы смотрим где чья работа:) Вашу мы определили хотя бы по тому, что, спасибо Полине, ник на GitHub соотвествует релаьному имени. Без этого прилось бы тратить время, искать и разбираться.
Я попытался тут накидать побольше примеров, чтобы было на что обратить внимание. И обосновать почему я согласен с оценкой за структуру коммитов. Тем не менее, у вас тут не всё плохо. Небольшие недочеты, как раз на половинку балла.
Это к сожалению важно, потому что Git система не из простых, и если к ней не привыкнуть, то легко работа с ней превращается в лишнюю трату времени без пользы. Поэтому пока что польза от нее есть в виде баллов. Зато в реальной работе вы уже не будете думать над сообщениями, не будете забывать коммитить как только дописали одну функцию и т.п. Когда это все дойдет до автоматизма - вы будете сильно круче любых ваших конкурентов в биоинформатике и в целом в IT, кто не запаривался так сильно над тем чтобы освоить Git. Поэтому здесь оценка это мотивация не остановиться на "я умею git commit и помню правила написания комментариев", а двигаться дальше чтобы Git был для вас также елементарен и само-собой-разумеещь как чистить зубы по утрам. Чтобы это было для вас как искусство, и вы не только знали его, но и чувствовали.
Соре за такой опус.
В общем, скорректированный балл: 7.8
Если вы еще с чем-то не согласны, можете прям тут в ветке отвечать, всё можно обсуждать, главное чтобы все всё поняли и было понятно куда двигаться вперёд.
No description provided.