Programmation en python

Retrouver tous les sujets résolus.
Répondre
Terminale S+3

Programmation en python

Message par Terminale S+3 » jeu. 2 févr. 2023 22:40

Bonjour,

Je travaille sur un projet en Python, et je suis coincé à une étape du projet. Je ne sais pas comment m'y prendre (au niveau du raisonnement), ce n'est pas l'aspect codage qui me pose problème. Je vais vous expliquer sur quoi je travaille :

Une séquence d'ADN est composé de 4 nucléotides : A, C, G, et T. Une enzyme de restriction peut couper un fragment d'ADN à une position spécifique lorsqu'il reconnait un motif particulier.

Par exemple, l'enzyme EcoRI reconnait le motif "GAATTC" et coupe en +1. On obtient alors "G" et "AATTC". L'endroit de coupure s'appelle le site de restriction. Ainsi, si mon fragment d'ADN est AAAAAGAATTCAA, la coupure par l'enzyme de restriction donnera deux fragments "AAAAAG" et "AATTCAA".

Jusqu'à maintenant, j'ai codé plusieurs fonctions, en suivant l'énoncé, dont les suivantes :
Une fonction qui prend en argument deux séquences de même taille, et qui retourne le nombre de différences entre ces deux séquences.
J'utilise cette fonction dans une deuxième fonction, qui s'appelle toutes_positions, qui me renvoie la liste de toutes les positions où un motif apparait dans une séquence.

Ma fonction troisième fonction fragment_lineaire utilise la fonction toutes_positions. Fragment_linéaire prend en argument une séquence, un motif, et la position de coupure. La fonction cherche dans la séquence le motif précis, et coupe à la position indiquée. Elle me retourne la liste des longueurs de chaque fragment, après coupure de l'enzyme de restriction.
C'est cela, l'enjeu : avoir la longueur de chaque fragment.

Voici comment fragment_lineaire fonctionne. Il utilise toutes_positions pour trouver liste des positions où se trouve le motif. J'additionne à chaque élément de cette liste la position de coupure, et j'ajoute la position 0 en début de liste.
Ensuite, je procède par soustraction pour avoir la longueur de chaque fragment.
J'obtiens ainsi la liste des longueurs de chaque fragment.

Voici où je bloque.
Le cas précédent suppose que le fragment d'ADN est linéaire.
Cependant, certains ADN peuvent être circulaire. Je souhaite créer une nouvelle fonction, fragment_circulaire. Comment faire ? L'une des difficultés, c'est que le site de restriction peut être "caché" par la représentation arbitrairement linéaire des fragments circulaires. Par exemple, ma séquence circulaire est CAGCAG, le motif est AGC, et je coupe en +1.
Il y aura bien un site de restriction, entre l'avant dernier et le dernier nucléotide. Il faudrait donc que ma fonction puisse "recoller" le début et la fin pour regarder s'il y a un motif.

Je me rends compte que c'est un peu long, je m'arrête ici. N'hésitez pas s'il vous faut un éclaircissement.
Merci de votre temps
SoS-Math(25)
Messages : 1859
Enregistré le : mer. 2 nov. 2011 09:39

Re: Programmation en python

Message par SoS-Math(25) » sam. 4 févr. 2023 13:53

Bonjour,

Peut-être peux-tu essayer de coller deux fois de suite la séquence circulaire au début de la fonction : "CAGCAG" -> "CAGCAGCAGCAG"
Ensuite, rechercher toutes les positions de motifs ou de coupures et si l'index de la position de coupure est plus grand que la longueur de la séquence d'entrée alors on ignore ou supprime ces positions ?

Bon courage
Terminale S+3

Re: Programmation en python

Message par Terminale S+3 » sam. 4 févr. 2023 23:53

Merci SOS 25 d'avoir pris le temps de me lire !

Merci de votre suggestion.
Je crains que cette méthode ne soit pas optimale, puisque nous analyserons des séquences pouvant aller jusqu'à des centaines (au moins) de nucléotides. Donc, coller deux fois de suite la séquence peut etre trop gourmand en terme de mémoire.

J'aurais pensé à concaténer en début de la séquence, une séquence de la longueur du motif. Ainsi, nous "recollons" le fragment, et regardons s'il y a un site de restriction.
Pour cela, je ferai seq= seq + seq[:len(motif)]. Je concatène une copie de la séquence seq avec un sous-fragment de la longueur du motif motif situé à l'extrémité gauche de la séquence seq.

Qu'en pensez vous ? Je ne sais pas si cela marchera bien...
SoS-Math(25)
Messages : 1859
Enregistré le : mer. 2 nov. 2011 09:39

Re: Programmation en python

Message par SoS-Math(25) » dim. 5 févr. 2023 12:40

Bonjour,

En effet c'est mieux si la séquence est très longue et si le nombre de motifs à rechercher est raisonnable, à tester donc. Il faudra faire attention à l'index de la coupure qui pourrait être à la fin de la séquence ou au début. Dans ce dernier cas, il faudra recalculer l'index.

Bon courage
Terminale S+3

Re: Programmation en python

Message par Terminale S+3 » dim. 5 févr. 2023 13:11

Bonjour,
Il faudra faire attention à l'index de la coupure qui pourrait être à la fin de la séquence ou au début. Dans ce dernier cas, il faudra recalculer l'index
Je n'ai pas bien compris cela. Qu'est ce que vous appelez l'index ? Comment le recalculer ?
Mais oui, en effet, le motif est assez petit, en général 6 nucléotides, parfois plus, mais jamais très long.

Bon week end !
SoS-Math(25)
Messages : 1859
Enregistré le : mer. 2 nov. 2011 09:39

Re: Programmation en python

Message par SoS-Math(25) » dim. 5 févr. 2023 13:23

Ajouter len(motif) - 1 à la fin de la séquence circulaire doit suffire je pense.


Je reprends et modifie légèrement ton exemple pour expliquer :

Si la séquence circulaire est CAGCAG, le motif est AGC, et je coupe en +3 :

CAGCAG -> CAGCAGCA

Index (positions) de coupures : [4, 7]

Mais 7 est en dehors de la séquence initiale qui ne contient que 6 éléments. Il faudrait donc avoir :

Index (positions) de coupures : [1, 4] ? (Recalculer les positions de coupures qui seraient en dehors de la séquence initiale)

Mais je n'ai peut-être pas tout saisi dans ce problème notamment, quels segments devrait-on obtenir ici après les coupures ?

A bientôt
Terminale S+3

Re: Programmation en python

Message par Terminale S+3 » lun. 6 févr. 2023 21:44

Ajouter len(motif) - 1 à la fin de la séquence circulaire doit suffire je pense.
Ca me semble etre une bonne idée !
J'ai pensé aussi à ajouter len(motif) -1. Il faut que j'ailles tester.
Je reprends et modifie légèrement ton exemple pour expliquer :
Si la séquence circulaire est CAGCAG, le motif est AGC, et je coupe en +3 :
CAGCAG -> CAGCAGCA
Index (positions) de coupures : [4, 7]
Mais 7 est en dehors de la séquence initiale qui ne contient que 6 éléments. Il faudrait donc avoir :
Index (positions) de coupures : [1, 4] ? (Recalculer les positions de coupures qui seraient en dehors de la séquence initiale)
Mais je n'ai peut-être pas tout saisi dans ce problème notamment, quels segments devrait-on obtenir ici après les coupures ?
Vous avez très bien compris la problématique !
La fonction doit cependant m'envoyer la longueur des fragments, mais pour cela, elle se base sur la position (l'index) de coupure.

Nous devrions obtenir, dans votre exemple (CAGCAG) le fragment suivant : C AGC AG (le dernier G étant collé au premier C, puisque la séquence est circulaire) .

Que suggérez vous pour palier à ce problème d'indice ?
J'ai l'impression, dans votre exemple, qu'il suffise de prendre les positions de coupure dans notre séquence modifiée, et de faire -3.
En effet, les positions de coupure de notre séquence modifiée est [4, 7] et celles de la séquence d'origine est [1, 4].

Donc, je pense procéder de cette façon : Ajouter len(motif) - 1 à la fin de la séquence circulaire originale.
Obtenir la liste des positions de coupure. Et vérifier s'il y a une coupure "cachée" (à cause de la représentation linéaire arbitraire d'une séquence circulaire).
Si oui : calculer les longueurs de chaque fragment, en faisant attention aux problèmes d'index comme expliqué ci dessus
Si non : si non, calculer les longueurs de chaque fragment, et retirant len(motif) -1 à la longueur du dernier fragment trouvé.

Qu'en pensez vous ?
Merci de votre attention !
SoS-Math(25)
Messages : 1859
Enregistré le : mer. 2 nov. 2011 09:39

Re: Programmation en python

Message par SoS-Math(25) » mar. 7 févr. 2023 13:35

Bonjour,

Pour passer de 7 à 1, je pensais à calculer un modulo : 7 % len(seq) -> 1 et 4% len(seq) -> 4. Cela permet de retomber dans la longueur de la séquence initiale.
Terminale S+3 a écrit :
lun. 6 févr. 2023 21:44
Nous devrions obtenir, dans votre exemple (CAGCAG) le fragment suivant : C AGC AG (le dernier G étant collé au premier C, puisque la séquence est circulaire) .

Que suggérez vous pour palier à ce problème d'indice ?
C'est cela que je ne comprends pas bien. Que deviennent les fragments découpés ? Ne faudrait pas faire "tourner" la séquence circulaire (repasser certains éléments du début à la fin) pour obtenir les fragments : AGC AGC ? -> positions de coupures [3, 6] après avoir placer le premier C à la fin ? Mais peut-être que la liste des longueurs de fragments possède une indication binaire (circulaire ou non)...

Bon courage
TerminleS+3

Re: Programmation en python

Message par TerminleS+3 » mar. 7 févr. 2023 14:18

Bonjour,
C'est cela que je ne comprends pas bien. Que deviennent les fragments découpés ? Ne faudrait pas faire "tourner" la séquence circulaire (repasser certains éléments du début à la fin) pour obtenir les fragments : AGC AGC ? ->
Si si ! Vous avez raison, je nai pas ete clair dans mon explication

Je nai pas du tout compris comment vous procedez avec le modulo...
Le modulo, vous designez bien la division entière entre deux nombres ? Pourquoi divisions nous ici ?

Merci de votre accompagnement
SoS-Math(25)
Messages : 1859
Enregistré le : mer. 2 nov. 2011 09:39

Re: Programmation en python

Message par SoS-Math(25) » mar. 7 févr. 2023 14:26

Il s'agit du reste de la division euclidienne :

7%6 = 1
4%6 = 4

Ici, comme la position ne peut être plus grande que 2 fois la longueur de la séquence initiale, cela revient à :

if pos >= len(seq) : pos -= len(seq)

Reste le cas de la position 0 ou len(seq) mais pour une séquence circulaire, c'est pareil je pense.
Terminale S+3

Re: Programmation en python

Message par Terminale S+3 » mar. 7 févr. 2023 23:07

SoS-Math(25) a écrit :
mar. 7 févr. 2023 14:26
Il s'agit du reste de la division euclidienne :

7%6 = 1
4%6 = 4
Je vois que cela marche (du moins avec cet exemple), mais je ne comprends pas du tout pourquoi nous faisons cela...
if pos >= len(seq) : pos -= len(seq)
N'y a t'il pas une erreur, en rouge ? Je n'ai pas bien compris ce que vous vouliez faire !
SoS-Math(25)
Messages : 1859
Enregistré le : mer. 2 nov. 2011 09:39

Re: Programmation en python

Message par SoS-Math(25) » mer. 8 févr. 2023 13:52

Bonjour,

Les positions ne doivent-elles pas être comprises entre 0 et len(seq)-1 ou entre 1 et len(seq) ?

Si la position est plus grande que la longueur de la séquence initiale alors il faut retrancher len(seq) à pos :

pos = pos - len(seq) (c'est la même chose que pos -= len(seq)).

Ainsi, si pos = 7 et que len(seq) = 6, on enlève 6 à 7 pour obtenir 1.

Cette méthode utilise un test sur chaque position (si pos > len(seq)...).

Ce serait plus performant, à mon avis, d'utiliser un modulo qui fait la même chose. Ainsi pas besoin de ce test :

pos = pos % len(seq)

1 = 7 % 6
4 = 4 % 6

A bientôt
TerminaleS+3

Re: Programmation en python

Message par TerminaleS+3 » ven. 10 févr. 2023 12:37

Bonjour,

Il me semble avoir bien compris la démarche.

Il me reste une question : lorsque nous utilisons le modulo %, toutes les positions sont affectées
pos = pos % len(seq)

1 = 7 % 6
4 = 4 % 6
Avec un test pos = pos - len(seq), seules les positions plus grande que la longueur de la séquence initiales sont traitées.

Est ce que j'ai mal compris quelque chose ? Ou il y a une différence entre ces deux méthodes ? Je pense faire des tests avec une séquence légèrement plus longue, je vous tiens au courant !

Merci de votre aide !
SoS-Math(25)
Messages : 1859
Enregistré le : mer. 2 nov. 2011 09:39

Re: Programmation en python

Message par SoS-Math(25) » ven. 10 févr. 2023 21:39

Bonsoir,

Avec le test il y aura donc un test sur chaque position puis, éventuellement un calcul de nouvelle position.

Avec un modulo, chaque position est re-calculée.

Les deux méthodes peuvent fonctionner.

Bon courage
TerminaleS+3

Re: Programmation en python

Message par TerminaleS+3 » ven. 17 févr. 2023 12:08

Merci, je vais essayer de coder tout ça, je vous tiens au courant !
A bientôt !
Répondre