Conversation
Add dna_tools.py, protein_tools.py, fastq_tools.py
Add "Possible commands" to run_dna_rna_tools and run_ultimate_protein_tools functions
albidgy
left a comment
There was a problem hiding this comment.
Общие комментарии:
- Работа правда хорошая! Сделана аккуратно. Я открывала ее в PyCharm, и он практически ни на что не ругался (в плане стиля кода).
- В README не хватает примеров для функций dna_rna_tools и protein_tools. А вот часть про фильтрацию fastq - отличная.
- Комментарии к коммитам замечательные!
- Обрати внимание на то, как иначе можно было сделать проверку качества ридов.
- Постарайся чуть более пристально писать Typing, в некоторых функциях встречается, что не все возможные типы указаны.
- Большинство замечаний учтено, но часть комментариев Никиты по обработке аминокислотных последовательностей не учтена.
Баллы:
- 3 фильтрации FASTQ 3/3
- Главная функция 1/1
README 1.8/2 (-0.2 за отсутствие примеров)
Структура репозитория и качество кода 2.9/3 (-0.1 за Typing)
Улучшение кода ДНК/РНК и белковых тулов 0.8/1
Итого: 9.5 баллов
| ```python | ||
| import ultimate_tools as ut | ||
| ``` |
There was a problem hiding this comment.
Тогда уже можно было бы написать, что нужно скачать проект с гитхаба git clone... Но это нюанс.
| @@ -0,0 +1,167 @@ | |||
| from typing import List, Tuple, Dict | |||
|
|
|||
There was a problem hiding this comment.
Лучше ставить 2 переноса строки. По PEP8 можно и так, и так, но чаще встречается все же вариант с переносом 2 строк
| 'I': [73, 40] | ||
| } | ||
|
|
||
| EXAMPLE_FASTQ = { |
There was a problem hiding this comment.
Не надо вставлять пример прям в код, смотрится нагроможденно, лучше вынести в README
| - float: GC-content in percentages | ||
| """ | ||
|
|
||
| return (seq.upper().count('G') + seq.upper().count('C')) / len(seq) * 100 |
| for key in seqs: | ||
| qual_seq = seqs[key][1] | ||
| qual_list = [] | ||
| for value in qual_seq: | ||
| qual_list.append(ASCII_Q_SCORE[value][1]) | ||
| mean_qual = sum(qual_list) / len(qual_list) | ||
| if mean_qual >= quality_threshold: | ||
| quality_in_bounds[key] = True | ||
| else: | ||
| quality_in_bounds[key] = False | ||
| return quality_in_bounds |
There was a problem hiding this comment.
Вот это решение верное, но неудачное. Лучше было не заводить словарь, а погуглить, как это можно автоматизировать. Логика PHRED базируется на том, что качество представляется в виде конкретного символа, значение которого можно получить, сделав перевод в Юникод. Тогда логику функции quality_seq можно сделать так:
def mean_quality_seq(qual_seq):
sum_phred = 0
for elem in qual_seq:
sum_phred += ord(elem) - 33
mean_quality = sum_phred / len(qual_seq)
return mean_qualityНу и добавить сюда логику для проверки условия по качеству, или вынести в отдельную функцию.
| - Dict[str, Tuple[str]]: a dictionary with filtered sequences | ||
| """ | ||
|
|
||
| if isinstance(gc_bounds, (int, float)): # input check |
There was a problem hiding this comment.
Кстати, забавный факт, с python3.10 можно еще и так писать:
| if isinstance(gc_bounds, (int, float)): # input check | |
| if isinstance(gc_bounds, int | float): # input check |
| if gc_bounds[1] > 100 or \ | ||
| (gc_bounds[0] > gc_bounds[1]) or \ | ||
| (length_bounds[0] > length_bounds[1]) or \ | ||
| not 0 <= quality_threshold <= 40: # bounds check | ||
| raise ValueError('The bounds are indicated incorrectly!') |
There was a problem hiding this comment.
Здорово, что сделал проверку на корректность входных данных
| quality_in_bounds = ( | ||
| fastq_tools.is_quality_in_bounds(seqs, quality_threshold)) |
There was a problem hiding this comment.
Не поняла, зачем здесь внешние скобки, без них работает также
| quality_in_bounds = ( | |
| fastq_tools.is_quality_in_bounds(seqs, quality_threshold)) | |
| quality_in_bounds = fastq_tools.is_quality_in_bounds(seqs, quality_threshold) |
| fastq_tools.is_quality_in_bounds(seqs, quality_threshold)) | ||
|
|
||
| filtered_fastq_seqs = {} | ||
| for key in seqs: |
There was a problem hiding this comment.
Вообще в этой функции несколько неоптимально идет проверка. Каждая из 3 функций-проверок иттерируются по словарю с ридами. Лучше цикл for вынести в тело главной функции. Тогда бы не нужны были списки, в которых хранятся True/False, а для каждой последовательности индивидуально принималось решение.
| if (seqs_gc_and_len_in_bounds[key][0] and | ||
| seqs_gc_and_len_in_bounds[key][1] and | ||
| quality_in_bounds[key]) is True: |
There was a problem hiding this comment.
Здесь не нужно писать is True. Фактически в условиях if проводится какая-то проверка, которая возвращает True/False. Если значение True, то тогда код заходит в тело if. Твои функции и так содержать болевые значения True/False. Например:
a = 2
if a == 2: -> True
some action Поэтому твою запись можно сделать так:
| if (seqs_gc_and_len_in_bounds[key][0] and | |
| seqs_gc_and_len_in_bounds[key][1] and | |
| quality_in_bounds[key]) is True: | |
| if (seqs_gc_and_len_in_bounds[key][0] and | |
| seqs_gc_and_len_in_bounds[key][1] and | |
| quality_in_bounds[key]): |
То есть это фактически
if (True and True and True) == True:
No description provided.