Skip to content

Conversation

nvaulin
Copy link
Member

@nvaulin nvaulin commented Feb 26, 2024

Review NPAS1

Copy link

@rereremin rereremin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Спасибо за выполненную работу!

Мне очень понравились некоторые Ваши решения, которые я возьму себе на заметку. Также отмечу высокое качество кода, однако еще бы аннотации типов не помешало добавить, тогда точно будет шик-блекс!
прог

Comment on lines +146 to +147


Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь можно было написать функцию, которая осуществляет трансляцию. Вероятно, Вы просто не успели что-либо написать в этом классе.

Comment on lines +62 to +67
@abstractmethod
def __len__(self):
pass

@abstractmethod
def __getitem__(self, index):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отличное использование декораторов!

Comment on lines +124 to +125
gc_content = gc_count / total_count if total_count > 0 else 0
return gc_content * 100 if as_percentage else gc_content

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Круто, что не забыли про пустые строки и деление на ноль!

Comment on lines +195 to +199
rna_seq = ""
for aa in self.sequence:
codon = choice(AA_CODON_DICT[aa])
rna_seq += codon
return rna_seq

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А, Вы решили восстанавливать мРНК, тоже хорошая идея.

Copy link

@anisssum anisssum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здорово, что использовали абстрактные классы (ABC) для представления биологических последовательностей.
Код соблюдает стандарты PEP 8, что способствует единообразию и читаемости.

Comment on lines +29 to +30
if gc_bounds[0] <= gc_percent <= gc_bounds[1] and \
length_bounds[0] <= seq_len <= length_bounds[1] and \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно было бы еще учесть. что gc_bounds и length_bounds может подаваться одно число, являющееся верхней границей.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Даже не можно а нужно :)

Comment on lines +35 to +37
output_filename = input_path.split("/")[-1]
else:
output_filename = output_filename + ".fastq"

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 файл будет сохранен в той же папке с одним расширением.

Copy link
Member Author

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)

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):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здорово, что есть вариант с процентами "as_percentage".

Copy link

@wwoskie wwoskie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Доброе утро! Поздравляю с прошедшим междунородным днем проверки второй домашки!

image

Работа хорошая!

Концептуально на мой взгляд все верно. Докстринги есть, это хорошо. Немного обидно, что некоторые методы возвращают не свой класс, а str. Еще по удобству чтения кода: мне кажется, читать аннотацию типов из докстрингов не так удобно, как из самих аргументов функции (ну хотя подцветки синтаксиса нет), да и автопроверки это тоже делают оттуда, поэтому я бы все-таки добавил их при объявлении функции

Comment on lines +29 to +31
if gc_bounds[0] <= gc_percent <= gc_bounds[1] and \
length_bounds[0] <= seq_len <= length_bounds[1] and \
mean_offset >= quality_threshold:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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
):

Есть такой ЛаЙфХаК, хотя твой способ не осуждаю (но этот имо аккурпатнее)

Copy link
Member Author

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:
Copy link

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]
Copy link

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"
Copy link

@wwoskie wwoskie Mar 11, 2024

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
Copy link

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)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Интересная конструкция

Copy link

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')
Copy link

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'
}
Copy link

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):
Copy link

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)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return ''.join(self.COMPLEMENT_DICT.get(base, base) for base in self.sequence)
return self.__class__(''.join(self.COMPLEMENT_DICT.get(base, base) for base in self.sequence))

можно как-то так попробовать, а то результат выполнения возвращает строку, что не совсем хорошо

image

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Чаще делают не self.__class__(...), а type(self)(...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants