Suite récurrente d'ordre 2 (programme python)

Bonjour à tous,
Je ne suis plus toute jeune et je dois programmer en Python.
Mon exercice est le suivant : "Écrire un programme qui calcule et affiche les termes de (Un) jusqu'à obtenir un terme supérieur à 1000."
U0=2
U1=1
Un=5Un-1-2Un-2
J'ai pensé à :
Si n=0 afficher "U=2"
Si n=1 afficher "U=1"
(a,b)=(2,1)
Pour n allant de 2 à N
(a,b)=(b,5b-2a)
Tant que b<1000
afficher b

Mais tout ça en Python, n'ayant jamais programmé ; j'ai beau regarder plein de tutos, je n'y arrive pas
Merci de m'aider !

Réponses

  • @ Odile, bonjour et bienvenue.

    Programmer en python ne te rendra pas ta jeunesse !

    amicalement,

    e.v.
    Personne n'a raison contre un enfant qui pleure.


  • Bonjour,

    La traduction en Python est assez littérale, cependant ton brouillon en pseudo-code est partiellement incorrect puisqu'on ne connaît justement pas N (ni n) à l'avance ! Proposition :
    (a, b) = (2, 1) 
    while b < 1000:
        (a, b) = (b, 5*b-2*a)
        print(b)
    
  • Ça n'est pas mal parti mais je vois deux problèmes de conception :
    • qui est N ?
      en fait, que veux-tu ? un truc qui calcule les N premiers termes pour un N à préciser après ou un truc qui calcule les 1000 premiers termes ? Il va de soi que la première option est plus intéressante : il faut alors définir une fonction de N ;
    • « tant que b<1000: afficher b » : ça, c'est incompréhensible ; en effet,
      • soit on fait une boucle "pour" du genre "pour b allant de 0 à 1000", auquel cas b va prendre toutes les valeurs de 0 à 1000 et le résultat va être 0, 1, 2, 3,..., 1000 ;
      • soit on comprend vraiment ça comme une boucle "tant que" et alors, comme b ne change pas de valeur dans la boucle, de deux choses l'une : soit b<1000 au moment où on voit la clause "tant que", alors on va afficher la valeur courante de b jusqu'à la mort des rats ; soit b>999 au moment où on voit la clause "tant que", alors on n'entre pas dans la boucle.
      De toute façon, ce que tu veux, c'est afficher b au moment où tu le calcules, non ? Comme tu ne le stockes nulle part (à chaque fois que tu écris "a,b = ...", la valeur de b est oubliée et remplacée par 5b–2a), c'est ta seule chance d'avoir tout le monde.
    Deux erreurs de présentations :
    • tes blocs d'instructions ne sont pas clairement délimités : qu'est-ce qui rentre dans la boucle "pour n..." ? juste la ligne en dessous ou les trois en dessous ? Avec la plupart des langages, on délimiterait le bloc d'instructions à exécuter pour chaque valeur de n entre accolades { ... } ; avec Python, ça se fait en incrémentant plus que le bloc dont ça dépend ; l'incrémentation fait partie de la syntaxe, qu'elle rend plus claire et plus légère ;
    • en pseudo-code, un algorithme doit comporter trois ingrédients : les variables d'entrée (ici, y en a-t-il une, N ou pas ?) ; la nature de ce qui est renvoyé (et pas seulement affiché : si on veut pouvoir l'utiliser, il faut que ça se termine par "renvoyer" ou "return") ; enfin, le corps de l'algorithme ; ici, on n'a que le corps et donc, les variables sont incompréhensibles.
    Bref, voilà comment ça pourrait commencer...
    # la fonction qui calcule
    def u(N):
        if N==0:
            return 2
        elif N==1:
            return 1
        else:
            a, b = 2, 1
            for n in range(2,N+1):
                a, b = b, 5*b-2*a
            return b
    
    # calcul de u(10)
    print('u(%s) = %s') % (10, u(10))
    
    # calcul et affichage des 10 premiers termes
    print([u(k) for k in range(11)])
    
    Ça ne renverra peut-être pas le bon résultat mais ça renverra quelque chose.
  • Autre possibilité :
    #--- PrintSuite   ------------------------------------------------
    #---                                                             -
    #---               Imprime les  termes d'une suite               -
    #---  Utilise print_liste pour choisir le nombre                 -
    #---        d'éléments par ligne et le séparateur                -
    #-----------------------------------------------------------------
    
    def print_liste (l , n=0 , s=" , ") : #-- n : nb d'éléments par ligne
                                          #-- s : séparateur    
      if n<1 : n=len(l)
      i=0
      v=[]
      while i < len(l) :
        v.append((liste[ i]))
        if (i+1) % n == 0 :
          print (*v,sep=s)
          v=[]
        i=i+1
      if len(v) > 0 : print (*v,sep=s)
    
    liste = []
    liste.append (2)  #---  U0
    liste.append (1)  #---  U1
    i = 1
    while (liste [ i] < 1000) :
      liste.append (5 * liste[ i] - 2 * liste[i-1])  #---  Un
      i = i+1
    
    print_liste (liste)
    print ()
    print_liste (liste , 3 , " | ")
    print ()
    print_liste (liste , 10 , " : ")
    

    [Mettre une ' ' entre [ et i sinon, l'afficheur du forum le prend pour une bannière BBcode de mise en italique. AD]
  • Quelques remarques sur votre code :

    Si n=0 afficher "U=2" n n'est pas initialisé . On ne peut pas tester sa valeur
    Si n=1 afficher "U=1" "
    (a,b)=(2,1)
    Pour n allant de 2 à N N pas initialisé
    (a,b)=(b,5b-2a)
    Tant que b<1000 boucle infinie car b ne change plus de valeur dans cette boucle
    afficher b
  • Comme le nombre d'éléments à afficher est très réduit (contrairement à ce que je pensais) on peut se dispenser de la fonction qui affiche sur un nombre de colonnes donné .
    #--- PrintSuite   ----------------------------------------
    #---                                                     -
    #---  Imprime les  termes de la suite                    -
    #---                Un = 5 U(n-1) - 2 U(n-2)             -
    #---      avec  U0 = 2   et   U1 = 1                     -
    #---------------------------------------------------------
    
    liste = []        #---  liste vide
    liste.append (2)  #---  U0
    liste.append (1)  #---  U1
    
    i = 1  #--- indice pour parcourir la liste
    
    while (liste [i ] < 1000) :
      liste.append (5 * liste[ i] - 2 * liste[i-1])  #---  Un
      i = i+1
    
    print(liste)
    

    [Mettre une ' ' entre [ et i sinon, l'afficheur du forum le prend pour une bannière BBcode de mise en italique. AD]
  • Comme principe, ce n'est pas une bonne idée de se passer de la fonction. Quand on programme quelque chose, on devrait faire en sorte que ce bout de code soit réutilisable, même si en pratique on ne le fait pas toujours ni même souvent.

    Pourquoi stocker ces données inutiles dans une liste si c'est seulement pour les afficher ? Il vaudrait mieux les afficher au fur et à mesure sans les garder en mémoire.
  • Bonjour Math Coss

    on m'a appris à séparer systématiquement tout ce qui relevait de l'affichage des résultats de ce qui relevait du traitement des données . Mais peut-être que dans un si petit programme ça n'a aucun intérêt .

    Cordialement
Connectez-vous ou Inscrivez-vous pour répondre.