-
Notifications
You must be signed in to change notification settings - Fork 0
Review NPAS1 #43
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?
Review NPAS1 #43
Conversation
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.
|
||
|
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.
Здесь можно было написать функцию, которая осуществляет трансляцию. Вероятно, Вы просто не успели что-либо написать в этом классе.
@abstractmethod | ||
def __len__(self): | ||
pass | ||
|
||
@abstractmethod | ||
def __getitem__(self, index): |
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.
Отличное использование декораторов!
gc_content = gc_count / total_count if total_count > 0 else 0 | ||
return gc_content * 100 if as_percentage else gc_content |
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.
Круто, что не забыли про пустые строки и деление на ноль!
rna_seq = "" | ||
for aa in self.sequence: | ||
codon = choice(AA_CODON_DICT[aa]) | ||
rna_seq += codon | ||
return rna_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.
А, Вы решили восстанавливать мРНК, тоже хорошая идея.
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.
Здорово, что использовали абстрактные классы (ABC) для представления биологических последовательностей.
Код соблюдает стандарты PEP 8, что способствует единообразию и читаемости.
if gc_bounds[0] <= gc_percent <= gc_bounds[1] and \ | ||
length_bounds[0] <= seq_len <= length_bounds[1] and \ |
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.
Можно было бы еще учесть. что gc_bounds и length_bounds может подаваться одно число, являющееся верхней границей.
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.
Даже не можно а нужно :)
output_filename = input_path.split("/")[-1] | ||
else: | ||
output_filename = output_filename + ".fastq" |
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.
Если в input_path уже написано расширение у файла, то он к этому расширению добавит ".fastq". Также некоторые операционные системы могут не понять "/".
Кажется, лучше сплитовать по ".", брать элемент с индексом 0 и добавлять к нему ".fasta". Тогда output файл будет сохранен в той же папке с одним расширением.
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.
Верное замечание. А вообще чтобы было универсально можно использовать basename
return self.sequence[index] | ||
|
||
def complement(self): | ||
return ''.join(self.COMPLEMENT_DICT.get(base, base) for base in self.sequence) |
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.
Круто написано.
Можно было бы еще учесть, что на вход подается РНК.
def complement(self): | ||
return ''.join(self.COMPLEMENT_DICT.get(base, base) for base in self.sequence) | ||
|
||
def gc_content(self, as_percentage=False): |
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.
Здорово, что есть вариант с процентами "as_percentage".
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.
Доброе утро! Поздравляю с прошедшим междунородным днем проверки второй домашки!
Работа хорошая!
Концептуально на мой взгляд все верно. Докстринги есть, это хорошо. Немного обидно, что некоторые методы возвращают не свой класс, а str
. Еще по удобству чтения кода: мне кажется, читать аннотацию типов из докстрингов не так удобно, как из самих аргументов функции (ну хотя подцветки синтаксиса нет), да и автопроверки это тоже делают оттуда, поэтому я бы все-таки добавил их при объявлении функции
if gc_bounds[0] <= gc_percent <= gc_bounds[1] and \ | ||
length_bounds[0] <= seq_len <= length_bounds[1] and \ | ||
mean_offset >= quality_threshold: |
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 gc_bounds[0] <= gc_percent <= gc_bounds[1] and \ | |
length_bounds[0] <= seq_len <= length_bounds[1] and \ | |
mean_offset >= quality_threshold: | |
if ( | |
gc_bounds[0] <= gc_percent <= gc_bounds[1] | |
and length_bounds[0] <= seq_len <= length_bounds[1] | |
and mean_offset >= quality_threshold | |
): |
Есть такой ЛаЙфХаК, хотя твой способ не осуждаю (но этот имо аккурпатнее)
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.
Согласен, со скобочками по-мне выглядит покрасивше, хотя наверное в этом случае лучше оставлять and в конце строки
но хз
mean_offset >= quality_threshold: | ||
filtered_seqs.append(record) | ||
|
||
if output_filename is None: |
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.
Хорошо, что проверка есть
filtered_seqs.append(record) | ||
|
||
if output_filename is None: | ||
output_filename = input_path.split("/")[-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.
Я бы предложил для таких проверок использовать всё-таки библиотечки типа os
или pathlib
if output_filename is None: | ||
output_filename = input_path.split("/")[-1] | ||
else: | ||
output_filename = output_filename + ".fastq" |
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 not self.alphabet_checking(): | ||
raise ValueError("Invalid characters in the sequence.") | ||
|
||
@abstractmethod |
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.
Круто, что ты делаешь самостоятельно эти базовые методы
return self.sequence[index] | ||
|
||
def complement(self): | ||
return ''.join(self.COMPLEMENT_DICT.get(base, base) for base in self.sequence) |
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.
Интересная конструкция
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.
Хотя это и немного странно, что он вернет сам себя, как будто немного неинтуитивное поведение
return ''.join(self.COMPLEMENT_DICT.get(base, base) for base in self.sequence) | ||
|
||
def gc_content(self, as_percentage=False): | ||
gc_count = self.sequence.count('G') + self.sequence.count('C') |
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.
count
в этом случае пробежится два раза, если будет длинная последовательность может быть неприятно.
TRANSCRIBE_DICT = { | ||
'T': 'U', | ||
't': 'u' | ||
} |
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.
Нативная интеграция (извините)
return f"{self.__class__.__name__}('{self.sequence}')" | ||
|
||
def alphabet_checking(self): | ||
if not set(self.sequence) <= set(type(self).ALPHABET): |
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.
Лайк
return self.sequence[index] | ||
|
||
def complement(self): | ||
return ''.join(self.COMPLEMENT_DICT.get(base, base) for base in self.sequence) |
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.
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.
Чаще делают не self.__class__(...)
, а type(self)(...)
Review NPAS1