Que j’ai ôté car je n’avais pas fait attention au fait que tu utilises une boucle while et non une boucle for
padrian
Effectivement, on obtient un code beaucoup plus élégant, voici ma correction :
compte le nombre total de bases et le nombre de chaque occurence
parametre : chaine a anlyser
valeur, retour : nombre total, nombre A, nombre C, nombre G, nombre T
def compte_bases(chaine):
nbA = nbC = nbG = nbT = TotalNb = 0
for base in chaine :
if base == “A”:
nbA +=1
elif base == “C”:
nbC +=1
elif base == “G”:
nbG +=1
elif base == “T”:
nbT +=1
TotalNb +=1
return(TotalNb, nbA, nbC, nbG, nbT)
SyntaxError: invalid syntax
il a surligné en rouge le while et le dièze
d’autre part si je comprends bien l’exercice consiste à écrire en python ce que le cours nous donne sous forme de algorythme car j’ai mis le code suivant dans idle et il ne fonctionne pas du tout , je n’obtiens que des erreurs
voici le code que vous connaissez :
nbA,nbC,nbG,nbT, TotalNb, index: integer, sequence: character, string [1:*]
nbA,nbC,nbG,nbT, TotalNb ? 0
index ? 1
repeat
case sequence [index] of
“A”: nbA ? nbA + 1
“C”: nbC ? nbC + 1
“G”: nbG ? nbG + 1
“T”: nbT ? nbT + 1
endcase
TotalNb ? TotalNb + 1
index ? index + 1
until sequence [index] = “#”
display “Longueur de la séquence :” TotalNb
display “%A=” (nbA/TotalNb)*100, “ %C=“, (nbC/TotalNb)*100, “ %G=”, (nbG/
TotalNb)*100, “ %nbT=”, (nbT/TotalNb)*100
pouvez vous me dire ce qu’il faut daire exactement et pourquoi mon dièze et mon while ne fonctionne pas ?
IsabellePoirier
Bonjour trx337,
Il s’agit effectivement ici de traduire l’algorithme écrit en pseudo-code dans le cours en programme Python.
IDLE s’attend à recevoir des instructions Python, et ne va pas comprendre le pseudo-code.
Je ne rencontre pas de problème avec ta fonction compte (en ajoutant les indentations qui ont disparu dans ton message).
Peut-être vérifier que tu utilises bien des guillemets droits (" et non “) ? Ou que tu n’avais pas oublié le deux-points final ? Ou encore que tu n’avais pas écrit While avec une majuscule ?
je vous tiens au courant plus tard si je réussis dans idle qui me parait plus simple .
merci et à bientôt
IsabellePoirier
Bonjour trx337,
Dans la cellule, il n’y a que la définition de la fonction, donc quand on l’exécute, rien ne se passe (du moins visiblement).
Pour tester que ta fonction fait bien ce qui est attendu d’elle, il faut ensuite exécuter la cellule de code suivante (celle avec le commentaire # évaluez cette cellule pour vérifier votre implémentation).
trx337
meci Isabelle ; ça commence à aller mieux mais j’ai des erreurs que je ne comprends pas ; d’une part j’ai vérifié while s’écrit avec une minuscule ; je ne comprends pas comment les guillemets se sont retrouvé en oblique et non en vertical ce qui faisait une erreur bête et incompréhensible . J’arrive maintenant à travailler dans le note book Pour finir je vous envoie mon code qui ne fonctionne pas ; je ne sais plus ce qu’il veut après un petit peu de travail . Je suis parti du code de Padrian mais plus tard j’essaierai de développer quelque chose de ma logique à moi . Je suis débutant en python et j’ai appris dernièrement scratch .Mais j’avais aussi fait un peu de langage c .
votre code
def compte(chaine):
nbAT = 0
nbGC = 0
TotalNb = 0
index = 0
while chaine[index] != “#”:
if chaine[index] == “A” or chaine[index] == “T”:
nbAT +=1
elif chaine[index] == “C” or chaine[index] == “G”:
nbGC +=1
TotalNb +=1
index +=1
result = “Longueur de la sequence : " + str(TotalNb)+ “\n” + “%AT : " + str((nbAT/TotalNb)*100)+”\n” + "%GC : " + str((nbGC/TotalNb)*100)
return result
NameError Traceback (most recent call last)
in
5 TotalNb = 0
6 index = 0
----> 7 while chaine[index] != “#”:
8 if chaine[index] == “A” or chaine[index] == “T”:
9 nbAT +=1
NameError: name ‘chaine’ is not defined
je ne comprends pas non plus pourquoi
nbAT = 0 (est en rouge)
nbGC = 0 ( et est en noir)
c’est bizarre , non ?
IsabellePoirier
Ne serait-ce pas un problème d’indentation ?
Toutes les instructions de la fonction (en dessous de la ligne def compte(chaine) doivent être décalées vers la droite du même niveau (et encore davantage pour les instructions de la boucle while).
C’est difficile à voir ici. Peut-être pourrais-tu coller une copie d’écran ?
padrian
Attention trx337, pour mon code python, j’utilise Eclipse + Pydev, il se peut qu’il y ait des particularités incompatibles avec l’éditeur/interpréteur du MOOC.
évidement mes lignes sont trop longues pour que l’on voit tout ; dernière question comment aller à la ligne sans faire d’erreur ?
IsabellePoirier
Il y a bien un souci d’indentation.
Le while doit être au même niveau que nbAT = 0.
Sinon, Python va considérer que cette instruction while est en dehors de la fonction, et à ce moment-là, il ne connaît pas la variable chaine qui est locale à la fonction.
Et, à l’intérieur du while, les instructions doivent être davantage indentées, et même chose à l’intérieur du if ou du elif.
IsabellePoirier
Tu peux aller à la ligne en inscrivant l’expression entre parenthèses, ou en utilisant un backslash avant ton retour à la ligne.
Par ailleurs, si tu veux pouvoir tester le fonctionnement de ta fonction dans le notebook, tu devrais conserver le nom proposé (count_gc_at) pour la fonction, sinon le test de la cellule suivante ne va pas fonctionner.
trx337
j’ai avancé d’un cran mais je ne comprends pas pourquoi nbGC est en noir , je ne comprends pas la fonction str (jamais vu) le back slash pour aller à la ligne je ne comprends pas est ce cela : \ ?
et pour ma ligne en print , il ne fait rien mais au moins je n’ai plus d’erreur
je n’ai plus qu’une erreur à la fin mais je ne vois pas ce qui se passe (str veut dire string mais quel est l’intéret de l’écrire ?)
IsabellePoirier
Je pense que le souci vient du " fermant de la chaîne de caractères lors de l’appel à la fonction. Il s’est à nouveau transformé en guillemets obliques.
La fonction str permet de transformer un objet en chaîne de caractères, ce qui permet de le concaténer à une autre chaîne par exemple. "Longueur de la séquence : " + TotalNb ne va pas fonctionner en Python 3 car on ne peut ajouter une chaîne de caractères et un nombre.
IsabellePoirier
L’erreur n’est en fait pas à la fin de ta fonction, mais dès l’appel à celle-ci.
Je pense que tu as encore des soucis d’indentation (d’où la coloration rouge de certaines instructions).
Vérifie bien que tu laisses exactement le même nombre d’espaces ou alors la même tabulation, mais ne mélange pas les deux.
zenjo
Bonjour,
il reste une erreur d’indentation ici:
while ...
if chaine ...
nbAT += 1
elif chaine ...
nbGC +=1
Aussi, le guillemet en fin d’appel de la fonction n’est pas correct (pas un guillement ")
Enfin, il serait nettement plus aisé de vous répondre si vous copiez/collez du code dans un paragraphe entouré au dessus et en dessous des 3 guillemets speciaux ``` qu’en postant des images qui ne permettent pas de vous signaler le code problématique sans devoir le recopier à la main.
Exemple, écrivez:
```
if test:
mon code
```
qui donnera ceci:
if test:
mon_code
beaucoup plus aisé pour une réponse, qu’une image.
Cordialement
Robert Sebille.
ThierryParmentelat
Pour compléter ce qui vient d’être dit,
le bouton
pour montrer du code et le conserver tel quel, vous pouvez aussi utiliser dans la barre de menu le bouton :
vous écrivez votre texte normalement, éventuellement par copier-coller, en faisant quand même attention à ce que le texte soit correct
vous sélectionnez la zone qui correspond à du code; ça marche aussi avec du texte qui n’est pas dans des lignes séparées; exemple, le terme fact est un symbole de code et mérite d’être présenté somme tel
vous cliquez le bouton - sur mac je peux aussi utiliser le raccourci clavier ⌘-⇧-C - il y en a aussi un sous windows bien sûr
les modifications sont faites directement dans le texte, vous pouvez voir comment c’est fait et ensuite avec l’habitude vous n’avez plus besoin du bouton.
pour info en markdown (ce que vous écrivez dans la partie gauche du panel est du markdown) il y a deux façons de mettre du texte ‘brut’
du code avec des quotes
cette façon permet de spécifier un langage, et du coup d’avoir des couleurs; le langage est optionnel
```python
def fact(n):
if n <= 1:
return 1
else:
return n * (n-1)
```
qui donne
def fact(n):
if n <= 1:
return 1
else:
return n * (n-1)
du code en décalant de 4 espaces vers la droite
et aussi en décalant simplement de 4 espaces vers la droite
def fact(n):
if n <= 1:
return 1
else:
return n * (n-1)
qui donne
def fact(n):
if n <= 1:
return 1
else:
return n * (n-1)
les entêtes de paragraphes
sachez enfin qu’en markdown, une ligne qui commence par un dièse signifie une entête de paragraphe
ainsi la ligne
# hello
donne
hello
c’est ce qui explique certains soucis; en utilisant la méthode ci-dessus, le souci disparait, on voit les commentaires aussi
pour publier un notebook
enfin je rappelle qu’on peut publier un snapshot des notebooks en faisant depuis le notebook ‘File -> Share Static Version’ ce qui est plus rapide que de copier-coller dans le forum, et donc peut dépanner aussi
trx337
# votre code
def count_gc_at(chaine):
nbAT = 0
nbGC = 0
au = 4
TotalNb = 0
index = 0
while chaine[index] != "#":
if chaine[index] == "A" or chaine[index] == "T":
nbAT +=1
elif chaine[index] == "C" or chaine[index] == "G":
nbGC +=1
TotalNb +=1
index +=1
result = "Longueur de la sequence : " + str(TotalNb)+ "\n" + "%AT : " + str((nbAT/TotalNb)*100)+"\n" + "%GC : " + str((nbGC/TotalNb)*100)
return result
print(count_gc_at("CCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAA#"))
j’ai mis mon texte de deux façons différentes . pour l’image on voit quand même la couleur qui change et dont je ne comprend pas le sens .
Donc je recommence mes difficultés
tout d’abord , on a l’impression que de temps en temps shift entrée ne fonctionne plus et ne dit plus rien . Dans ces moments là , une étoile se met à coté de entrée
2 je demande depuis hier pourquoi ma variable nbGC est en noir
aujourd’hui j’ai écrit au = 4 pour voir ce qui se passe et elle est en rouge . Donc là je ne comprends rien .
3 pour les guillemets , ils me paraissent bon après avoir à nouveau regardé .
4 pouvez vous expliquer les couleurs rouges , vert et noir ; ne serait pas un bon debut pour comprendre quelque chose .
5 et pour finir , pourquoi ne pas me donner le corrigé de ce que j’ai écrit car au niveau mathématique , là n’était pas la difficulté de résolution
zenjo
Bonjour
Pour vous donner un corrigé, il fallait que vous fassiez au moins ce que vous avez fait, c-à-d un copier/coller du code plutôt qu’un image (je ne vais quand même pas recopier à la main votre code, si?
Le guillemet final a été corrigé par rapport au dernier Traceback imagé qui donnait un guillemet oblique
Voici votre corrigé. Il n’y avait que des erreurs d’indentation.
Les blocs de code en python doivent s’indenter. Une indentation de 4 espaces est en général une bonne norme.
# votre code
def count_gc_at(chaine):
nbAT = 0
nbGC = 0
au = 4
TotalNb = 0
index = 0
while chaine[index] != "#":
if chaine[index] == "A" or chaine[index] == "T":
nbAT +=1
elif chaine[index] == "C" or chaine[index] == "G":
nbGC +=1
TotalNb +=1
index +=1
result = "Longueur de la sequence : " + str(TotalNb)+ "\n" + "%AT : " +\
str((nbAT/TotalNb)*100)+"\n" + "%GC : " + str((nbGC/TotalNb)*100)
return result
print(count_gc_at("CCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAA#"))
Bien cordialement,
Robert Sebille.
trx337
merci robert pour l’instant mon noté book ne marche pas ; il y a marqué bad gateaway
pour le code écrit , je n’ai compris que aujourd’hui comment on faisait , pour l’instant je suis archi débutant et je voudrais bien comprendre pourquoi nbGC est en noir et pourquoi il y a du rouge et du vert et pourquoi le bloc note est souvent bloqué et ne répond plus .
lorsque vous voyez une étoile apparaitre, c’est que votre bout de programme n’a pas fini de tourner; soit il est très long, soit vous avez fait une erreur de logique et il ne se terminera jamais (ça arrive plus facilement qu’on ne pense…)
dans ces cas là, il faut l’arrêter, on dit l’interrompre; pour ça vous avez un menu Kernel qui propose entre autres l’option Interrupt, ça devrait vous aider dans ce genre de situation
IsabellePoirier
Bonjour trx337,
Je pense que certaines lignes apparaissaient en rouge car l’indentation n’était pas correcte.
Vérifie que tu utilises bien à chaque ligne exactement la même indentation, et à ne pas utiliser espaces et tabulations à la fois.
ThierryParmentelat
dans les cas où vous recevez un message Bad gateway: cela signifie que la plateforme de notebooks a du mal, ça peut être lié à une charge excessive (de plus en plus de cours l’utilisent…);
dans ces cas l-a je vous recommande un peu de patience, le mieux est de recharger toute la page avec le navigateur; au bout de quelques secondes/dizaines de secondes en général ça revient
Comme le dit le final’s God message dans hhgg: we apologize for the inconvenience
trx337
rebonjour
aujourd’hui j’ai l’impression d’avoir avancé d’un cran mais je vous montre mon code à moi qui me semble être écrit comme senjo qui m’a donné le corrigé . un corrigé qui est la meme chose que moi mais senjo ça marche et moi il tourne en continu ( étoile) je viens de l’apprendre
d’autre part mon indentation , je le faisais avec touche espace or pour celui que je vous montre , je l’ai fais avec touche flèche tabulation . Je remarque qu’avec flèche tabulation , mon code reste noir . Donc je me dis que rien ne doit etre écrit en rouge . estce cela ?
voici mon code , il ne fonctionne pas :
# votre code moi
def count_gc_at(chaine):
nbAT = 0
nbGC = 0
TotalNb = 0
index = 0
while chaine[index] != "#":
if chaine[index] == "A" or chaine[index] == "T":
nbAT +=1
elif chaine[index] == "C" or chaine[index] == "G":
nbGC +=1
TotalNb +=1
index +=1
result = "Longueur de la sequence : " + str(TotalNb)+ "\n" + "%AT : " + str((nbAT/TotalNb)*100)+"\n" + "%GC : " + str((nbGC/TotalNb)*100)
return result
print(count_gc_at("CCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAA#"))
zenjo
Bonjour, le problème est ici:
index = 0
while chaine[index] != "#":
if chaine[index] == "A" or chaine[index] == "T":
nbAT +=1
elif chaine[index] == "C" or chaine[index] == "G":
nbGC +=1
TotalNb +=1
index +=1 # problème d'indentation
Avec son implementation dans le bloc elif chaine[index] == "C" or chaine[index] == "G":, index n’est plus mis à jour et reste bloqué à sa valeur, dans if chaine[index] == "A" or chaine[index] == "T":, dès qu’il rencontre un “A” ou un “T”. On entre alors dans une boucle infinie.
La séquence devrait être codée comme dans le code que je vous ai renvoyé:
index = 0
while chaine[index] != "#":
if chaine[index] == "A" or chaine[index] == "T":
nbAT +=1
elif chaine[index] == "C" or chaine[index] == "G":
nbGC +=1
TotalNb +=1
index +=1
Changement d’indentation pour TotalNb et index.
Bien cordialement
Robert Sebille.
trx337
exact ; maintenant cela marche ; fallait le voir ; merci ; je vais essayer de faire à ma façon
Au revoir tout le monde
zenjo
Attention à ceci: cette fois, même si elle semble s’exprimer ainsi, ça n’est plus une vraie faute d’indentation, mais bien une vraie faute de logique, à savoir:
un compteur de boucle placé dans le mauvais bloc de commande
Bien à vous.
trx337
dans le script de padrian , ainsi que sans le pseudo code , je note des choses:
tout d’abord il est demandé de dire que la variable est un entier;
ex
int entier = 17
d’autre part padrian ulilise elif ; il pourait utiliser else
3 en général case of existe en langage informatique ( et est différent de la boucle for)
4 si l’index doit être mis à 1 , la première case est le 0 en informatique ; donc si on regarde le pseudo code et celui de padrian , padrian met l’index à 0 et et le prof met l’index à 1 . Il doit y avoir un mot de vocabulaire qui ne va pas quelque part
zenjo
Le typage de python est dynamique, et donc les déclarations n’y sont pas requises. Par contre, il est important qu’un langage algorithimique simule un typage statique, afin que les algorithmes puissent être implémentés dans ce type de langage également (c++, par exemple).
Personnellement, j’ai tendance à penser que typage dynamique ou statique, c’est un bon exercice pour l’informaticien.
Pas du tout, si il veut respecter l’algorithme que vous exposez ci-dessus. En effet, ici, l’alogrithme comme le elif évite de comptabiliser une mauvaise lettre. Avec un else, toute lettre autre que A, T, C, G serait comptabilisée dans nbGC +=1. Ici, une lettre erronée n’est pas comptabilisée. Attention, c’est important de détecter ce typpe de logique!
De plus, si la contrainte est effectivement d’éviter les lettres erronées, il y a une erreur de logique dans l’algorithme, fidèlement reproduite dans le script python; je vous laisse découvrir laquelle.
Oui, mais cette structure n’existe pas en python. Ceci dit, il est (parfois avantageusement) remplaçable par d’autres structures du langage.
Effectivement, il y a une différence de conception à la base là-dessus. Les biologistes veulent compter de 1 à 10 (sur leur 10 doigts? ;-), là ou un informaticien compte (mathématiquement plus correct, d’ailleurs) de 0 à 9. C’est ainsi, et il nous faut nous y adapter, semble-t-il.
Cordialement.
trx337
merci zenjo ; je retiens que case of ne fonctionne pas dans python;
suite
j’ai mis le script de zenjo dans idle et il ne fonctionne pas (et il fonctionait dans note book )
merci si quelqu’un comprend quelque chose , car moi j’y pige que pouic
Dans la console interactive de IDLE, tu ne peux saisir qu’instruction par instruction.
Or ici, tu définis la fonction et tu l’appelles.
Essaie de ne saisir d’abord que la définition, et seulement après l’instruction print qui appelle la fonction.
Si tu veux pouvoir copier le code entier directement, il faut le faire dans un fichier (menu file New file), l’enregistrer puis appuyer sur F5 (ou Run module du menu Run).
trx337
justement pour run si vous regardez bien ma photo ; il n’apparait pas . Je ne sais pas ou il se cache
IsabellePoirier
Oui, car là, tu es dans la console interactive qui exécute les instructions les unes après les autres (donc pas besoin de menu Run pour elle).
Ouvre un nouveau fichier dans lequel tu copies le code, et là, tu auras le menu Run.
trx337
merci je suis débutant dans idle
IsabellePoirier
Avec plaisir.
Si tu veux en savoir plus sur Python, il y a cet excellent MOOC sur cette même plateforme.
trx337
merci j’ai regardé mais je ne sais pas si j’aurais le temps de suivre deux moocs à la fois car celui ci avec de la génétique m’intéresse beaucoup et il semble qu’il y est beaucoup de travail . J’avais déjà suivi le mooc langage c avec Rémy Shamrock . Pour idle , ça y est ça fonctionne
zenjo
Bonne nouvelle, si vous avez fait du C, vous ne devriez pas rencontrer trop de problème en programmation!
Ceci dit, il y a des différences entre C et python, qui peuvent être déroutantes au premier abord. Voici une page présentant “some differences between C and Python”
Cordialement et bonne continuation du mooc,
Robert Sebille.
trx337
pour le mooc en c , il y avait deux sessions , une débutant et une avancé et j’ai fait les deux et j’ai eu le certificat ; sinon j’ai fait un mooc sur html5 avec du javascript qui lui était carton . Je connais aussi html , css et un peu php . et dernièrement j’ai fait seul scratch et j’ai un livre ou ils expliquent scratch en rapport avec python . Ceci dit , j’ai l’impression qu’à la fin de cette première semaine , ça se complique avec tous ces dictionnaires et ces dessins ; Je me demande donc si en cinquième semaine , le niveau en python ne va pas être du genre polytechnique supérieur !!! je ne connais pas le mot tupple ; on est là pour apprendre non ?
zenjo
Bonjour,
non, je ne crois pas; le mooc est plutôt orienté algorithmique et logique (ce qui, de mon avis, est beaucoup plus correct pour de l’informatique que des maths d’ingenieurs). Et vous avez aussi l’air de bien vous débrouiller, non?
Dans cette cheat sheet, laissez tomber les parties Pygame et Django qui ne nous concerne pas, mais cherchez donc les tuples? Il y sont bien et brièvement décrits. Je vous ajoute tout de suite quelque chose à propos des tuples, qui n’est pas expliqué parce qu’implicite, mais qui pourra vous servir: lorsque dans une fonction vous faite un return x y par exemple, eh bien vous retournez en fait un tuple. Je vous dis cela, car en python, un tuple est une structure particulière présente en beaucoup d’endroit, parfois implicitement. En gros elle se comporte à peu près comme une liste, MAIS c’est un immuable (une structure de donnée immuable est une structure de données qu’on ne peut plus changer une fois qu’elle a été créée; comme par exemple les chaines de caractères, les entiers, etc.)
J’ajouterais, ne restez pas trop longtemps bloqué sur un problème. Bien sur, cherchez d’abord par vous même et sur internet, mais si ça coince de partout, bon ben utilisez le forum. Et tout doucement, je crois, un nouveau sujet!
Bien cordialement, et bon courage,
Robert.
trx337
merci pour votre réponse
trx337
A tous :
regardez voir ça :
adrienollier
Bonjour tout le monde.
Je vois que vous cherchez tous la fin de la chaîne avec le caractère ‘#’ comme dans les vidéos, sauf qu’on voit bien dans les exemples que les chaînes de texte ne se terminent pas par ‘#’, donc on peut considérablement simplifier le code.
Je vous propose ma solution, merci de me dire ce que vous en pensez :
def count_gc_at(dna):
nbGC = 0
nbAT = 0
total = 0
for nucleotide in dna:
if nucleotide in 'GC':
nbGC += 1
else:
nbAT += 1
total += 1
return (nbGC/total, nbAT/total)
trx337
je ne suis pas très fort mais ta boucle for n’est pas satisfaisante:
nucléotide et dna ne sont pas défini (gc non plus ) et une boucle for s’écrit avec le terme (in range)
soit tu écrit en python , soit tu écris en pseudo code ; ceci est mon humble avis de débutant
IsabellePoirier
Bonjour trx337,
Le code d’Adrien est correct . dna n’a pas à être définie à l’intérieur de la fonction, car il s’agit du paramètre de la fonction.
Quant à ‘GC’, cela définit une chaîne de caractères composée des caractères G et C. Il ne s’agit pas d’une variable. nucleotide est quant à elle définie par l’instruction for nucleotide in dna. for n’est pas automatiquement associée à un appel à range. C’est le cas lorsque tu veux itérer sur des nombres, comme sur les indices d’une séquence par exemple, mais Python permet d’itérer directement sur les éléments de la séquence, grâce à cette syntaxe.
Ici, nucleotide est une variable qui va prendre successivement comme valeur les différents caractères qui composent la chaîne dna.
Je t’invite à tester cette fonction dans Python tutor, tu pourras voir ce qui se passe instruction par instruction.
adrienollier
Bonjour,
j’ai remarqué qu’on peut accélérer le calcul en faisant l’optimisation du calcul du total à la fin du parcours de la chaîne de caractères au lieu de le faire à chaque tour de boucle :
def count_gc_at(dna):
nbGC = 0
nbAT = 0
for nucleotide in dna:
if nucleotide in 'GC':
nbGC += 1
else:
nbAT += 1
total = nbGC + nbAT
return (nbGC/total, nbAT/total)
IsabellePoirier
Bien vu !
ThierryParmentelat
Bonjour à tous
Pour rebondir sur un certain nombre de commentaires, je voudrais (re)dire qu’en effet le parti pris éditorial ici est d’utiliser Python de la manière la plus basique possible; l’objectif est de donner au plus grand nombre un moyen de faire fonctionner les algorithmes décrits dans le cours.
Je me suis donc astreint à utiliser les traits de Python les plus élémentaires; ce qui donne un code qui a uniquement une vertu pédagogique, mais très différent en effet de ce qu’on écrirait dans la pratique.
Si vous cherchez à améliorer votre Python, je vous recommande de suivre par ailleurs cet autre MOOC: Python 3 : des fondamentaux aux concepts avancés du langage, toujours sur FUN, co-écrit par votre serviteur , dont je crois d’ailleurs me souvenir qu’adrienollier - que je salue au passage - l’a suivi dans une session précédente.
trx337
merci Isabelle
effectivement dna est dans en paramètre de la fonction et je l’avais appris (quand je faisais entre autre du c )
pour nucleotide , je pensais que ça ne pouvait être qu’un compteur en chiffre , mais là c’est apparemment chaque lettre ou chiffre d 'une chaine ce que je ne savais pas et vu qu’il est dans for , il n’y a pas besoin de l’initialiser .
et après , il dit (in’ GC’)
if nucleotide in ‘GC’:ça veut dire , si nucleotide est un G ou un C
effectivement , ça va plus vite d’écrire ceci que ce que l’on avait écrit .
Merci encore à tout le monde ; je comprends bien
trx337
je voudrais préciser quelque chose selon mon caractère maniaque :
j’ai mis le script d’Adrien dans mon idle et il fonctionne .
Mais il a quand même oublié (multiplié par 100 pour avoir le pourcentage .
Maintenant moi j’ai écrit ceci pour avoir le résultat :
blou = input('écrit ta phrase : ’ )
print(count_gc_at(blou))
si on écrit : “AATTCCGG#”
cela fonctionne
si on écrit : AATTCCGG#
cela fonctionne aussi
sauf que il calcul différemment (soit il compte le dièze en plus , soit il compte les guillemets
ThierryParmentelat
si on veut faire un code qui ignore les caractères exotiques, on peut par exemple écrire ceci:
def count_gc_at(dna):
nbGC = 0
nbAT = 0
total = 0
for nucleotide in dna:
if nucleotide in 'GC':
nbGC += 1
total += 1
elif nucleotide in 'AT':
nbAT += 1
total += 1
return (nbGC/total, nbAT/total) * 100
mais bon, notre but ici est de vous donner les clés pour justement adapter les algorithmes à vos besoins; dans les cas où on sait par ailleurs que la chaine n’a pas de caractère exotique, il est possible d’être - un peu - plus efficace.
n’oubliez pas que, très clairement, si l’efficacité devient un élément décisif, on écrira plutôt du C ou du C++, quitte à wrapper ça dans une fine couche de Python
trx337
dans idle , il me dit souvent invalid syntax à cause de ceci :
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
Type “help”, “copyright”, “credits” or “license()” for more information.
le 7 de Python 3.7.2 est en rouge
si vous comprenez quelque chose ?
trx337
effectivement dans le script de adrien ollier , il ne s’occupe pas du dièze
quant à wrapper , c’est pour moi du chinois
je n’ai pas fait de c++ et je ne sais pas ce qu’il a de différent de c
ceci dit , python ne me semble pas beaucoup différent de c si on en reste à un niveau débutant ; Peut etre que dans c , on ne peux pas dessiner ; (j’en sais rien)
par contre avec scratch justement on peut dessiner et je vais essayer ; je vous montrerais le résultat si j’y arrive .
A bientôt
adrienollier
Bonjour @trx337,
je n’ai volontairement pas multiplié par 100 le résultat car en fait ce n’est pas un pourcentage qui est attendu (contrairement à ce qui est écrit dans la consigne).
Et en effet je ne m’occupe pas du ‘#’ puisqu’il n’y en a pas dans le jeu de test proposé.
Dans la page, on voit clairement que les résultats attendus ne sont pas des pourcentages mais des valeurs comprises entre 0 et 1.
Et dans les chaînes de texte proposées, il n’y a rien d’autre que les 4 lettres ‘A’, ‘C’, ‘G’ et ‘T’.
adrienollier
Comme je l’ai dit, je considère que dans dna il n’y a que les quatre lettres ‘A’, ‘C’, ‘G’ et ‘T’ (pas de dièse donc) et c’est bien ce qui est proposé en exercice.
Donc c’est sûr que si tu mets un ‘#’ à la fin le compte n’est pas bon puisqu’il sera compté avec les ‘AT’ au lieu d’être ignoré.
trx337
merci pour votre réponse
mon but est de bien comprendre ce que chacun fait pour mieux comprendre comment programmer en python
Tajou
Bonjour,
Je suis perdue dans la plateforme et en fait, je ne sais pas où trouver python? est ce que je dois le télécharger pour faire les exercices?
Merci d’avance pour votre aide,
Tajou
trx337
tu peux travailler dans le note book sur la plateforme , il est fait pour cela
sinon en dehors du mooc , le logiciel pour python à télécharger se nomme IDLE
Tajou
Merci beaucoup pour ton aide
adrienollier
Bonjour @Tajou,
Vous n’avez pas à “trouver Python” mais à écrire du code en Python dans les zones de texte éditable, puis l’exécuter en appuyant sur Shift + Entrée ou Cell > Run Cells.
Bien sûr il faut savoir un minimum coder en Python.
Si vous n’avez aucune connaissance en Python, vous pouvez suivre le MOOC Python sur FUN.
Tajou
Merci pour votre réponse et pour le lien. C’est tout nouveau pour moi, je patauge un peu…
adrienollier
Pour suivre le présent cours et faire les exercices en Python, il n’y a pas besoin d’avoir un niveau extraordinaire en Python.
Je vous conseille de lire le cours des deux premières semaines, ce sera largement suffisant pour ce qu’on a à faire ici.
Bien sûr vous pouvez aller aussi loin que vous le voulez dans le cours sur Python.
N’hésitez pas à poser des questions sur les forums, il y a plein de gens qui pourront vous répondre.
Bon courage.
Tajou
Merci encore pour toutes ces clarifications, j’en avais besoin.
Bon courage à vous aussi
trx337
j’ai remarqué ceci :
if base in "A":
if base == "A":
ne serait ce pas la même chose ?
IsabellePoirier
Bonjour trx337,
Dans ce cas, cela revient effectivement au même. if base in "A" va regarder si base est une sous-chaîne de la chaîne “A”. Comme cette dernière n’est composée que d’un seul caractère, cela revient à tester si base est égal à ce caractère.
Dans cette situation, j’aurais tendance à utiliser la deuxième syntaxe, mais je ne sais pas si l’une est plus “efficace” que l’autre.
zenjo
D’après un p’tit calcul vite fait, il n’y a pratiquement pas de différence
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fileencoding=utf-8
import time
B = base = "A"
for k in range(5):
start_1 = time.time()
for i in range(10000):
if base == "A":
B = base
print(str(k), "base == 'A' =", str(time.time() - start_1))
start_2 = time.time()
for i in range(10000):
if base in "A":
B = base
print(str(k), "base in 'A' =", str(time.time() - start_2))
print("-"*10)
Résultat:
0 base == 'A' = 0.0015289783477783203
0 base in 'A' = 0.0015742778778076172
----------
1 base == 'A' = 0.0015146732330322266
1 base in 'A' = 0.0015330314636230469
----------
2 base == 'A' = 0.0015056133270263672
2 base in 'A' = 0.001554250717163086
----------
3 base == 'A' = 0.0015053749084472656
3 base in 'A' = 0.0015418529510498047
----------
4 base == 'A' = 0.0015146732330322266
4 base in 'A' = 0.0015430450439453125
----------
bien à vous tous,
Robert Sebille
trx337
merci à Isabelle et à Robert ; la réponse de robert , c’est balaize
en fait hier je voulais transcrire du python en scratch à savoir ceci :
for nucleotide in dna:
ou bien
for base in chaine :
eh bien j’ai l’impression que ce n’est pas possible
python semble plus simple que scratch dans ce cas précis
l’instruction dans scratch es t"répéter"
mais elle se confond avec while
et pourquoi pas
while base in chaine
ou
while nucleotide in dna:
je voulais aussi vous dire ceci
j’ai fait un mooc en bash avec l’université de la réunion ; c’était très bien
et j’avais bien réussi
mais aujourd’hui , je ne me rappelle plus de rien
mais en regardant la formule
from turtle import *
on remarque que l’étoile est surement dérivée du langage bash
(étoile) représente je crois l’ensemble bref le tout
pour cette formule
import turtle
turtle.forward(100)
si on écrit ensuite
turtle.right(25)
faut il réécrire import turtle .
bref la différence des deux formules n’est pas clair
IsabellePoirier
Dans Scratch, tu as deux instructions de boucle, la boucle “répéter n fois” qui peut s’apparenter à une boucle for i in range(n) en Python, et la boucle “répéter jusqu’à ce que” que l’on peut détourner pour correspondre à une boucle while en Python.
Mais il n’y a en effet pas possible d’itérer directement sur les caractères d’une chaîne de caractères, ou les items d’une liste, comme en Python. Il faut utiliser leurs indices.
Si tu importes le module turtle au début de ton script, tu as alors accès à toutes les fonctions définies dans ce module, et il n’est donc pas besoin d’une deuxième instructionimport turtle.
zenjo
Bonjour trx337, c’est une manière de faire habituelle pour tester quelle fonction sera la plus efficiente de 2. On répète plusieurs fois de nombreuses fois 2 fonctions pour avoir une idée moyenne de leur rapidité. Je vous ai mis le code pour que vous puissiez voir comment ça fonctionne.
Actuellement, les développeurs utiliseront plutot le module timeit, mais c’est une question d’habitude.
Cordialement,
Robert Sebille.
ThierryParmentelat
pour info je vous signale également un magic ipython - donc dispo dans une cellule notebook par exemple:
pour toute une cellule
%%timeit
# avec deux % on va mesurer le code de toute la cellule
bla
bla
ou ligne par ligne
# avec un seul % on va mesurer le code de la ligne
%timeit base in 'A'
trx337
SeqLength, L, I, InitW, nbA,nbC,nbG,nbT, NbStepsRight, NbStepsUp: integer
XEndSegment, YEndSegment, Step: real
sequence: character string [1:*]
InitW¬ 1
repeat
nbA,nbC,nbG,nbT ¬ 0
for I from InitW to InitW + L - 1 do
case sequence [I] of
“A”: nbA ¬ nbA + 1
“C”: nbC ¬ nbC + 1
“G”: nbG ¬ nbG + 1
“T”: nbT ¬ nbT + 1
endcase
endfor
NbStepsRight ¬ nbC – NbG
NbStepsUp ¬ nbA – nbT
XEndSegment ¬NbStepsRights * Step
YEndSegment ¬ NbStepsUp * Step
DrawTill (XEndSegment, YEndSegment)
InitW ¬ InitW + L
until InitW > SeqLength
pour le code ci dessus qui est l’exercice no 3
j’ai l’impression qu’il n’est pas di difficile puisque le point de départ et le point d’arrivée sont ceci :
NbStepsRight ¬ nbC – NbG
NbStepsUp ¬ nbA – nbT
ce qui est bizarre c’est que personne ne donne de code donc personne ne l’a écrit en python
je pose une question sérieuse : est ce que je dois essayer avec ma brave petite turtle ?
IsabellePoirier
Bonjour trx337,
Je ne sais pas s’il est aisé d’utiliser le module turtle dans les notebooks. Cela expliquerait peut-être pourquoi le code Python n’a pas été fourni.
Mais bien sûr que tu peux écrire le code correspondant.
ThierryParmentelat
En effet, le module turtle pose des problèmes particuliers par rapport à une utilisation dans les notebooks, c’est pourquoi je me suis abstenu de l’utiliser dans ce contexte.
trx337
bonjour tout le monde
moi ce qui me pose problème c’est le code avec pylot etc qui me parait difficile
par contre dans idle , la tortue mange son herbe correctement
Je vais essayer
puisque le mooc est ouvert pendant un an , vous serez toujours là dans 9 mois pour nous répondre ?
def count_gc_at(dna):
nbA=dna.count("A")
nbC=dna.count("C")
nbG=dna.count("G")
nbT=dna.count("T")
l=len(dna)
dna=str()
for index in range (0,l+1):
return (((nbA+nbT)/l),((nbC+nbT)/l))
print (((nbA+nbT)/l),((nbC+nbT)/l))
pouvez vous me dire ce qui ne va pas ? (je débute en python).
cordialement
ThierryParmentelat
je me permets d’éditer votre message pour la mise en forme
je vois bien quelques défauts:
le gros bug est ici: return (((nbA+nbT)/l),((nbC+nbT)/l)) ................^.............^ deux fois T !
dna = str() ne sert à rien
vous faites un for mais comme vous faites immédiatement un return la boucle ne sert pas non plus
enfin vous ne passez jamais par le print parce que vous avez fait return avant
je vous laisse rectifier
Myenj
Oui ! Merci,
votre code
def count_gc_at(dna):
nbA=dna.count("A")
nbC=dna.count("C")
nbG=dna.count("G")
nbT=dna.count("T")
l=len(dna)
for index in range (0,l+1):
ratioAT = (nbA+nbT)/l
ratioCG = (nbC+nbG)/l
return (ratioCG,ratioAT)
maintenant, ça fonctionne beaucoup mieux !
adrienollier
Je propose plus haut dans ce forum une première solution, puis une deuxième qui est la première solution mais améliorée.
Il faut connaître un minimum le langage Python pour comprendre l’algorithme.
adrienollier
Bonjour,
effectivement ce code fonctionne mais il est très inefficace parce que vous faites le calcul de ratioAT et ratioCG l fois alors qu’une seule fois suffit. De plus, en appelant quatre fois la fonction count() pour compter le nombre de chaque caractère, vous parcourez implicitement la chaîne de caractères quatre fois, alors qu’une seule fois suffirait à compter toutes les lettres.
Déjà en enlevant la boucle for, votre code devient :
Si vous voulez utiliser la boucle for, alors il ne faut plus utiliser la fonction count().
Je vous laisse réfléchir à comment faire cela, et si vous le voulez je peux vous donner ma solution.
Cordialement,
Adrien Ollier
Myenj
Ma mère me disait toujours de réfléchir avant d’agir, OK.
Donc l’ADN possède 4 lettres différentes, et on peut compter les A et T, par exemple.Alors le nombre de CG sera la longueur totale moins le nombre de A et de T. Il doit donc suffire de compter AT et la longueur pour avoir les deux ratios …
ce qui donnerait :
je ne sais pas si c’est le minimum, on peut peut être compter en même temps A et T ?
est ce que je me rapproche de la solution ? Cordialement.
adrienollier
C’est déjà mieux, l’idée est bonne mais on peut faire encore mieux.
Vous utilisez deux fois la fonction count(), donc deux parcours de la chaîne sont faits.
Pour ne faire qu’un seul parcours et compter à la fois les ‘A’ et les ‘T’, vous devez abandonner la fonction count et compter vous-même dans une boucle for. Là vous aurez la solution optimale.
Bon courage !
Myenj
Re Bonjour,
et comme ça ?
def count_gc_at(dna):
nbAT=0
l=len(dna)
nbCG = l-nbAT
for nucleotide in dna:
if nucleotide in 'GC':
nbAT+=1
return ((nbAT/l),(1-(nbAT/l)))
Merci pour tous vos conseils, est ce que je me rapproche d’une solution acceptable ?
adrienollier
Si nucléotide vaut G ou C, c’est nbGC qu’il faut incrémenter, pas nbAT.
Mis à part cette erreur, cette solution est tout à fait acceptable et efficace !
Myenj
oui ! (à part le copier-coller) … faut toujours bien se relire (que je dis d’habitude) …
merci !!
anfe67
Bonjour. Je sais que une bonne partie de l’algorithme est de parcourir le brin d’ADN, mais dans ce cas particulier Python nous donne des instruments pour faire le chose beaucoup plus rapidement. En particulier la methode “count” de string. Voici ma solution:
def count_gc_at(dna):
# J’utilise la methode count de chaines de characteres
strLen = len(dna)
nbGC = dna.count(“C”) + dna.count(“G”)
nbAT = dna.count(“A”) + dna.count(“T”)
return (nbGC/strLen, nbAT/strLen)
adrienollier
Bonjour @anfe67,
votre proposition permet d’écrire moins de code (donc c’est plus rapide à écrire), mais à l’exécution c’est beaucoup plus lent.
En effet, à chaque fois que vous appelez la méthode count() pour compter le nombre d’occurrences d’une lettre, vous parcourez toute la chaîne de texte.
En appelant count() 4 fois, vous parcourez implicitement la chaîne 4 fois, alors qu’une seule suffit.
Donc bien que votre code fonctionne, il est inefficace. Vous pourriez le constater en comparant les algorithmes sur de très longues chaînes de texte.
J’espère vous avoir convaincu.
Adrien
anfe67
Bonjour Adrien,
Merci pour la réponse. Mais je ne suis pas convaincu, car les classes de python sont écrits en C si on utilise l’implémentation normale (CPython). J’ai écrit trois variations, et j’ai utilisé une chaine (brin d’ADN) qu’est un multiple (je ne sais plus combine de fois) de celle d’exemple. Dans ce cas, la proportion de GC et AT ne devrait pas changer. De ces trois versions, la plus rapide est celle qui utilise l’itération du “count” et puis celle de “char in string”.
Les voilà, j’en ai fait un screen-shot parce que le format est plus lisible e parce seul les images sont authorisees.
Puis, j’ai mesuré le temps d’exécution :
Ce que j’ai noté c’est qu’en ligne de commande la méthode “count” est plus rapide (en général), et qu’en Jupyter Notebook le parcours avec le “char in string” est plus rapide (j’ai essayé une dizaine de fois). Comment vous l’expliquez?
adrienollier
Je pense qu’utiliser le module datetime n’est pas l’idéal pour mesurer de si petites durées de temps. Voyez plutôt du côté du module timeit.
anfe67
Je viens de le faire, et j’ai répété les mesures dans les deux environnements. Cette fois (avec timeit, boucles de 10000 exécutions), les résultats sont plus clairs (à mon avis) :
Image 1: Code utilisant timeit :
Image 2: Résultats python ligne de commande:
Image 3: Résultats en Jupyter
Ma conclusion personnelle est que le “count” est en C, et il est optimisé. Pour les comptages simples comme ceux de L’exercice ça pourrait faire bien l’affaire, car il est aux moins un ordre de 25 fois plus rapide que parcourir la chaine (je l’utilise 4 fois, c’est encore mieux que ça).
adrienollier
Eh bien d’accord. Je suis très étonné de ce résultat. J’avoue ne pas avoir essayé de mon côté.
Ceci dit, si c’est l’implémentation CPython qui est utilisée, alors tout est compilé en C, y compris la version qui parcourt la chaîne de texte. Donc je ne vois pas bien pourquoi l’exécution est plus rapide avec la méthode count().
ThierryParmentelat
je vous signale également la classe Counter
from collections import Counter
qui pourrait vous éviter de reparcourir la séquence n fois
sinon pour ce qui concerne vos mesures, en règle générale lorsque deux algorithmes sont dans le même ordre de grandeur, c’est-à-dire formellement si le rapport entre leur temps d’exécution est borné, on considère que c’est blanc bonnet et bonnet blanc; ici dans les deux cas vous êtes en O(n), si l’un des deux est 4 ou 6 fois plus rapide que l’autre, ça ne fait pas tant de différence que ça.
c’est surtout lorsqu’un étudiant utilise par exemple une méthode en O(n**2) - souvent sans en avoir conscience à cause de l’utilisation de fonctions de la lib. standard -, alors que le problème est linéaire, qu’il est important de relever le cas
anfe67
J’ai un peu mal à la tête mais je crois avoir trouvé (grace à stackoverflow): La réponse devrait être dans le byte-code intermédiaire que python génère avant l’exécution. On sait générer le byte-code (que normalement nous ne voyons pas du tout). Nous les générons comme ça : d’abord il faut importer dis (pour disassemble). Le premier est le byte-code des appels “count”. Le deuxième celui du “parcourir”.
La performance est perdue au niveau du byte-code (interprété). En effet, tout ce qui est “count” se fait dans un seul appel de système (donc les boucles sont en “C” à bas niveau). Ici je le fais 4 fois. Tout ce qui est “boucle” python est fait aux niveaux du byte-code et pour l’implémenter il y a des sauts à l’interieur du byte-code même (et comparaisons et incrémentations d’index etc).
anfe67
Merci j’essaierais ça aussi. Pour ce qui concerne l’ordre de complexité nous sommes toujours dans O(n) mais la différence ne sera pas de 4* ou 6* mais plutôt de 100* (dans mes tests nous sommes + ou - à 30 *).
ThierryParmentelat
ah oui quand même, 30* ça commence à compter, et 100* encore plus… !
merci en tous cas de partager ce genre de périgrinations