Skip to content

Hw4 voskoboinikov #27

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

Open
wants to merge 64 commits into
base: main
Choose a base branch
from
Open

Conversation

wwoskie
Copy link

@wwoskie wwoskie commented Oct 1, 2023

No description provided.

Aleksandr Voskoboinikov and others added 27 commits October 1, 2023 12:04
…s, convert_aa_name

Remove '/ Args' in all 3 functions
Update docstrings and comments
Copy link

@albidgy albidgy left a comment

Choose a reason for hiding this comment

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

Для проверки выбрала случайных 5 функций: 'get_length_of_protein', 'get_atomic_mass', 'get_protein_rnas', 'get_length_of_protein', 'calculate_protein_mass'.
Плюсы:

  • Видно, что вы много времени потратили на работу.
  • Код написан в целом аккуратно. Но почему-то воспринимается достаточно тяжело, попробуйте упростить вашу логику, это можно сделать более легко читаемым, но нужно посидеть над кодом.
  • Достриги подробные, здорово.
  • Отличные комментарии к коммитам.
  • Здорово, что использовали константы.

Замечания:

  • В ИБ мат запрещен. Да и в принципе, если вы пишете какой-то код, который могут использовать другие люди, сохраняйте деловой стиль. Я так поняла, вы просто не дочистили код.
  • У вас есть возможность передавать данные в виде словаря, но, как именно это нужно сделать, не сказано.
  • Нет описания, что такое аргумент check_if_user_conscious. По большей части, этот аргумент только мешает нормальной работе функций. Я не нашла, где бы он использовался по назначению.
  • У вас многие функции достаточно не интуитивные, не всегда хватает описания функции. Например, get_frameshift_proteins.
  • Не нужно константы записывать в новые переменные в теле функции. Их можно вызвать напрямую.
  • Не используйте конкатенацию строк.
  • Если вы хотите выводить сообщения, что что-то пошло не так нужно их делать более информативными и не записывать в результат, а выводить на экран (то есть либо делать exceptions, либо печать на экран сообщение - лучше всего print(message, file=sys.stderr), а в результат записывать, например, None).

Баллы:

  • README - 2.7 балла (-0.5 за недостаточно подробное описание функций, -0.2 за отсутствие примера, как подавать словари и что в них должно быть) = 2 балла.
  • Функции - 7.5 баллов (-1 за конкатенацию строк, -0.7 за неправильную передачу данных в get_atomic_mass, -0.3 за запись констант в переменные внутри функций) = -2 балла.
  • Доп штраф за мат -1 балл.

Итого: 7.2 балла

{frame_0: ['protein_seqs'], frame_1: ['protein_seqs'], frame_2: ['protein_seqs']}
"""

if check_if_user_conscious:
Copy link

Choose a reason for hiding this comment

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

Зачем здесь эта проверка? Какую смысловую нагрузку несет? Фактически программа просто останавливает работу, если не указать этот параметр. Не лучшее решение.

Comment on lines +366 to +368
for codon in codons:
for kmer in kmers:
current_kmers.append(kmer + codon) # append every codon to existing kmers
Copy link

Choose a reason for hiding this comment

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

Конкатенация строк - долгий и не оптимальный процесс, лучше использовать добавление элемента к списку.

Comment on lines +530 to +531
if aa_atomic_mass is None:
aa_atomic_mass = AA_MASS_DICT
Copy link

Choose a reason for hiding this comment

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

Не нужно так делать. Словарь можно вызывать напрямую.

total_mass = 0
char = 0 # idx init
if atomic_mass is None:
atomic_mass = ATOMIC_MASS
Copy link

Choose a reason for hiding this comment

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

Можно словарь вызывать напрямую. Не нужно его записывать в другую переменную.

element = chem[char]
char += 1 # очень надо, а то я опять бесконечный цикл сделала
if char < len(chem) and chem[char].isdigit():
number = ''
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.

А можно вопрос, для случая с глюкозой допустим C6H12O6, как обойти конкатенацию, просто не очень понимаю. Спасибо.

Copy link

@albidgy albidgy Oct 6, 2023

Choose a reason for hiding this comment

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

Вообще сам по себе этот код неоптимальный. Но быстро я не придумала, как его аккуратнее переписать. Я подумаю на выходных, как можно иначе написать.
Касаемо конкатенации строк, лучше сделать так:

number = []
while char < len(chem) and chem[char].isdigit():
     number.append(chem[char])
     char += 1  # очень надо
total_mass += atomic_mass[element] * int(''.join(number))

Кстати, забыла написать: комментарии лучше писать на английском языке.

parsed_dct = {}
inp_type = type(inp) # get input type
if inp_type == list:
for i, seq in enumerate(inp):
Copy link

Choose a reason for hiding this comment

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

i - плохой нейминг, лучше ind или idx


def run_ultimate_protein_tools(command,
inp,
*args,
Copy link

Choose a reason for hiding this comment

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

Использование *args не лучшее решение. Если пользователь подаст позиционные аргументы для другой функции не в том порядке, все сломается. Лучше просто оставить kwargs

else:
output_dct[name] = is_protein_valid(input_dct[name])
elif command == 'get_atomic_mass':
output_dct[name] = command_dct[command](input_dct[name], *args, **kwargs)
Copy link

Choose a reason for hiding this comment

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

Вы передаете в функцию get_atomic_mass **kwargs, но в самой функции **kwargs не принимаете, поэтому программа падает с ошибкой.

frames_list.append(frame) # append frame to frames list
frameshift_dct[f'frame_{frame_number}'] = list(set(frames_list)) # clean duplicates and write to dict
return frameshift_dct
return "You don't fucking know what you're doing!" # politely ask user to reconsider their actions
Copy link

Choose a reason for hiding this comment

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

Лучше выбрасывать ошибку и более корректную.

"""
output_dct = {}
input_dct = parse_input(inp, **kwargs)
for name in input_dct:
Copy link

Choose a reason for hiding this comment

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

Здесь выдается не имя, а порядковый номер, лучше иттерироваться по значениям, чтобы выдавать последовательность. Так будет более информативно.

@nvaulin
Copy link
Member

nvaulin commented Oct 5, 2023

Для проверки выбрала случайных 5 функций: 'get_length_of_protein', 'get_atomic_mass', 'get_protein_rnas', 'get_length_of_protein', 'calculate_protein_mass'. Плюсы:

  • Видно, что вы много времени потратили на работу.
  • Код написан в целом аккуратно. Но почему-то воспринимается достаточно тяжело, попробуйте упростить вашу логику, это можно сделать более легко читаемым, но нужно посидеть над кодом.
  • Достриги подробные, здорово.
  • Отличные комментарии к коммитам.
  • Здорово, что использовали константы.

Замечания:

  • В ИБ мат запрещен. Да и в принципе, если вы пишете какой-то код, который могут использовать другие люди, сохраняйте деловой стиль. Я так поняла, вы просто не дочистили код.
  • У вас есть возможность передавать данные в виде словаря, но, как именно это нужно сделать, не сказано.
  • Нет описания, что такое аргумент check_if_user_conscious. По большей части, этот аргумент только мешает нормальной работе функций. Я не нашла, где бы он использовался по назначению.
  • У вас многие функции достаточно не интуитивные, не всегда хватает описания функции. Например, get_frameshift_proteins.
  • Не нужно константы записывать в новые переменные в теле функции. Их можно вызвать напрямую.
  • Не используйте конкатенацию строк.
  • Если вы хотите выводить сообщения, что что-то пошло не так нужно их делать более информативными и не записывать в результат, а выводить на экран (то есть либо делать exceptions, либо печать на экран сообщение - лучше всего print(message, file=sys.stderr), а в результат записывать, например, None).

Баллы:

  • README - 2.7 балла (-0.5 за недостаточно подробное описание функций, -0.2 за отсутствие примера, как подавать словари и что в них должно быть) = 2 балла.
  • Функции - 7.5 баллов (-1 за конкатенацию строк, -0.7 за неправильную передачу данных в get_atomic_mass, -0.3 за запись констант в переменные внутри функций) = -2 балла.
  • Доп штраф за мат -1 балл.

Итого: 7.2 балла

Амнистия за мат (всем членам команды), т.к. все таки обычная шутка
Но больше так не делайте:)

Copy link
Member

@nvaulin nvaulin left a comment

Choose a reason for hiding this comment

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

Всем привет еще раз, был запрос проверить другой набор функций. Запрос одобрил, функции пере-оценил (не "переоценил"), можете также найти комментарии к коду.

В следуйщий раз предусмотрим чтобы "сделать в 2 раза больше" было еще менее выиграшной стратегий. Нужно брать не количеством а качеством)

Баллы:

  • README 2.7
  • is_protein_valid 1.5/1.5
  • get_protein_rnas_number 1.5/1.5
  • count_aa 1.4/1.5
  • get_length_of_protein 0.75/1
  • get_fracture_of_aa 1.4/1.5

Итого 9.25

Comment on lines +294 to +307
def is_protein_valid(seq: str) -> bool:
"""
Checks if protein is valid.

Arguments:
- seq (str): seq to be checked

Return:
- bool, the result of the check
"""

if set(seq).issubset(RNA_AA_TABLE):
return True
return False
Copy link
Member

Choose a reason for hiding this comment

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

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

Suggested change
def is_protein_valid(seq: str) -> bool:
"""
Checks if protein is valid.
Arguments:
- seq (str): seq to be checked
Return:
- bool, the result of the check
"""
if set(seq).issubset(RNA_AA_TABLE):
return True
return False
def is_protein_valid(seq: str) -> bool:
"""
Checks if protein is valid.
Arguments:
- seq (str): seq to be checked
Return:
- bool, the result of the check
"""
return set(seq).issubset(RNA_AA_TABLE):

return "You don't know what you're doing!" # politely ask user to reconsider their actions


def get_protein_rnas_number(seq: int, **_) -> int:
Copy link
Member

Choose a reason for hiding this comment

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

Зачем тут **_ ?

Comment on lines +404 to +407
check_upper = True
for letter in (set(codon)):
check_upper = letter.isupper() and check_upper
return check_upper
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
check_upper = True
for letter in (set(codon)):
check_upper = letter.isupper() and check_upper
return check_upper
return all([letter.isupper() for letter in set(codon)])

return len(seq)


def count_aa(seq: str, aminoacids: str = None, **_) -> dict:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
def count_aa(seq: str, aminoacids: str = None, **_) -> dict:
def count_aas(seq: str, aminoacids: str = None) -> dict:


Arguments:
- seq (str): sequence to count amino acids
- aminoacids (str): which amino acids to count in sequence
Copy link
Member

Choose a reason for hiding this comment

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

по смыслу это логичнее передавать списком

- dict: a dictionary with amino acids and its count
"""

aa_dict_count = {}
Copy link
Member

Choose a reason for hiding this comment

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

  1. Множественное число
  2. Не надо писать тип данных в названии переменной. Мы же не пишем for i_int in range(0,10):
Suggested change
aa_dict_count = {}
aas_counts = {}

return "You don't fucking know what you're doing!" # politely ask user to reconsider their actions


def get_length_of_protein(seq: str, **_) -> int:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
def get_length_of_protein(seq: str, **_) -> int:
def get_protein_length(seq: str) -> int:

Ну, конечно, тут ошибиться так-то негде:)
Я спокойно принимал эту функцию в других работах, потому что может не хватить фантазии / времени и так есть способ добить чем то простеньким. Ладно бы хотя бы оно правильно считало длину и в однобуквенном и в трехбуквенном коде. Но так-то это совсем примитивно)
Опять же, мы это принимали, но тут вы написали в 2 раза больше функций чем надо. Мы всё равно все в любом случае проверяем (а еще перепроверяем). В первую очередь это отнимает скорость и качество проверки у ваших коллег)). И теперь еще эта функция выделяется как одна из ваших лучших функций. Я не согласен. Почти все (если не все) ваши функции лучше чем эта, даже не смотря на какие-то синтаксические недочеты.
Я не буду сейчас ставить за неё 0, хотя, если честно, захотелось )

Comment on lines +509 to +511
aa_dict_count = count_aa(seq, aminoacids=aminoacids)
aa_dict_percent = {}
len_of_protein = get_length_of_protein(seq)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
aa_dict_count = count_aa(seq, aminoacids=aminoacids)
aa_dict_percent = {}
len_of_protein = get_length_of_protein(seq)
aas_counts = count_aa(seq, aminoacids=aminoacids)
aa_dict_percent = {}
protein_len = get_length_of_protein(seq)

aa_dict_percent название переменной не соотвествует содержанию, там могут лежать не проценты


if show_as_percentage:
mult = 100
round_var = 2
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
round_var = 2
precision = 2

else:
mult = 1
round_var = 4
aa_dict_count = count_aa(seq, aminoacids=aminoacids)
Copy link
Member

Choose a reason for hiding this comment

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

Функция получается просто делает нормировку уже имеющейся. Опять же, в целом это ок, но тут из всего набора что у вас есть вы предлагаете две которые по сути одна, которая разбита на две (хоть и правильно сделана что разбита). Ну ок.

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.

5 participants