Hw4 voskoboinikov#27
Conversation
Hw4 vasilev
Hw4 lisitsa
Hw4 vasilev
…s, convert_aa_name Remove '/ Args' in all 3 functions
Update docstrings and comments
…ns2 into HW4_Vasilev
Hw4 vasilev
Hw4 vasilev
… into HW4_Voskoboinikov
Update README.md
albidgy
left a comment
There was a problem hiding this comment.
Для проверки выбрала случайных 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: |
There was a problem hiding this comment.
Зачем здесь эта проверка? Какую смысловую нагрузку несет? Фактически программа просто останавливает работу, если не указать этот параметр. Не лучшее решение.
| for codon in codons: | ||
| for kmer in kmers: | ||
| current_kmers.append(kmer + codon) # append every codon to existing kmers |
There was a problem hiding this comment.
Конкатенация строк - долгий и не оптимальный процесс, лучше использовать добавление элемента к списку.
| if aa_atomic_mass is None: | ||
| aa_atomic_mass = AA_MASS_DICT |
There was a problem hiding this comment.
Не нужно так делать. Словарь можно вызывать напрямую.
| total_mass = 0 | ||
| char = 0 # idx init | ||
| if atomic_mass is None: | ||
| atomic_mass = ATOMIC_MASS |
There was a problem hiding this comment.
Можно словарь вызывать напрямую. Не нужно его записывать в другую переменную.
| element = chem[char] | ||
| char += 1 # очень надо, а то я опять бесконечный цикл сделала | ||
| if char < len(chem) and chem[char].isdigit(): | ||
| number = '' |
There was a problem hiding this comment.
Лучше не использовать конкатенацию строк, а добавлять элемента в список.
There was a problem hiding this comment.
А можно вопрос, для случая с глюкозой допустим C6H12O6, как обойти конкатенацию, просто не очень понимаю. Спасибо.
There was a problem hiding this comment.
Вообще сам по себе этот код неоптимальный. Но быстро я не придумала, как его аккуратнее переписать. Я подумаю на выходных, как можно иначе написать.
Касаемо конкатенации строк, лучше сделать так:
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): |
|
|
||
| def run_ultimate_protein_tools(command, | ||
| inp, | ||
| *args, |
There was a problem hiding this comment.
Использование *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) |
There was a problem hiding this comment.
Вы передаете в функцию 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 |
There was a problem hiding this comment.
Лучше выбрасывать ошибку и более корректную.
| """ | ||
| output_dct = {} | ||
| input_dct = parse_input(inp, **kwargs) | ||
| for name in input_dct: |
There was a problem hiding this comment.
Здесь выдается не имя, а порядковый номер, лучше иттерироваться по значениям, чтобы выдавать последовательность. Так будет более информативно.
Амнистия за мат (всем членам команды), т.к. все таки обычная шутка |
nvaulin
left a comment
There was a problem hiding this comment.
Всем привет еще раз, был запрос проверить другой набор функций. Запрос одобрил, функции пере-оценил (не "переоценил"), можете также найти комментарии к коду.
В следуйщий раз предусмотрим чтобы "сделать в 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
| 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 |
There was a problem hiding this comment.
В данном случае получаются небольшие проблемы с логикой. Вы проверяете булево выражение какое булево значение оно выдает, и если условие выполнилось, то возвращаете булево значение, а иначе проходите мимо него и возвращате другое булево значение. Тут можно было бы гораздно проще - сразу возвращать результат булевой операции :)
| 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: |
| check_upper = True | ||
| for letter in (set(codon)): | ||
| check_upper = letter.isupper() and check_upper | ||
| return check_upper |
There was a problem hiding this comment.
| 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: |
There was a problem hiding this comment.
| 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 |
There was a problem hiding this comment.
по смыслу это логичнее передавать списком
| - dict: a dictionary with amino acids and its count | ||
| """ | ||
|
|
||
| aa_dict_count = {} |
There was a problem hiding this comment.
- Множественное число
- Не надо писать тип данных в названии переменной. Мы же не пишем
for i_int in range(0,10):
| 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: |
There was a problem hiding this comment.
| def get_length_of_protein(seq: str, **_) -> int: | |
| def get_protein_length(seq: str) -> int: |
Ну, конечно, тут ошибиться так-то негде:)
Я спокойно принимал эту функцию в других работах, потому что может не хватить фантазии / времени и так есть способ добить чем то простеньким. Ладно бы хотя бы оно правильно считало длину и в однобуквенном и в трехбуквенном коде. Но так-то это совсем примитивно)
Опять же, мы это принимали, но тут вы написали в 2 раза больше функций чем надо. Мы всё равно все в любом случае проверяем (а еще перепроверяем). В первую очередь это отнимает скорость и качество проверки у ваших коллег)). И теперь еще эта функция выделяется как одна из ваших лучших функций. Я не согласен. Почти все (если не все) ваши функции лучше чем эта, даже не смотря на какие-то синтаксические недочеты.
Я не буду сейчас ставить за неё 0, хотя, если честно, захотелось )
| aa_dict_count = count_aa(seq, aminoacids=aminoacids) | ||
| aa_dict_percent = {} | ||
| len_of_protein = get_length_of_protein(seq) |
There was a problem hiding this comment.
| 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 |
There was a problem hiding this comment.
| round_var = 2 | |
| precision = 2 |
| else: | ||
| mult = 1 | ||
| round_var = 4 | ||
| aa_dict_count = count_aa(seq, aminoacids=aminoacids) |
There was a problem hiding this comment.
Функция получается просто делает нормировку уже имеющейся. Опять же, в целом это ок, но тут из всего набора что у вас есть вы предлагаете две которые по сути одна, которая разбита на две (хоть и правильно сделана что разбита). Ну ок.
No description provided.