Hoy vamos a ver más ejercicios de Python con secuencias de ADN. Son 9 ejercicios y se trabaja con cadenas, bases y secuencias.
La descripción dice así:
- Desarrollar un programa en Python para usar distintas funciones. El programa debe ofrecer un menú.
- Al comienzo del programa preguntar si se desea ingresar una secuencia particular en cada opción correspondiente del menú o si se desea trabajar todo el programa con una misma secuencia fija, que se cargará inicialmente.
- En todos los casos se debe controlar que las secuencias ingresadas sean válidas (contengan exclusivamente “A”, “C”, “T”, “G”, y largo de la secuencia mayor o igual a 1) sin importar mayúsculas y minúsculas.
Luego se muestra el menú con estas opciones:
- Opción 0: Salir del programa
- Opción 1-9: En cada opción, según se haya indicado inicialmente, se trabaja con la secuencia fija o se solicita una al usuario si corresponde.
En caso de ser necesarios datos adicionales específicos, se solicitan. En cada opción se invoca a la función correspondiente que se detalla a continuación y se muestra el resultado por pantalla.
Python – Secuencias de ADN
A continuación colocaré los 9 puntos que se solicitan y luego el código:
1. transformar_ADN_ARN(secuencia): retorna la transformación de la secuencia de ADN en ARN (cambiando la base “T” por “U”).
Ejemplo: Recibe: “AGGTCT”, retorna: “AGGUCU”.
2. tieneStartStop(secuencia): retorna verdadero si la secuencia empieza con “ATG” y termina con stop: “TGA” y además, entre ambas debe haber una cantidad múltiplo de 3 de bases. No puede contener otras secuencias “ATG” o “TGA”.
Ejemplo: Recibe: “ATGCCAATTTGA”, retorna true. Recibe: “ATACCA”, retorna false.
3. mostrar(secuencia): considerar las bases “A”, “C”, “T” y “G”, retornar la información de cada una de ellas, indicando la cantidad presente en la secuencia (representándola con la misma cantidad de “*””) y el % correspondiente.
Ejemplo: Recibe: “TAAACAACCT”, retorna: A ***** 50.0% C *** 30.0% T ** 20.0% G 0.0%
4. resumir(secuencia): retorna la secuencia en forma resumida, indicando por cada base de la secuencia la cantidad de veces que está en forma consecutiva.
Ejemplo: Recibe: “ATTCAAAAATCAGGG”, retorna: “A1T2C1A5T1C1A1G3” Recibe: “AAAAAAAAAAAA”, retorna: “A12”.
5. duplicar(secuencia): retorna la secuencia recibida duplicando cada base.
Ejemplo: Recibe: “ATAGTG”, retorna: “AATTAAGGTTGG”.
6. segmentos(secuencia): retorna la cantidad de segmentos en la secuencia recibida. Un segmento se define como una secuencia de una o más bases “G”, “T” y, o “C”, delimitada por “A”.
Ejemplo: Recibe: “AATAGCACTTAC”, retorna: 3. Recibe: “AATAGCACTTACA”, retorna: 4. Recibe: “AAAAA”, retorna: 0.
7. expandir(datos): recibe un string de datos formado por bases y cantidades (se asume válido, las cantidades van de 1 a 9) y retorna la secuencia correspondiente.
Ejemplo: Recibe “A1T2C1A5T1C1A1G3”, retorna: “ATTCAAAAATCAGGG”
8. primeraBaseUnica(secuencia): retorna cuál es la posición de la primera base que está una única vez en la secuencia. Si no hay ninguna, retorna -1.
Ejemplo: Recibe “GAGTAAA”, retorna 3. Recibe: “GATAAGACTTC”, retorna -1. Recibe: “AGC” retorna 0.
9. periodica(secuencia): recibe una secuencia y retorna verdadero si es periódica, esto es, si se puede rearmar tomando un subgrupo de una o más bases sucesivas de la secuencia y replicándolos para formar la secuencia recibida, concatenando el subgrupo las veces necesarias.
Ejemplo: Recibe: “AGAG”, retorna true. Recibe: “AGA”, retorna false. Recibe: “GATGATGATGAT”, retorna true.
Código de solución
Ya mostré anteriormente lo solicitado, ahora la solución. Por cierto, ya he explicado por separado varios ejercicios que aparecen aquí, dejo los enlaces en el lugar donde corresponde.
Para el ejercicio 1 simplemente remplazamos una letra por otra. En el segundo comprobamos si empieza y termina con una subcadena, para el tercero contamos la frecuencia de letras que hay en una frase.
Siguiendo con el ejercicio 4 lo que se hace es comprimir o resumir una cadena, en el 5 duplicamos cada letra.
Luego en el 7 tenemos que expandir la cadena según el número que aparece a su lado, en el 8 comprobamos si la base aparece solo una vez y en el 9 comprobamos si la string es periódica.
# https://parzibyte.me/blog
def transformar_ADN_ARN(secuencia):
arn = ""
for base in secuencia:
if base == "T":
arn += "U"
else:
arn += base
return arn
def tieneStartStop(secuencia):
# Si no tiene el inicio, el final y algo (3 + 3 + algo) entonces no
if len(secuencia) < 7:
return False
inicio = secuencia[:3]
fin = secuencia[-3:]
if inicio != "ATG":
return False
if fin != "TGA":
return False
parte_central = secuencia[3:-3]
longitud_parte_central = len(parte_central)
if longitud_parte_central % 3 != 0:
return False
if "ATG" in parte_central:
return False
if "TGA" in parte_central:
return False
# Si pasó todas las validaciones de arriba, entonces es válido
return True
def mostrar(secuencia):
longitud = len(secuencia)
cantidad_a = 0
cantidad_c = 0
cantidad_t = 0
cantidad_g = 0
for base in secuencia:
if base == "A":
cantidad_a += 1
elif base == "C":
cantidad_c += 1
elif base == "T":
cantidad_t += 1
elif base == "G":
cantidad_g += 1
porcentaje_a = (cantidad_a * 100) / longitud
porcentaje_c = (cantidad_c * 100) / longitud
porcentaje_t = (cantidad_t * 100) / longitud
porcentaje_g = (cantidad_g * 100) / longitud
salida = ""
salida += "A " + ("*" * cantidad_a) + " " + str(porcentaje_a) + "% "
salida += "C " + ("*" * cantidad_c) + " " + str(porcentaje_c) + "% "
salida += "T " + ("*" * cantidad_t) + " " + str(porcentaje_t) + "% "
salida += "G " + ("*" * cantidad_g) + " " + str(porcentaje_g) + "% "
return salida
def resumir(secuencia):
ultima_base = secuencia[0]
salida = ""
conteo = 0
indice = 0
for base in secuencia:
if base == ultima_base:
conteo += 1
else:
if conteo > 0:
salida += ultima_base + str(conteo)
conteo = 1
ultima_base = base
# Caso especial cuando llegamos al final
if indice + 1 >= len(secuencia):
salida += ultima_base + str(conteo)
indice += 1
return salida
def duplicar(secuencia):
salida = ""
for base in secuencia:
salida += base*2
return salida
def segmentos(secuencia):
print(secuencia)
conteo = 0
inicio_de_segmento_encontrado = False
for base in secuencia:
if base == "A":
if inicio_de_segmento_encontrado:
conteo += 1
inicio_de_segmento_encontrado = False
else:
inicio_de_segmento_encontrado = True
return conteo
def expandir(datos):
salida = ""
# Hacer un ciclo "de 2 en 2", es decir, vamos en 0, 2, 4, 6, etcétera
for i in range(0, len(datos), 2):
# Extraer la base y cantidad
par = datos[i:i+2]
base = par[0]
cantidad = int(par[1])
# Expandimos la base multiplicando la cadena
base_expandida = base * cantidad
# La agregamos al resultado final
salida += base_expandida
return salida
def primeraBaseUnica(secuencia):
indice = 0
for base in secuencia:
# Si la primera ocurrencia de izquierda a derecha (index) es la misma que de derecha a izquierda, entonces
# esta base solo aparece una vez en la secuencia
if secuencia.index(base) == secuencia.rindex(base):
return indice
indice += 1
return -1
"""
Realizamos combinaciones de todas las subcadenas. Por ejemplo para AGAG serían las siguientes combinaciones:
A
AG
AGA
AGAG
En cada combinación que hacemos, vemos si al multiplicarla N veces se daría con la cadena completa. N es
las veces que esta subcadena cabe en toda la secuencia, redondeada al entero anterior más próximo.
Entonces tomando en cuenta cada combinación:
A, al multiplicarla 4 veces da AAAA, no nos da la cadena AGAG entonces lo descartamos
AG, al multiplicarla 2 veces da AGAG, SÍ nos da la cadena AGAG entonces regresamos True y ya no hacemos las siguientes
Otro ejemplo, para AGA:
Para A, multiplicamos por 3. Nos da AAA, no es AGA entonces descartamos
Para AG, multiplicamos por 1, nos da AG, no es AGA entonces descartamos
Para AGA, multiplicamos por 1 y SÍ nos da AGA pero NO lo tomamos en cuneta porque la combinación mide igual que la cadena completa
Llegamos al final de las comprobaciones y regresamos False
"""
def periodica(secuencia):
longitud_secuencia = len(secuencia)
for i in range(longitud_secuencia):
combinacion = secuencia[:i+1]
longitud_combinacion = len(combinacion)
cantidad_de_veces_que_cabe = longitud_secuencia // longitud_combinacion
# Ver si esta subcadena, al multiplicarla por las veces que cabe, es igual a la cadena completa
# Nota: también comprobamos si la subcadena no es exactamente igual a la cadena original
multiplicada = combinacion*cantidad_de_veces_que_cabe
if longitud_combinacion != longitud_secuencia and multiplicada == secuencia:
return True
return False
def solicitar_y_validar_secuencia():
while True:
secuencia = input("Ingrese la secuencia: ")
if len(secuencia) < 1:
print("La longitud de la secuencia debe ser mayor o igual a 1")
continue
for base in secuencia:
correcto = True
if base.upper() not in "ACTG":
correcto = False
if not correcto:
print("La secuencia solo puede estar conformada por A, C, T o G")
continue
# Si ninguno de los "continue" de arriba se cumplió, entonces estamos bien
# La regresamos en mayúscula porque todas las funciones suponen que estará en mayúscula
return secuencia.upper()
def menu(secuencia_fija, secuencia):
while True:
opcion = input("0. Salir del programa\n1. Transformar\n2. Comprobar si tiene start y stop\n3. Mostrar\n4. Resumir\n5. Duplicar\n6. Segmentos\n7. Expandir\n8. Primera base única\n9. Periódica\nElija: ")
if opcion == "0":
return
# Comprobamos si es necesario solicitar la secuencia
if not secuencia_fija and opcion != "7": # opción 7 no necesita secuencia
secuencia = solicitar_y_validar_secuencia()
if opcion == "1":
print(transformar_ADN_ARN(secuencia))
elif opcion == "2":
print(tieneStartStop(secuencia))
elif opcion == "3":
print(mostrar(secuencia))
elif opcion == "4":
print(resumir(secuencia))
elif opcion == "5":
print(duplicar(secuencia))
elif opcion == "6":
print(segmentos(secuencia))
elif opcion == "7":
datos = input("Ingrese los datos para expandir: ")
print(expandir(datos))
elif opcion == "8":
print(primeraBaseUnica(secuencia))
elif opcion == "9":
print(periodica(secuencia))
else:
print("Opción inválida")
def main():
respuesta_secuencia_fija = input(
"¿Desea trabajar con una secuencia fija? [s/n]: ")
secuencia = ""
secuencia_fija = False
if respuesta_secuencia_fija.lower() == "s":
secuencia = solicitar_y_validar_secuencia()
secuencia_fija = True
menu(secuencia_fija, secuencia)
main()
También puedes ver que, cumpliendo con los requisitos del ejercicio, se solicita la secuencia de ADN al inicio en caso de que el usuario quiera trabajar con ella en todos los puntos, y si no, se le solicita en cada punto.
El menú también está implementado. Yo ejecuté una prueba rápida y aparece lo siguiente:
Para terminar te dejo con más tutoriales y ejercicios resueltos de Python en mi blog.