0

I have a program that needs to take user input to find a FASTA file containing a protein sequence (and give an error if the file can't be found), then scan through the sequence and find these four-letter sequences that follow the following rules: Start with "N", then anything but "P", then "S" or "T", then anything but "P". I have the part where an error is given if the file is not found. However, when scanning through the sequence, I am only receiving one-letter sequences.

Here is my code:

import re
userinput = input("Please provide a FASTA file.")
while userinput:
    try:
        if userinput == "0":
            break
        with open(userinput, mode = 'r') as protein:
            readprotein = protein.read()
        matches = re.findall('N[^P](S|T)[^P]', readprotein)
        for match in matches:
            print(match)
        break
    except FileNotFoundError:
        print("File not found. Please ensure that you are typing the file name exactly as it is found with the file extension.")
        userinput = input("Please provide a FASTA file. 0 to quit.")

The FASTA file that I'm working with is the HIV Type-2 proteome, and here's a small snippet:

>sp|P18096|POL_HV2BE Gag-Pol polyprotein OS=Human immunodeficiency virus type 2 subtype A (isolate BEN) OX=11714 GN=gag-pol PE=3 SV=4
MGARNSVLRGKKADELEKVRLRPGGKKKYRLKHIVWAANELDKFGLAESLLESKEGCQKI
LRVLDPLVPTGSENLKSLFNTVCVIWCLHAEEKVKDTEEAKKLAQRHLVAETGTAEKMPN
TSRPTAPPSGKRGNYPVQQAGGNYVHVPLSPRTLNAWVKLVEEKKFGAEVVPGFQALSEG
CTPYDINQMLNCVGDHQAAMQIIREIINEEAADWDSQHPIPGPLPAGQLRDPRGSDIAGT
TSTVDEQIQWMYRPQNPVPVGNIYRRWIQIGLQKCVRKYNPTNILDIKQGPKEPFQSYVD
RFYKSLRAEQTDPAVKNWMTQTLLIQNANPDCKLVLKGLGMNPTLEEMLTACQGVGGPGQ
KARLMAEALKEAMGPSPIPFAAAQQRKAIRYWNCGKEGHSARQCRAPRRQGCWKCGKPGH
IMANCPERQAGFFRVGPTGKEASQLPRDPSPSGADTNSTSGRSSSGTVGEIYAAREKAEG
AEGETIQRGDGGLAAPRAERDTSQRGDRGLAAPQFSLWKRPVVTAYIEDQPVEVLLDTGA
DDSIVAGIELGDNYTPKIVGGIGGFINTKEYKNVEIKVLNKRVRATIMTGDTPINIFGRN
ILTALGMSLNLPVAKIEPIKVTLKPGKDGPRLKQWPLTKEKIEALKEICEKMEKEGQLEE
APPTNPYNTPTFAIKKKDKNKWRMLIDFRELNKVTQDFTEIQLGIPHPAGLAKKKRISIL
DVGDAYFSIPLHEDFRQYTAFTLPAVNNMEPGKRYIYKVLPQGWKGSPAIFQYTMRQVLE
PFRKANPDVILIQYMDDILIASDRTGLEHDKVVLQLKELLNGLGFSTPDEKFQKDPPFQW
MGCELWPTKWKLQKLQLPQKDIWTVNDIQKLVGVLNWAAQIYSGIKTKHLCRLIRGKMTL
TEEVQWTELAEAELEENKIILSQEQEGYYYQEEKELEATIQKSQGHQWTYKIHQEEKILK
VGKYAKIKNTHTNGVRLLAQVVQKIGKEALVIWGRIPKFHLPVERETWEQWWDNYWQVTW
IPEWDFVSTPPLVRLTFNLVGDPIPGAETFYTDGSCNRQSKEGKAGYVTDRGKDKVKVLE
QTTNQQAELEVFRMALADSGPKVNIIVDSQYVMGIVAGQPTESENRIVNQIIEEMIKKEA
VYVAWVPAHKGIGGNQEVDHLVSQGIRQVLFLEKIEPAQEEHEKYHSIIKELTHKFGIPL
LVARQIVNSCAQCQQKGEAIHGQVNAEIGVWQMDYTHLEGKIIIVAVHVASGFIEAEVIP
QESGRQTALFLLKLASRWPITHLHTDNGPNFTSQEVKMVAWWVGIEQSFGVPYNPQSQGV
VEAMNHHLKNQISRIREQANTIETIVLMAVHCMNFKRRGGIGDMTPAERLINMITTEQEI
QFLQRKNSNFKNFQVYYREGRDQLWKGPGELLWKGEGAVIVKVGTDIKVVPRRKAKIIRD
YGGRQELDSSPHLEGAREDGEMACPCQVPEIQNKRPRGGALCSPPQGGMGMVDLQQGNIP
TTRKKSSRNTGILEPNTRKRMALLSCSKINLVYRKVLDRCYPRLCRHPNT
>sp|P18095|GAG_HV2BE Gag polyprotein OS=Human immunodeficiency virus type 2 subtype A (isolate BEN) OX=11714 GN=gag PE=3 SV=3
MGARNSVLRGKKADELEKVRLRPGGKKKYRLKHIVWAANELDKFGLAESLLESKEGCQKI
LRVLDPLVPTGSENLKSLFNTVCVIWCLHAEEKVKDTEEAKKLAQRHLVAETGTAEKMPN
TSRPTAPPSGKRGNYPVQQAGGNYVHVPLSPRTLNAWVKLVEEKKFGAEVVPGFQALSEG
CTPYDINQMLNCVGDHQAAMQIIREIINEEAADWDSQHPIPGPLPAGQLRDPRGSDIAGT
TSTVDEQIQWMYRPQNPVPVGNIYRRWIQIGLQKCVRKYNPTNILDIKQGPKEPFQSYVD
RFYKSLRAEQTDPAVKNWMTQTLLIQNANPDCKLVLKGLGMNPTLEEMLTACQGVGGPGQ
KARLMAEALKEAMGPSPIPFAAAQQRKAIRYWNCGKEGHSARQCRAPRRQGCWKCGKPGH
IMANCPERQAGFLGLGPRGKKPRNFPVTQAPQGLIPTAPPADPAAELLERYMQQGRKQRE
QRERPYKEVTEDLLHLEQRETPHREETEDLLHLNSLFGKDQ

Obviously, the error within my code lies within the "findall" function that my professor instructed me to use, and I think it may just be because I can't fully wrap my head around the use of regular expressions. What I have is re.findall('N^P[^P]', readprotein). I don't see why the single letter sequences that I am getting don't even start with "N", it is just a bunch of "T"s or "S"s. Any help is appreciated!

  • Your example has newlines in the sequence, you might need/want to remove those before searching. – wwii Dec 10 '19 at 20:18

1 Answers1

0

The problem is that (S|T) is a capturing group, so re.findall returns just the part of the match which it captures. You can fix it by writing (?:S|T) to make it a non-capturing group instead, so that re.findall returns the whole match.

Example:

>>> import re
>>> re.findall('N[^P](S|T)[^P]', 'NSTN')
['T']
>>> re.findall('N[^P](?:S|T)[^P]', 'NSTN')
['NSTN']
kaya3
  • 47,440
  • 4
  • 68
  • 97