-
Notifications
You must be signed in to change notification settings - Fork 0
Review CNTN6 #21
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 CNTN6 #21
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.
Чуть-чуть запутались в сложной теме с асбтрактным классом. Все остальное сделано очень хорошо, и получилось возвращать нужного типа при транскрипции, и освоили super (что мне показалось очень сложным!). Тут хочется добавить про вот такую фишку: можно в классе NucleicAcidSequence задать переменные, которые у классов уже должны быть. Но не задавать их значения. вот так:
def init(self, sequence: str, alphabet: dict = None, complement_alphabet: dict = None):
self.sequence = None
self.alphabet = None
self.complement_alphabet = None
Тут может возникнуть вопрос, а как же тогда мы обратимся к алфавиту, если он None. А тут и кроется секрет - можно создать отдельный сеттер для создания экзмепляров дочернего класса
Вот такое прописываем в родительском нуклеотидном классе
def setter(self, sequence: str, alphabet: dict, complement_alphabet: dict = None):
self.sequence = sequence
self.alphabet = alphabet
self.complement_alphabet = complement_alphabet
А в дочернем, например РНК - вызываем его уже с алфавитом, заданном в РНК:
def init(self, sequence: str):
super().setter(sequence, ALPHABET, REV_TRANSCRTPTION_COMPLEMENT)
Так получится хранить каждый нужный алфавит в своем классе.
Хорошая работа!
@@ -0,0 +1,88 @@ | |||
class BiologicalSequence: | |||
def __init__(self, sequence): | |||
self.sequence = 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.
Суть абстрактного класса - не держать в себе готовые атрибуты и методы, а только говорить какие атрибуты и/или методы должны обязательно быть у его наследников. Здесь выходит так, что у наследуемых классов с нуклеотидными последовательностями будет алфавит белков по умолчанию :(
@@ -0,0 +1,88 @@ | |||
class BiologicalSequence: | |||
def __init__(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.
В целом, как говорили на паре, идеальный абстрактный класс init не содержит (чтобы нельзя было создавать его экзмепляры). Но тут конечно логично, что у каждого наследника должна быть последовательность, но лучше бы переписать это все в наследниках.
def __repr__(self): | ||
return f'{self.__class__.__name__}({self.sequence!r})' |
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.
Класс, даже repr не забыт! И все методы строки есть! Супер!
'S': 'Ser', 'T': 'Thr', 'W': 'Trp', 'Y': 'Tyr', 'V': 'Val'} | ||
|
||
def __init__(self, sequence): | ||
super().__init__(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.
super().__init__(sequence) | |
super().__init__(sequence) | |
self.ALPHABET = {'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'Y'} | |
- кажется тут смотрится логично :)
for char in self.sequence: | ||
if char not in self.ALPHABET: | ||
return False | ||
return True |
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 char in self.sequence: | |
if char not in self.ALPHABET: | |
return False | |
return True | |
unique_chars = set(self.sequence) | |
if not (unique_chars <= self.ALPHABET): | |
return False | |
return True |
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.
Можно избежать лишних циелов используя set :) Это не обязательно, но кажется будет работать чуть быстрее. Особенно если алфивиты тоже сразу сделаны сетами - удобная вещь!)
def gc_content(self): | ||
return (self.sequence.count('G') + self.sequence.count('C'))/len(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.
О, супер! Правда очень логично держать эту функцию тут - мы ведь ее можем и для РНК, и для ДНК использовать!
|
||
|
||
class RNASequence(NucleicAcidSequence): | ||
REV_TRANSCRTPTION_COMPLEMENT = {'A': 'T', 'U': 'A', 'C': 'G', 'G': '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.
о! Класс!
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.
алфавит тоже сюда можн перенести)
REV_TRANSCRTPTION_COMPLEMENT = {'A': 'T', 'U': 'A', 'C': 'G', 'G': 'C'} | |
REV_TRANSCRTPTION_COMPLEMENT = {'A': 'T', 'U': 'A', 'C': 'G', 'G': 'C'} | |
ALPHABET = {'A','U','G','C'} |
|
||
def __init__(self, sequence): | ||
super().__init__(sequence) | ||
self.ALPHABET = {'A','U','G','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.
self.ALPHABET = {'A','U','G','C'} |
Нет смысл держать его тут, он же относится ко всему классу. Зачем на его переобъявлять для каждого экземпляра?
def reverse_transribe(self): | ||
return DnaSequence(self.complement(self.REV_TRANSCRTPTION_COMPLEMENT)) |
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.
Супер! И дополнительная функция, и еще и может возвращать другой класс!!!
TRANSCRTPTION_COMPLEMENT = {'A': 'U', 'T': 'A', 'C': 'G', 'G': 'C'} | ||
def __init__(self, sequence): | ||
super().__init__(sequence) | ||
self.ALPHABET = {'A', 'T', 'G', '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.
TRANSCRTPTION_COMPLEMENT = {'A': 'U', 'T': 'A', 'C': 'G', 'G': 'C'} | |
def __init__(self, sequence): | |
super().__init__(sequence) | |
self.ALPHABET = {'A', 'T', 'G', 'C'} | |
TRANSCRTPTION_COMPLEMENT = {'A': 'U', 'T': 'A', 'C': 'G', 'G': 'C'} | |
ALPHABET = {'A', 'T', 'G', 'C'} | |
def __init__(self, sequence): | |
super().__init__(sequence) |
class BiologicalSequence: | ||
def __init__(self, sequence): | ||
self.sequence = sequence | ||
self.ALPHABET = {'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'Y'} |
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.
кажется, что каждая биологическая последовательность должна иметь алфавит - это логично и верно, что прописано. Но определять его здесь не нужно, так как каждая конкертная последовательность - ДНК, РНК или белок - будет иметь свой алфавит
@@ -0,0 +1,88 @@ | |||
class BiologicalSequence: | |||
def __init__(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.
не должно быть инита в абстрактном классе
class NucleicAcidSequence(BiologicalSequence): | ||
def complement(self, COMPLEMENT_NUCLEOTIDES=None): | ||
if COMPLEMENT_NUCLEOTIDES is None: | ||
COMPLEMENT_NUCLEOTIDES = {'A': 'T', 'T': 'A', 'C': 'G', 'G': '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.
Наверное эта часть должна быть в ДНК и РНК отдельно, так как это позволит сразу создать их с верным алфавитом
self.ALPHABET = {'A','U','G','C'} | ||
|
||
def reverse_transribe(self): | ||
return DnaSequence(self.complement(self.REV_TRANSCRTPTION_COMPLEMENT)) |
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.
верно, что возвращает объект правильного класса
REV_TRANSCRTPTION_COMPLEMENT = {'A': 'T', 'U': 'A', 'C': 'G', 'G': 'C'} | ||
|
||
def __init__(self, sequence): | ||
super().__init__(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.
если я не ошибаюсь, получается что все super().__init__
отсылаются к биологической последовательности, но было бы лучше если бы они были в самих классах ДНК, РНК и белоков
Тут прям очень большие куски кода в тексте. Это очень здорово! Но в таком случае их точно надо оформлять штрихами (клавиша ё) чтобы было как код |
Review CNTN6