Partage
  • Partager sur Facebook
  • Partager sur Twitter

Conditions

Bien les rédiger

    3 février 2011 à 22:36:43

    Bonjour à tous

    je suis professeur de maths en collège et j'anime un atelier d'initiation à la programmation à destination de mes élèves volontaires. J'ai bien entendu choisi Python pour cela. N'étant pas informaticien de métier ou de formation, je me heurte à quelques interrogations. En ce moment nous étudions les conditions, if, elif, else... ainsi que les opérateurs logiques ou et and.
    Pour les programmes que je leur ai demandés d'écrire il y avait toujours plusieurs manières de faire. L'exemple de SdZ sur les années bissextiles est assez éloquent dans ce sens. De même un simple and peut être remplacé par deux if imbriqués. Je me demandais simplement s'il existait une manière recommandée d'opérer, une sorte de convention...
    Dans le même genre d'idée, je rencontre souvent l'instruction while True suivie de la close d'arrêt dans un if. Ne devrait-elle pas suivre automatiquement le while ? Un if devrait-il être suivi d'un else ?

    En bref y a-t-il un algorithme pour être efficace dans la manière d'écrire ses conditions ? À défaut existe-t-il une sorte d'équivalent PEP 8 pour les conditions ? Ca ne me gêne pas de me fier à mon bon sens mais je crains réellement de louper quelque chose.


    Par avance merci de vos réponses.
    • Partager sur Facebook
    • Partager sur Twitter
      4 février 2011 à 0:43:46

      > En bref y a-t-il un algorithme pour être efficace dans la manière
      > d'écrire ses conditions ?

      Oui, c'est très simple :

      Tu fais lire le code à un autre. Si il trouve ça clair, c'est bon.

      L' "autre", ça peut être l'auteur du code, si il le relit 3 mois plus tard. On part du postulat que tu as tout oublié. Tu relis ton code, si tu ne comprends pas ce que le machin fait, il y a un problème.

      Ça pourrait être intéressant de faire un débat avec ta classe sur "quelle façon d'écrire ce machin est la plus lisible" ?

      > un simple and peut être remplacé par deux if imbriqués

      C'est assez subjectif, et ça dépend du contenu de code[1..4] ci-dessous, si certains sont vides on utilisera plutôt le and, sinon plutôt les if imbriqués.

      if a:
        code1
        if b:
          code2
        else:
          code3
      else:
        code4
      

      • Partager sur Facebook
      • Partager sur Twitter
        4 février 2011 à 0:44:34

        Salut !

        Personnellement, je me fie avant tout à mon bon sens comme tu dis en essayant de limiter les imbrications de if, else essentiellement pour des questions de lisibilité. ^^
        J'espère ne pas dire de bêtises mais je pense qu'il est possible de réduire n'importe quelle série de if/else imbriqués en plusieurs conditions distinctes en s'aidant de l'algèbre de Boole. En tant que prof de math tu devrais adorer ce lien même si cela ne répond pas vraiment à ta question... :p Je n'ai pas utilisé ça depuis longtemps mais j'en ai gardé le souvenir d'un outil vraiment puissant.

        En pratique donc il me semble plus simple d'imbriquer quelques if plutôt que de passer par l'équation logique. Lorsque c'est possible je regroupe plusieurs tests en une fois à l'aide des opérateurs logiques. Mais je ne connais pas d'algorithme pour rationaliser l'écriture des conditions... peut-être en cherchant du côté des machines d'états pour modéliser les conditions... mais c'est plus à voir dans le sens d'une aide à penser qu'une démarche fixe.

        Au sujet du while True, je pense que python ne prévoit simplement pas la syntaxe while if dont tu parles. On utilise donc True ou une variable initialisée à True et lorsqu'on atteint la condition de sortie du programme on passe la variable à False ou l'on fait un break pour sortir de la boucle.

        Un if ne doit pas nécessairement être suivit d'un else ou d'un elif.
        • Partager sur Facebook
        • Partager sur Twitter
          4 février 2011 à 0:46:31

          Note que while est assez rare en python. Si l'idée est de parcourir un truc qui ressemble à une liste, on utilisera toujours un for.
          • Partager sur Facebook
          • Partager sur Twitter
            4 février 2011 à 1:34:23

            Merci pour vos réponses, je retiens l'idée du débat. Ma déformation professionnelle m'incite à effectivement choisir la solution la plus élégante, selon des critères qui ne sont pas forcément définis. Je n'ai sans doute pas été très clair pour le while True, je proposerai un exemple plus concret sous peu.

            Concernant l'emploi des listes pour boucler, je compte remettre ça à plus tard avec mes élèves. À titre personnel j'ai aussi une préférence pour les listes, particulièrement en compréhension. Mais j'aime autant leur faire intégrer les principes de l'algorithmique plus que le langage en lui-même. Le while aura de plus sa place juste après les conditions.
            Un exercice sympa auquel je pensais pour introduire l'usage des listes (et le for) : jouer une partition à l'aide du module winsound (permet de jouer une note de fréquence et de durée données).

            Je vous dirai si ça a été réussi.
            • Partager sur Facebook
            • Partager sur Twitter
              5 février 2011 à 15:44:25

              Voici un exemple concernant le while auquel je pensais. Je souhaite créer un programme affichant tous les nombres positifs dont le carré doit être compris entre 1000 et 2000 et qui ne soient pas multiples de 3 (c'est purement pour s'exercer). Voici deux manières auxquelles je pensais, merci de me dire ce qui vous semble le mieux/plus lisible et éventuellement comment vous auriez fait, avec pourquoi pas les listes.

              # Méthode 1
              i = 0
              while True:
                  if i**2 > 1000:
                      break
                  if i%3 != 0:
                      print(i)
                  i += 1
              
              # Méthode 2
              i = 0
              while i**2 <= 1000:
                  if i%3 != 0:
                      print(i)
                  i += 1
              


              Là où je m'interroge en fait, c'est de trouver régulièrement le while True, y compris dans la documentation officielle. Dans cet exemple, la première version plus simple à mon goût, s'en passe. Y a-t-il selon vous des cas plus complexes où un while True s'impose ?
              • Partager sur Facebook
              • Partager sur Twitter
                5 février 2011 à 15:53:45

                Là, c'est clairement la 2è qui gagne, parce que ton While a une condition d'arrêt très claire (i**2 <= 1000) donc puisqu'elle existe, autant la mettre dans le while, c'est un peu l'idée du while d'ailleurs...

                Typiquement le while True, c'est là :

                while True:
                  p = flux.lire_paquet()
                  if p is None:
                    break
                  faire_un_truc( p )
                


                Là, p est connu seulement après qu'on l'ait lu. Donc on ne peut pas le mettre comme condition dans le while.
                En C/C++ tu aurais pu avoir :

                while(( p = flux.lire_paquet() ))
                {
                  faire_un_truc( p )
                }
                


                Mais en python, ça ne se fait pas.

                Par contre, si on fait vraiment du python, on va trouver que le while est laid, et faire :

                for p in flux.lire_paquets():
                  faire_un_truc( p )
                


                Et ton exemple devient :

                for n in xrange(0, int(math.ceil(math.sqrt(1000)))):
                   if n % 3:
                      print n
                
                • Partager sur Facebook
                • Partager sur Twitter
                  5 février 2011 à 16:07:56

                  Le while True: est aussi beaucoup utilisé pour faire l'équivalent d'un do{}... while() du C.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  yjltg.
                  Anonyme
                    5 février 2011 à 16:15:37

                    Citation

                    éventuellement comment vous auriez fait, avec pourquoi pas les listes



                    La difficulté pour toi cher collègue ;) serait de savoir si c'est une simple curiosité personnelle ou un rapport avec le niveau de tes élèves.

                    En ce qui me concerne je ferais cela comme cela, mais bon, des solution il y en a un paquet.

                    >>> [(n, n**2) for n in xrange(0, int(ceil(sqrt(2000))+1)) if n**2>=1000 and n**2<=2000 and n%3!=0]
                    


                    Il y a évidemment l'importation de la fonction ceil et sqrt du module math.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      5 février 2011 à 18:51:11

                      Citation : Flanders

                      j'anime un atelier d'initiation à la programmation à destination de mes élèves volontaires.



                      Je n'arrive pas à savoir s'il faut te répondre par rapport aux capacités et desiderata d'élèves de 4ème ou s'il faut répondre dans l'absolu.

                      Citation : Flanders

                      L'exemple de SdZ sur les années bissextiles est assez éloquent dans ce sens.



                      La question des années bissextiles n'est pas si simple (être multiple de 4 sauf multiple de 100 à moins qu'on ne soit multiple de 400).

                      Citation : Flanders

                      L'exemple de SdZ sur les années bissextiles est assez éloquent dans ce sens. De même un simple and peut être remplacé par deux if imbriqués. Je me demandais simplement s'il existait une manière recommandée d'opérer, une sorte de convention...




                      Je dirais que pour des élèves qui découvrent la programmation, cela ne pas vraiment d'importance même si à mon avis les opérations sur les booléens ne sont pas forcément faciles à comprendre. Dans l'absolu, je dirais qu'utiliser des booléens est préférable (on obtient une expression tandis que deux if imbriqués ne sont pas une expression).


                      Citation : Flanders


                      Dans le même genre d'idée, je rencontre souvent l'instruction while True suivie de la close d'arrêt dans un if. Ne devrait-elle pas suivre automatiquement le while ?





                      Pas compris la question. Par contre le while True ne me semble pas du tout prioritaire chez des collégiens à moins qu'ils ne soient très motivés.




                      Citation : Flanders


                      Un if devrait-il être suivi d'un else ?



                      Non.


                      Citation : Flanders


                      En bref y a-t-il un algorithme pour être efficace dans la manière d'écrire ses conditions ? À défaut existe-t-il une sorte d'équivalent PEP 8 pour les conditions ? Ca ne me gêne pas de me fier à mon bon sens mais je crains réellement de louper quelque chose.



                      La PEP ? Euh, à mon avis, tu te prends trop la tête ;)




                      Citation : Flanders

                      affichant tous les nombres positifs dont le carré doit être compris entre 1000 et 2000 et qui ne soient pas multiples de 3



                      Tes codes ne répondent pas exactement à la question posée. Pour des élèves de 4ème, je privilégierais une boucle for sans break :


                      >>> for i in range(2001):
                      ...     if 1000<= i*i <= 2000 and i%3!=0:
                      ...             print i
                      ... 
                      32
                      34
                      35
                      37
                      38
                      40
                      41
                      43
                      44
                      >>>
                      








                      Citation : fred1599


                      >>> [(n, n**2) for n in xrange(0, int(ceil(sqrt(2000))+1)) if n**2>=1000 and n**2<=2000]
                      



                      Il y a évidemment l'importation de la fonction ceil et sqrt du module math.



                      Ben, donc donner du code complet. Par ailleurs, pour être naturel et même pythonique, on écrit plutôt
                      1000 <= n**2 <= 2000
                      au lieu de
                      n**2>=1000 and n**2<=2000
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        5 février 2011 à 19:26:19

                        Citation

                        Ben, donc donner du code complet.



                        Désolé, j'avais modifié mon code 20 minutes avant que tu copies colles mon ancien code.

                        Beaucoup de réflexions pour pas grand chose, mais tout en ton honneur.

                        Ok pour la question pythonique
                        • Partager sur Facebook
                        • Partager sur Twitter
                          5 février 2011 à 20:54:05

                          Citation : Lord Casque Noir


                          Par contre, si on fait vraiment du python, on va trouver que le while est laid, et faire :




                          Je ne crois pas que le codeur Python raisonne ne fonction de critères esthétiques pour décider de choisir for au lieu de while, c'est la sémantique qui décide. Par exemple, si tu fais un code qui convertit d'une base en une autre, a priori, tu écris un while. De même si tu étudies la suite de Syracuse. Noter que la tournure while True est très très usuelle en Python (faire un tour dans le code source de Cpython par exemple) qui a souvent pour effet d'éviter la redondance de code.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            8 février 2011 à 23:43:57

                            Citation : candide


                            Je n'arrive pas à savoir s'il faut te répondre par rapport aux capacités et desiderata d'élèves de 4ème ou s'il faut répondre dans l'absolu.


                            Les deux en fait, je n'ai pas une formation solide en info et je voudrais être certain de ne pas enseigner trop d'âneries. Après j'aime bien aller au fond des choses, y compris pour des choses insignifiantes.

                            Citation : candide


                            Tes codes ne répondent pas exactement à la question posée.


                            J'ai modifié mon problème en cours de post et n'ai pas pensé à modifier les codes...

                            Citation : candide


                            Par ailleurs, pour être naturel et même pythonique, on écrit plutôt
                            1000 <= n**2 <= 2000


                            J'ignorais le coup de l'inégalité double, c'est sympa.


                            Merci à tous pour vos réponses détaillées. Je réalise que je ne maîtrise pas vraiment Python, notamment par méconnaissance des autres langages.
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Conditions

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown