IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Comment boucler ?


Sujet :

Shell et commandes GNU

  1. #1
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut Comment boucler ?
    Bonjour à tous,
    Je débute et apprend seul, j'ai donc quelques difficultés...
    Pour le code posté ci-dessous je n'arrive pas à boucler afin d'arriver à 1.
    Pourriez-vous m'éclairer ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    #!bin/sh
     
    # Programme qui, tant qu'un nombre est différent de 1, le divise
    # par 2  s'il est pair et le multiplie par 3 et lui ajoute 1 s'il
    # est impair.
     
    case $# in
        0) echo "Fournissez un nombre s'il vous plait :"
        read nombre
        nombre2=$[ nombre % 2 ]
        while [ $nombre > 1 ]
            do
         	   if [ $nombre2 = 0 ]
                	then
                            nombre3=$[ nombre / 2 ]
                            echo "$nombre est pair, j'obtiens donc $nombre3"
                    else
                       	nombre3=$[ (nombre * 3) + 1 ]
                            echo "$nombre est impair, j'obtiens donc $nombre3"
               fi
    	done;;
      1)  nombre4=$[ $1 % 2 ]
       while [ $1 > 1 ]
           do
              if [ $nombre4  = 0 ]
                    then
                            nombre4=$[ $1 / 2 ]
                            echo "$1 est pair, j'obtiens donc $nombre4"
                    else
                            nombre4=$[ ($1 * 3) + 1 ]
                            echo "$1 est impair, j'obtiens donc $nombre4"
              fi
            done;;
       *) echo "TROP DE PARAMETRES !"
    esac
    D'avance, merci.

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 138
    Par défaut
    A la lecture de ton script, je ne comprends pas bien ce qu'il est censé faire...

    Ce que je te propose, c'est de commenter chaque ligne du programme en indiquant ce qu'elle fait.
    Ensuite tu ne conserves que les commentaires et tu les relis (à haute voix) pour savoir si le programme que tu as écrit fait bien ce que tu voudrais qu'il fasse.

    Pour écrire un programme, la technique est d'ailleurs la même : décrire le fonctionnement en langage clair (pseudo-code) et associer ensuite chaque phrase de la description à son équivalent dans le langage de programmation.
    C'est un moyen sûr d'arriver au bout de ce que l'on cherche à programmer, de pouvoir se relire quand on reprend le programme pour le faire évoluer ... et de garder de bonnes relations avec ses collègues quand ils doivent travailler sur ton code
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Ce script devrait donner ceci en console :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $ script2 10
    10 est pair, j'obtiens donc 5 
    5 est impair, j'obtiens donc 16
    16 est pair, j'obtiens donc 8
    8 est pair, j'obtiens donc 4
    4 est pair, j'obtiens donc 2
    2 est pair, j'obtiens donc 1
    Je suis parvenu à 1...
    $ script 2 
    Fournissez un nombre s'il vous plait : 13
    13 est impair...
    Donc je souhaite faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    Si aucun argument
    Demander nombre
    Le lire
    Enregistrer le reste de la division par deux dans nombre2
    Tant que nombre est > à 1
    	faire
    		Si cette variable vaut 0
    			alors
    				nombre3 vaut nombre divisé / 2
    				on affiche un message
    # c'est là que je ne perçois pas comment passer au calcul suivant, 
    # resultat pair ou impair
    			sinon
    				nombre4 vaut nombre * 3 + 1
    				on affiche un message
    Le reste voulant procéder de la même logique mais avec un nombre en argument.

    Le scrip boucle de manière infini au niveau du commentaire.

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 138
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    Si aucun argument
    Demander nombre
    Le lire
    Tant que nombre est > à 1
        faire
            # A faire dans la boucle
            Enregistrer le reste de la division par deux dans nombre2
            Si cette variable vaut 0
                alors
                    nombre3 vaut nombre divisé / 2
                    on affiche un message
                sinon
                    nombre4 vaut nombre * 3 + 1
                    on affiche un message
           finsi
    # c'est là qu'il manque quelque chose
        lire le nombre suivant # avant de boucler
    Fin tant que
    N'oublie pas non plus les fin de structure (finsi, fin tant que, ...) dans ton pseudo-code. C'est aussi important
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  5. #5
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Je prend bonne note de ces conseils...

    Cependant, après beaucoup de lecture (trop ?) de tutos, faq et autres, je suis toujours bloqué. Je n'arrive pas à visualiser comment finaliser.
    J'ai du faire fausse route mais je ne vois pas où.
    Montrez-moi la voir SVP

  6. #6
    LLB
    LLB est déconnecté
    Membre émérite
    Inscrit en
    Mars 2002
    Messages
    968
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 968
    Par défaut
    C'est un problème de logique. Quand je lis ton algo, en français, ça me semble normal qu'il y ait une boucle infinie. nombre n'est jamais modifié.

  7. #7
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Oui, c'est bien la que je séche, je ne vois pas comment procéder

  8. #8
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 138
    Par défaut
    Je t'ai pourtant donné la réponse....
    Citation Envoyé par al1_24 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Si aucun argument
    Demander nombre
    Le lire
    Tant que nombre est > à 1
        faire
            # A faire dans la boucle
            Enregistrer le reste de la division par deux dans nombre2
            Si cette variable vaut 0
                alors
                    nombre3 vaut nombre divisé / 2
                    on affiche un message
                sinon
                    nombre4 vaut nombre * 3 + 1
                    on affiche un message
           finsi
    # c'est là qu'il manque quelque chose
        lire le nombre suivant # avant de boucler
    Fin tant que
    
    N'oublie pas non plus les fin de structure (finsi, fin tant que, ...) dans ton pseudo-code. C'est aussi important
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  9. #9
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Oopss... je n'avais rien lu prenant les deux premières lignes pour mon propre post.
    Je regarde bien sur et reviendrais

  10. #10
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Super, là bien sur... ça fonctionne.
    Je poste le code corrigé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    #!bin/sh
     
    # Programme qui, tant qu'un nombre est différent de 1, le divise
    # par 2 s'il est pair et le multiplie par 3 et lui ajoute 1 s'il
    # est impair.
     
    case $# in
        0) echo "Fournissez un nombre s'il vous plait :"
           read nombre
           while [ $nombre != 1 ]
             do
             nombre2=$[ nombre % 2 ]
               if [ $nombre2 = 0 ]
                    then
                            nombre3=$[ nombre / 2 ]
                            echo "$nombre est pair, j'obtiens donc $nombre3"
                    else
                            nombre3=$[ (nombre * 3) + 1 ]
                            echo "$nombre est impair, j'obtiens donc $nombre3"
               fi
             nombre=$nombre3
             done;;
         1) nombre4=$1
            while [ $nombre4 != 1 ]
              do
              nombre5=$[ nombre4 % 2 ]
                if [ $nombre5  = 0 ]
                    then
                            nombre6=$[ nombre4 / 2 ]
                            echo "$nombre4 est pair, j'obtiens donc $nombre6"
                    else
                            nombre6=$[ (nombre4 * 3) + 1 ]
                            echo "$nombre4 est impair, j'obtiens donc $nombre6"
                fi
              nombre4=$nombre6
              done;;
         *) echo "TROP DE PARAMETRES !"
    esac
    Merci pour votre aide.

  11. #11
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Une dernière question :
    Ce code peut-il être optimisé (plus court, avec moins de variable, plus rapide...)
    Merci.

  12. #12
    LLB
    LLB est déconnecté
    Membre émérite
    Inscrit en
    Mars 2002
    Messages
    968
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 968
    Par défaut
    Oui.

    Dans la première partie, tu peux te passer de nombre2 et nombre3.

    Ensuite, tu peux factoriser le code, puisque la boucle while est identique (la duplication de code est quelque chose à éviter absolument). Essaie de mettre le while après le case. Le case sert alors juste d'initialisation.

  13. #13
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut Presuqe bon
    Ce script s'améliore, en voici la dernière version :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    case $# in
            0) read -p "Fournissez un nombre s'il vous plait : " nombre
            ;;
            1) nombre=$1
            ;;
            *) echo "TROP DE PARAMETRES !"
            ;;
    esac
            while [ $nombre != 1 ]
                do
                    nombre2=$(( nombre % 2 ))
                    if [ $nombre2 -eq 0 ]; then
                            nombre3=$(( nombre / 2 ))
                            echo "$nombre est pair, j'obtiens donc $nombre3"
                    else
                            nombre3=$(( (nombre * 3) + 1 ))
                            echo "$nombre est impair, j'obtiens donc $nombre3"
                    fi
                    nombre=$nombre3
                done
    J'ai, par contre, un message d'erreur que je ne parviens pas à solutionner lorsque je rentre deux d'arguments. Le script fonctionne mais j'en veux pas.
    Le voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    TROP DE PARAMETRES !
    [: 25: 1: unexpected operator
    Si 25 est le numéro de ligne cela correspond à la dernière soit le "done" ?
    Savez-vous d'où cela provient ?
    Merci.

  14. #14
    LLB
    LLB est déconnecté
    Membre émérite
    Inscrit en
    Mars 2002
    Messages
    968
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 968
    Par défaut
    Oui.

    Quand il y a trop de paramètres, tu veux quitter (exit).

    Comme tu n'as pas mis exit, nombre n'est pas défini quand il y a plusieurs paramètres. Mettre $nom_inexistant est la même chose que ne rien mettre. Ta ligne avec le while est donc identique à :
    La commande [ renvoie alors une erreur.


    P.S. : il y a aussi une erreur si l'argument donné n'est pas un nombre entier.

    P.S.2 : != sert pour la comparaison de chaines. Utilise -ne pour comparer des entiers (man [).

  15. #15
    Membre confirmé Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Par défaut
    Merci LLB.
    La lecture ne remplacera jamais certaines explications...
    Quelques lignes et tout s'éclaire.
    C'est exactement le genre de choses expliquées nulle part, dans aucun tuto (cas du case avec exit) :
    Pourtant quelques exemples du genre : "ne faites pas ceci" ou "attention à cela" aideraient les débutants auxquels ils sont destinés. Mais bon je suis hors sujet là
    Merci encore.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 10/02/2008, 21h13
  2. Réponses: 2
    Dernier message: 24/12/2007, 10h53
  3. [XSLT] Comment boucler ?
    Par stofeben dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 15/05/2007, 11h39
  4. [XSLT] comment boucler ?
    Par bilb0t dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 11/10/2006, 12h37
  5. [VB6] Comment boucler sur des controls d'un form ?
    Par lankviller dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 27/01/2003, 17h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo