Comparació de seqüències ADN

Avís

Per a resoldre aquest exercici no es poden fer servir iteracions (ni for ni while ), només les funcions predefinides de Python i les dels mòduls itertools, functools i operator. Tampoc es poden fer servir llistes, tuples, diccionaris ni cap altra estructura de dades per a desar tots els elements dels iterables.

L”alineament de seqüències és un important problema de la bioinformàtica, consistent en comparar dues o més seqüències o cadenes d’ADN o ARN per ressaltar les seves zones de similitud. Lluny de resoldre el problema de l’alineament, ens volem ocupar de la comparació de seqüències d’ADN.

Suposarem que partim de dues seqüències d’ADN o ARN, representades com cadenes de caràcters. Ambdues cadenes tenen la mateixa longitud i estan formades únicament pels caràcters 'A', 'T', 'C', 'G', 'U' (cada caràcter indica una de les bases de l’ADN o ARN: adenina, timina, citosina, guanina, uracil). L’objectiu és saber com de semblants són aquestes dues seqüències.

Deseu al fitxer adn.py les funcions següents:

  1. Dissenyeu la funció següent:

    adn.fusiona(it1, it2)

    A partir de dos iterables it1 i it2 que produeixen dues seqüències com les que s’acaben de descriure, retorna un iterador amb la seqüència resultant de la comparació de les dues originals. Cada element i-èssim de l’iterador generat ha de ser o bé el mateix que els elements i-èssims de les dues seqüències originals, si aquests coincideixen, o bé el caràcter '*', si són diferents:

    >>> from adn import fusiona
    >>> it = fusiona('ACCTGAG','ACGTATG')
    >>> next(it)
    'A'
    >>> next(it)
    'C'
    >>> for x in it:
    ...     print(x, end="/")
    */T/*/*/G/
    >>> next(it)
    Traceback (most recent call last):
      ...
    StopIteration
    

    Per a resoldre aquest apartat es recomana utilitzar la funció map().

  2. Dissenyeu la funció següent:

    adn.sense_asteriscs(it)

    A partir de l’iterable it que genera una seqüència de caràcters, retorna un iterador amb la mateixa seqüència que l’original però en la qual s’han eliminat els caràcters '*':

    >>> from adn import sense_asteriscs
    >>> it = sense_asteriscs('GATT*GAT***AG*G*TCA*')
    >>> next(it)
    'G'
    >>> next(it)
    'A'
    >>> for x in it:
    ...     print(x, end="/")
    T/T/G/A/T/A/G/G/T/C/A/
    >>> next(it)
    Traceback (most recent call last):
      ...
    StopIteration
    

    Per a resoldre aquest apartat es recomana utilitzar la funció filter().

  3. Dissenyeu la funció següent:

    adn.iter_a_cadena(it)

    A partir de l’iterador it que genera una seqüència de caràcters, retorna la cadena de caràcters (string) corresponent a la seqüència:

    >>> from adn import iter_a_cadena
    >>> it = iter('DESOXIRIBONUCLEIC')
    >>> iter_a_cadena(it)
    'DESOXIRIBONUCLEIC'
    >>> it = iter(['A','B','C','D'])
    >>> iter_a_cadena(it)
    'ABCD'
    >>> next(it)
    Traceback (most recent call last):
      ...
    StopIteration
    

    Per a resoldre aquest apartat es recomana que utilitzeu el mètode str.join(). Una alternativa és utilitzar functools.reduce() i el mòdul operator.

  4. Dissenyeu la funció següent:

    adn.dues_cadenes(a, b)

    Donades dues cadenes de caràcters de la mateixa longitud, a i b retorna dues altres cadenes: la corresponent a la fusió de a i b amb asteriscs i la corresponent a la fusió de a i b sense els asteriscs:

    >>> from adn import dues_cadenes
    >>> dues_cadenes('ATACA','ACATA')
    ('A*A*A', 'AAA')
    

    Per a resoldre aquest apartat caldrà que utilitzeu tot el que heu fet anteriorment. També us pot ser útil la funció itertools.tee().

Disposeu de jocs de prova en els fitxers adn-1.txt i adn-2.txt i una solució a adn.py.