Project: s41467-024-46107-z | Function: differencestrings (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Compares reference and query DNA sequences to identify mutations including replacements, insertions and deletions for prime editor evolution analysis

**KEY TERMS:** {
  "ref": "reference sequence",
  "query": "evolved sequence variant",
  "differencelist": "list of sequence differences",
  "mutations": "identified mutations list",
  "positionref": "position in reference sequence",
  "positionquery": "position in query sequence"
}

**CONTEXT CODE:** import pandas as pd
from Bio.Seq import Seq
from diff_match_patch import diff_match_patch
from collections import Counter
from os import listdir


def aminoacidchangefunc(position, initialbp, mutatedbp):
    '''Show amino acid change from reference to query.'''
    # MASKED: Calculates amino acid changes from nucleotide mutations in prime editor protein evolution analysis implementation
    raise NotImplementedError("This function is masked for testing purposes.")
    
    
def differencestrings(ref,query):
    '''Compare reference to query and return list with mutations on nucleotide basis.'''
    # MASKED: Compares reference and query DNA sequences to identify mutations including replacements, insertions and deletions for prime editor evolution analysis implementation
    raise NotImplementedError("This function is masked for testing purposes.")


def fasta2df(infile):
    '''Read .fasta file and store it as dataframe. Remove spaces in fasta filename first'''
    # MASKED: Converts FASTA sequence files to dataframe format for mutation analysis in prime editor evolution implementation
    raise NotImplementedError("This function is masked for testing purposes.")


referencepath = 'Define_Path'
def list_files1(path):
    return [f for f in listdir(path) if '.fa' in f]

# Global variable used by aminoacidchangefunc
pereference = ""

if __name__ == "__main__":
    referencelist = list_files1(referencepath)
    for reference in referencelist:  # loop through all evolutions/domains
        referencename = reference
        folder1name = '_'.join(referencename.split('_')[:2])
        editorname = referencename.split('_')[-1][:-3]
        fastapath = referencepath+folder1name+'\\'+editorname+'\\'
        fastaname = editorname+".fa"

        pereference = pd.read_csv(referencepath+referencename).iloc[0,0]
        pereferencelength = len(pereference)

        fasta = fasta2df(fastapath+fastaname)
        fasta['length'] = fasta.sequence.apply(lambda x: len(x))

        # remove reads which deviate more than x bp from reference sequence:
        maxlengthdeviation = 10
        fasta = fasta[(fasta.length <pereferencelength+maxlengthdeviation) & (fasta.length >pereferencelength-maxlengthdeviation)]

        mutationdf = pd.DataFrame()
        mutationsummary = []
        aasummary = []
        for index, query in fasta.iterrows():
            try:
                mutations, mutationshortlist, replacementonly, aachange = differencestrings(pereference,query['sequence'])
            except IndexError:
                print(query['sequence'])
                print()
            mutationsummary+=mutationshortlist
            aasummary+=aachange
            mutationdf.loc[index,'replacementmutations'] = str(replacementonly)
            mutationdf.loc[index,'mutationshortlist'] = str(mutationshortlist)
            mutationdf.loc[index,'mutations'] = str(mutations)
            mutationdf.loc[index,'aachangereplacement'] = str(aachange)
            print(replacementonly)
            print()

        aacount = Counter(aasummary)
        aacountdf = pd.DataFrame.from_dict(aacount, orient='index').reset_index()

        aacombinationcount = Counter(mutationdf['aachangereplacement'])
        aacombinationcountdf = pd.DataFrame.from_dict(aacombinationcount, orient='index').reset_index()

        mutationcount = Counter(mutationsummary)
        mutationcountdf = pd.DataFrame.from_dict(mutationcount, orient='index').reset_index()

        mutationcombinationcount = Counter(mutationdf['mutationshortlist'])
        mutationcombinationcountdf = pd.DataFrame.from_dict(mutationcombinationcount, orient='index').reset_index()


        aacountdf.to_csv(fastapath+'\\Define_path'+referencename[:-3]+'.csv')
        aacombinationcountdf.to_csv(fastapath+'\\Define_path'+referencename[:-3]+'.csv')
        mutationdf.to_csv(fastapath+'\\Define_path'+referencename[:-3]+'.csv')
        mutationcountdf.to_csv(fastapath+'\\Define_path'+referencename[:-3]+'.csv')
        mutationcombinationcountdf.to_csv(fastapath+'\\Define_path'+referencename[:-3]+'.csv')


Complete the function implementation replacing "raise NotImplementedError".