Extract, filter and match three letters from the given arguments and predict the name

Case 1: rank1_naming

This function takes two arguments

• list_proteins_pattern_available
• best_match_protein_name

Objective: Extract the three letter pattern from the both arguments. Match the pattern and keep only the matched items. Extract the numbers from list_proteins_pattern_available and also sort it. Find the maximum number from the collected numbers and add 1 to get the next number.

Please let me know if you have any questions.

Can you point ways to improve this script?

import re

def case_rank1_naming(list_proteins_pattern_available, best_match_protein_name):
#This will store the list of numbers
available_list_numbers = []

#extract the three letter pattern
protein_pattern = re.search(r"[A-Z]{1}[a-z]{2}", best_match_protein_name)
protein_pattern = protein_pattern.group()

#extract the numbers
for name in list_proteins_pattern_available:
pattern = re.search(r"[A-Z]{1}[a-z]{2}\d{1,3}", name)
number = re.search(r"\d{1,3}", pattern.group())
available_list_numbers.append(number.group())

#Convert all the string numbers to integers
available_list_numbers = [int(x) for x in available_list_numbers]

#Sort the available number. Just realized I use two times sort function.
available_list_numbers.sort()

# Sort the available number, get the maximum number and add one to get next number
# Example: result will be 50
primary_number_prediction = int(max(sorted(available_list_numbers))) + 1

#Add the protein pattern, the next predicted number and 'Aa1' at the suffix
predicted_name = protein_pattern + str(primary_number_prediction) + 'Aa1'

return predicted_name

list_proteins_pattern_available = ['Xpp1Aa1', 'Xpp2Aa1', 'Xpp35Aa1', 'Xpp35Ab1', 'Xpp35Ac1', 'Xpp35Ba1', 'Xpp36Aa1', 'Xpp49Aa1', 'Xpp49Ab1']

best_match_protein_name = 'Xpp35Ba1'

predicted_name = case_rank1_naming(list_proteins_pattern_available, best_match_protein_name)

print(predicted_name)
#Xpp50Aa1


I'll show an example implementation first, and then describe it:

from typing import Iterable
import re

def case_rank1_naming(proteins_available: Iterable[str], best_match_protein_name: str) -> str:
# extract the three-letter pattern
protein_pattern = re.search(r"[A-Z][a-z]{2}", best_match_protein_name).group()

# extract the numbers
best_number = max(
int(re.search(r"[A-Z][a-z]{2}(\d{1,3})", name)[1])
for name in proteins_available
)

# Add the protein pattern, the next predicted number and 'Aa1' at the suffix
return f'{protein_pattern}{best_number + 1}Aa1'

def main():
proteins_available = (
'Xpp1Aa1', 'Xpp2Aa1', 'Xpp35Aa1', 'Xpp35Ab1', 'Xpp35Ac1',
'Xpp35Ba1', 'Xpp36Aa1', 'Xpp49Aa1', 'Xpp49Ab1'
)
best_match_protein_name = 'Xpp35Ba1'
predicted_name = case_rank1_naming(proteins_available, best_match_protein_name)
assert predicted_name == 'Xpp50Aa1'

if __name__ == '__main__':
main()

• Don't write {1} in a regex - you can just drop it
• Call max immediately on a generator rather than making and sorting a list
• Have a main function
• In main, use a tuple for proteins_available instead of a list because it doesn't need to mutate