Skip to content
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

Hw4 smertina #7

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions HW4_Smertina/run_protein_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
def amino_acid_frequency(seq: str) -> dict:

"""
Calculates amino acid frequencies

Arguments:
-seq (str) input protein sequence
Return:
-dictionary with amino acid and its frequency

"""

# Словарь для хранения частоты аминокислот

Choose a reason for hiding this comment

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

Можно было не писать ))

freq_dict = {}
# Подсчитываем количество каждой аминокислоты в последовательности

Choose a reason for hiding this comment

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

Можно было не писать ))

for letter in seq:
if letter in freq_dict:
freq_dict[letter] += 1
else:
freq_dict[letter] = 1
# Преобразуем количество в проценты

Choose a reason for hiding this comment

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

Можно было не писать ))

for letter in freq_dict:
freq_dict[letter] = round(freq_dict[letter] / len(seq) * 100, 2)
return freq_dict

# Функция для поиска мотивов в белке

Choose a reason for hiding this comment

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

Можно было не писать ))

def find_motifs(seq: str, motif: str):

"""
Finds a motif of interest in a protein sequence
Arguments:
-seq (str) input protein sequence
-motif (str) motif to be found in sequence
Return:
-position(s) of the motif in seq

"""
# Список для хранения позиций мотивов в последовательности

Choose a reason for hiding this comment

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

Можно было не писать ))

positions = []
# Ищем мотив в последовательности с помощью скользящего окна

Choose a reason for hiding this comment

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

Можно было не писать ))

for i in range(len(seq) - len(motif) + 1):
window = seq[i:i+len(motif)]
if window == motif:
positions.append(i+1)

Choose a reason for hiding this comment

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

А зачем i + 1? 0_0
Представьте, что вы дальше в питоне хотите с этим работать ... а в итоге у вас получается сдвиг на 1 аминокислоту

return positions

def check_protein_seq(seq: str) -> str:

"""
Checks whether a sequence is written using 1-letter amino acid code

Arguments:
-seq (str) input protein sequence
Return:
- str, 'single_letter_prot_seq' otherwise 'Invalid Input' error is raised

"""
unique_chars = set(seq)
single_letter = set('GALMFWKQESPVICYHRNDTgalmfwkqespvicyhrndt')

if unique_chars <= single_letter:
seq = 'single_letter_prot_seq'

else:
raise ValueError("Invalid Input")
return seq
Comment on lines +61 to +66

Choose a reason for hiding this comment

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

Если у вас тут идет проверка только на валидность (что передали однобуквенную последовательность), то лучше вернуть тут bool (True/False)


def molecular_weight(seq: str) -> int:

"""
Calculates molecular weight of a protein

Arguments:
- seq (str) 1-letter coded protein sequence
Return:
- int, molecular weight (g/mol) rounded to integer

"""
if check_protein_seq(seq) == 'single_letter_prot_seq':

Choose a reason for hiding this comment

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

А зачем тут эта проверка?
Функция ж больше ничего не возвращает )))

list_input_seq = list(seq)

Choose a reason for hiding this comment

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

зачем? 0_0 ))

aa_weight_dict = {'G':75, 'g':75, 'A':89, 'a':89, 'R':174, 'r':174, 'N':132, 'n':132,
'D':133, 'd':133, 'C':121, 'c':133, 'E':147, 'e':147, 'Q':146, 'q':146,
'H':155, 'h':155, 'I':131, 'i':131, 'L':131, 'l':131, 'K':146, 'k':146,
'M':149, 'm':149, 'F':165, 'f':165, 'P':115, 'p':115, 'S':105, 's':105,
'T':119, 't':119, 'W':204, 'w':204, 'Y':181, 'y':181, 'V':117, 'v':117}
Comment on lines +81 to +85

Choose a reason for hiding this comment

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

А почему это в блоке ифа?
Кажется, это вообще можно вынести как константу в начало файла

water_mw = 18
for aa in list_input_seq:

Choose a reason for hiding this comment

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

for aa in seq ... и никаких листов не нужно )))

Choose a reason for hiding this comment

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

Ну и еще один вопрос по циклу ... а зачем он тут вообще нужен, если ниже вот эта aa вообще никак не используется? 0_0
То есть буквально:

        water_mw = 18
        total_mw = sum(aa_weight_dict[a] for a in seq)
        return total_mw - water_mw * (len(seq) - 1)

total_mw = sum(aa_weight_dict[a] for a in list_input_seq)

Choose a reason for hiding this comment

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

Зачем это тут?
То есть проходя по аминокислотам мы буквально каждый раз должны считать эту сумму (проходя по аминокислотам) )))
Почему бы не вынести было это до цикла for?

(Говоря на алгоритмическом, это вот уже вообще O(N**2) )

mw_water_removed = (total_mw - (water_mw * (len(list_input_seq)-1)))
return mw_water_removed
def one_to_three_letter(seq: str) -> str:
Comment on lines +90 to +91

Choose a reason for hiding this comment

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

Нету 2х пустых строк :(


"""
Converts a 1-letter amino acid code sequence into a 3-letter sequence

Arguments:
- seq (str) sequence to convert, must be 1-letter coded protein sequence
Return:
- str, a 3-letter coded protein sequence without spaces

"""
if check_protein_seq(seq) == 'single_letter_prot_seq':

Choose a reason for hiding this comment

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

Та же история. Тут эта проверка не нужна, раз функций только это и возвращает ))

aa_code_dict = {'C':'Cys', 'c':'Cys', 'D':'Asp', 'd':'Asp', 'S':'Ser', 's':'Ser', 'Q':'Gln', 'q':'Gln',
'K':'Lys', 'k':'Lys', 'I':'Ile', 'i':'Ile', 'P':'Pro', 'p':'Pro', 'T':'Thr', 't':'Thr',
'F':'Phe', 'f':'Phe', 'N':'Asn', 'n':'Asn', 'G':'Gly', 'g':'Gly', 'H':'His', 'h':'His',
'L':'Leu', 'l':'Leu', 'R':'Arg', 'r':'Arg', 'W':'Trp', 'w':'Trp', 'A':'Ala', 'a':'Ala',
'V':'Val', 'v':'Val', 'E':'Glu', 'e':'Glu', 'Y':'Tyr', 'y':'Tyr', 'M':'Met', 'm':'Met'}
Comment on lines +103 to +107

Choose a reason for hiding this comment

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

Это тоже бы вынести как константу в начало


three_letter_aa = ''

Choose a reason for hiding this comment

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

Тогда уж three_letter_seq

for aa in seq:
three_letter_aa += aa_code_dict[aa]
return three_letter_aa

from typing import Optional

Choose a reason for hiding this comment

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

Все импорты должны быть сверху файла ))

def run_protein_tool(*args: str, function: str, motif: Optional[str]=None):

"""
This is the main function
Arguments:
-seq(str) protein sequence(s)
-function(str) specify the function
-motif(str), optional argument for find_motifs function
Return:
-result of the specified function

"""
results = []
for seq in args:
check_protein_seq(seq)
if function == 'check_protein_seq':
results.append(check_protein_seq(seq))
elif function == 'molecular_weight':
results.append(molecular_weight(seq))
elif function == 'one_to_three_letter':
results.append(one_to_three_letter(seq))
elif function == 'amino_acid_frequency':
results.append(amino_acid_frequency(seq))
elif function == 'find_motifs':
results.append(find_motifs(seq, motif))
if len(results) == 1:
results = results[0]

Choose a reason for hiding this comment

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

return results[0]

return results

94 changes: 55 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,81 @@
# HW 4. Functions 2
> *This is the repo for the fourth homework of the BI Python 2023 course*
# run_protein_tool

### Homework description
```run_protein_tool``` includes a set of commands that perform various operations with protein or peptide sequences of any length. The input sequence(s) must be written
using 1-letter amino acid code and can contain any of the following 20 amino acids:

На прошлой неделе вы делали утилиту для работы с последовательностями нуклеиновых кислот (с весьма строгим ТЗ). Пришло время для чего-то более самостоятельного.
![aacids](https://github.com/sme229/HW4_Functions2/assets/104040609/825a697f-5562-4829-9771-01e3b519bdee)

#### Основное задание
The following functions are implemented:

1. ```molecular_weight``` This function takes 1-letter coded protein sequence(s) (string) and calculates molecular weight rounded to integer in g/mol. The function is not case-sensitive.
Usage examples:
```
run_protein_tool('peptide', function='molecular_weight')
799
```
```
run_protein_tool('pEpTiDe', function='molecular_weight')
799
```
2. ```one_to_three_letter``` This function takes 1-letter coded protein sequence(s) (string) and returns a 3-letter coded sequence(s) without spaces (string). Usage examples:
```
run_protein_tool('PEPTIDE', function='one_to_three_letter')
'ProGluProThrIleAspGlu'
```
```
run_protein_tool('p', 'peptide', function='one_to_three_letter')
['Pro', 'ProGluProThrIleAspGlu']
```
3. ```amino_acid_frequency``` This function takes 1-letter coded protein sequence(s) (string), calculates frequency for each unique amino acid and creates a dictionary
with amino acids as keys and corresponding frequencies as values. Usage example:

Напишите утилиту для работы с последовательностями белков. Там должно быть минимум 5 различных операций, должна быть какая-то точка входа через которую пользователь будет всё это дело использовать. На этом, по сути, всё. Всё целиком зависит от вашей фантазии и креативности. Можете опираться на ДЗ №2 и №3.
```
run_protein_tool('MADSEQNQEEAGGGEQREH', function='amino_acid_frequency')
{'M': 5.26,
'A': 10.53,
'D': 5.26,
'S': 5.26,
'E': 26.32,
'Q': 15.79,
'N': 5.26,
'G': 15.79,
'R': 5.26,
'H': 5.26}
```
4. ```find_motifs``` This function takes two string arguments: 1-letter coded protein sequence(s) and a motif of interest, where motif is any sequence which occurence
will be searched for in the input protein sequence(s). The function returns position(s) of the motif. If a motif was not found, the function will return an empty list.
Please note that this function can only search for one motif at a time. Usage example:

Самая главная часть задания - это файл `README.md`. Сделайте краткое введение, напишите описание тула, приведите документацию по использованию со списком аргументов. Добавьте примеры использования. Возможно, вы захотите сделать секцию Troubleshooting. ***Почему это нужно?*** В этот раз проверяющий не будет знать того, как должен работать ваш тул. Это ваш авторский код. Даже самая прекрасная функциональность, не будучи отраженной в README, скорее всего останется незамеченной. README - это ваш способ познакомить пользователя с тулом, показать всё лучше и обосновать, почему именно ваша команда должна получить наивысший балл.
```
find_motifs('MADSEQNQEEAGGGEQREH', function='find_motifs', motif='GG')
[12, 13]
```
# Troubleshooting

Есть люди которые, любят писать документации, а есть те - кто не любит. Найдите в вашей команде того, кто любит. И в будущем в своих рабочих проектах всегда держите рядом такого человек (или будьте им).
Please make sure that your input sequence(s) is written using the **1-letter** amino acid code as shown in the examples. A sequence containing letters that
do not correspond to one of the 20 amino acids from the table above will result in 'Invalid Input' error. Please note that function ```find_motifs``` also requires the motif
of interest as input after the function name.

Примеры некоторых README, которыми можно вдохновляться:
# Contributors

- [MetaFX](https://github.com/ctlab/metafx), тул Артёма Иванова. Там еще и [wiki](https://github.com/ctlab/metafx/wiki) крутое.
- [samovar](https://github.com/nvaulin/samovar)
- [MetaGEM](https://github.com/franciscozorrilla/metaGEM)
- [Pharokka](https://github.com/gbouras13/pharokka)
Elena Smertina implemented check_protein_seq, molecular_weight, one_to_three_letter and run_protein_tool functions;
Natalia Erofeeva implemented amino_acid_frequency and find_motifs functions.

Типовые секции, на которые стоит обратить внимание: Title, Overview, Usage, Options, Examples, Troubleshooting, Contacts.

**Tехническое требование к заданию.**

Это задание будет выполняться в командах по 3 человека. Каждый из членов команды должен внести <ins>***как минимум***</ins> 2 функции. Каждое внесение функции должно сопровождаться коммитом с осмысленным описанием коммита. Ниже приведена последовательность действий для успешного выполнения задания (аналогично ДЗ №2):

1. Посмотрите состав своей команды здесь ([**ССЫЛКА**](https://docs.google.com/spreadsheets/d/1KMBBBu8LqauRpDJb0v1ldPwpvzNn8-KakcHexAcqLsE/edit?usp=sharing)).
2. Тимлид делает форк данного репозитория. **В форке создает ветку `HW4_<surname>`, в ветке создает папку `HW4_<surname>`, в этой папке вы всё делаете.**

Choose a reason for hiding this comment

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

По заданию, собственно, нужно было ридми делать в папке HW4_ ))

3. Члены команды могут либо делать свои форки, либо работать в репозитории тимлида в качестве колабораторов ("contributors"). В любом случае делаете клоны => пишите код локально => пушите.
4. В конце тимлид делайет pull-request из `HW4_<surname>` своего репозитория в `main` этого.


А также:
- Сопроводите программу лучшим `README.md` файлом в вашей жизни (на английском языке).
- В этом ДЗ проблемы с качеством кода (нейминги, пустые строки, анноатции типов, док.стринги, пробелы) могут привести к снижению балла. Воспользуйтесь линтерами чтобы себя обезопасить. IDE по типу PyCharm или VSCode имеют фунцонал по авто-исправлению многих проблем такого рода.

Автотестов на GitHub в этом ДЗ нет, но вы можете прогнать линтеры на качество кода локально (как в ДЗ №3, подробнее читайте [тут](https://plausible-cannon-091.notion.site/Code-auto-checks-02b2ea69c1d545fca07b50ce5933ed5f?pvs=4)).

- Программа должна сохранять регистр символов.
- Программа должна работать только с последовательностями белков.
- Запрещается использование сторонних модулей.


### Форма сдачи

Прикрепите ссылку на pull-request тимлида в Google Class (можете сделать от лица каждого члена команды, но это не обязательно).


### Pазбалловка

- За каждую из 5 операций - максимум **1.5 балла**
- За README - максимум **2.5 балла**
- Если вы не внесли как минимум 2 функции от себя, вы получаете 0 баллов (на баллы остальных членов команды это не влияет).
- За фото созвона в README можно получить 0.2 доп. балла (но не более 10 баллов суммарно)



### **Предполагаемый учебный результат**

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

Удачи! ✨✨