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

Caml Discussion :

affichage incompréhensible d'un arbre


Sujet :

Caml

  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Points : 376
    Points
    376
    Par défaut affichage incompréhensible d'un arbre
    Bonsoir, je ne comprends pas quelque chose, et j'espère que vous pourrez m'aiguillez sur la source du problème

    Je travaille sur ce type de donnée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    type 'a arbre=
     |Feuille of 'a
     |Noeud of ('a arbre * 'a * 'a arbre);;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    (*Renvoit le premier élément d'un couple*)
    let nom = fun p ->
    	match p with
    	|(a,_) -> a;;
     
    (*Renvoit le second élément d'un couple*)
    let pouvoir = fun p ->
    	match p with
    	|(_,b) -> b;;
     
    (*Concatène les infos d'une personne*)
    let personnetoString = fun p ->
    	(nom p)^"["^(pouvoir p)^"]";;
    Jusque là rien de sorcier

    voici un exemple avec une racine seule

    let p1=Feuille("a","E");;

    Ici, E correspond à eau en réalité, donc à l'affichage je voudrais retrouver eau et non E.

    Du coup, j'ai fais une autre fonction intermédiaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    (*récupère la représentation d'un couple pour l'affichage*)
    let abbreToRepre = fun c ->
    	match c with
    	|(n,p) -> match p with
    				|"E" -> (n,"eau")
    				|"F" -> (n,"feu")
    				|"T" -> (n,"terre")
    				|"A" -> (n,"air")
    				|"X" -> (n,"rien")
    				| _ -> failwith "Type inconnu";;
    Par ailleurs, étant donné que mes arbre sont construit sous la forme de feuille, j'ai une autre fonction qui va récupérer le couple d'une feuille

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    (*Récupère le couple d'information correspondant à une feuille*)
    let feuilleToCouple = fun f ->
    	match f with 
    	|Feuille(a,b) -> (a,b)
    	|Noeud(a,i,b) -> failwith "Traite seulement les feuilles";;

    Le coeur du problème est ici

    Voilà la fonction que j'utilise pour afficher un de mes arbres sous la forme que je veux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    (*Retourne la chaine correspondante à un arbre*)
    let rec concatArbre = fun a ->
    	match a with
    	|Feuille(n,p) -> personnetoString(abbreToRepre(feuilleToCouple a))
    	|Noeud(b,i,c) -> personnetoString (abbreToRepre i) ^"("^ concatArbre b ^ ","  ^ concatArbre c^")";;

    Donc,si je fais

    concatArbre p1;;

    je m'attends à obtenir a[eau] sauf que, dans mon cas j'obtiens a[E]
    Ce qui me parait encore plus absurde, c'est que, si je regarde le résultat de personnetoString(abbreToRepre(feuilleToCouple p1)) j'obtiens pourtant bien a[eau].

    Bref, je suis peut être trop dedans ce qui fait que je ne trouve pas la source du problème et je viens donc demander un coup de main =)

  2. #2
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Points : 376
    Points
    376
    Par défaut
    Re,

    petit message pour signaler que le problème est résolu.

    En fait, j'ai modifié concatArbre après avoir écrit printArbre.

    Du coup, printArbre fonctionnait avec l'ancienne version de concatArbre. Une erreur de débutant...désolé !

  3. #3
    Membre du Club
    Homme Profil pro
    Chercheur en maths appli
    Inscrit en
    Novembre 2013
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Chercheur en maths appli
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2013
    Messages : 29
    Points : 46
    Points
    46
    Par défaut
    Juste pour info, pas besoin de filtrer un couple. Tu peux le faire apparaître explicitement en paramètre.
    Càd, au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    let nom = fun p ->
    	match p with
    	|(a,_) -> a;;
    tu peux écrire :


  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Points : 376
    Points
    376
    Par défaut
    Je suis d'accord, mais je trouve ça "sale".
    Je veux dire par là, dans un fichier de milles et qques lignes de codes ou plus, si on voit ça, on a du mal à comprendre l'utilité de la chose, surtout que honnêtement ça fait pas gagner beaucoup de temps à l'écriture, et ça nous en fera perdre surement bien plus à la relecture.

    A la limite, je suis d'accord pour dire qu'il aurait été plus propre de remplacer le match par function. Qui est plus compact et tout aussi lisible.

  5. #5
    Membre du Club
    Homme Profil pro
    Chercheur en maths appli
    Inscrit en
    Novembre 2013
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Chercheur en maths appli
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2013
    Messages : 29
    Points : 46
    Points
    46
    Par défaut
    Tout est une question de point de vue.
    Pour moi, le filtrage a vocation d'éclater les différentes valeurs structurelles possibles, c'est donc logique de ne pas filtrer une valeur qui n'a qu'une seule structure possible (ici un couple). Tu utilises un peu un bazooka pour tuer une mouche, et ça n'aide clairement pas à la lecture.

    Pour moi, utiliser function nuit beaucoup plus à la lecture (bien que je l'utilise).

    Ca fait plusieurs années que je code en Caml, je l'enseigne, et avec le temps, j'ai affiné mes choix d'implémentation pour améliorer l'écriture, la relecture et la maintenance.
    Par exemple, j'écrirais ton code comme cela :

    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
    type pouvoir = E | F | T | A | X
     
    let pouvoir2string = function
      | E -> "eau"
      | F -> "feu"
      | T -> "terre"
      | A -> "air"
      | X -> "rien
     
    (* récupère la représentation d'un couple pour l'affichage *)
    let representation (nom, pouvoir) =
      (nom, pouvoir2string pouvoir)
     
    let personne2string (nom, pouvoir) =
      nom ^ "[" ^ pouvoir ^ "]"
     
    (*Retourne la chaine correspondante à un arbre*)
    let rec concat_arbre arbre =
      match arbre with
        | Feuille(nom, pouvoir) -> personne2string (nom, pouvoir)
        | Noeud(gauche, personne, droit) -> personne2string (representation personne) ^ "(" ^ concat_arbre gauche ^ "," ^ concat_arbre droit ^ ")"
    Pas besoin de faire compliqué quand on peut faire simple

  6. #6
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Points : 376
    Points
    376
    Par défaut
    Au final, ta version fait la même chose, sauf que tu simplifie en ne l'appelant plus sur un couple. La fonction devient donc plus simple et permet d'arriver au même résultat. C'est vrai.

    Dans le fond, ce n'est qu'une question de point de vue, je pense qu'il suffit de faire ce qui est le plus parlant.

    Par exemple, le traitement que je fais en une fonction tu le fais en deux. Niveau lisibilité ta solution est clairement la meilleure, mais niveau ressource je pense que la mienne serait moins gourmande. Quoi que je n'ai aucune certitude là dessus =)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Pas besoin de faire compliqué quand on peut faire simple
    Amen !

    Je ne saurais être plus d'accord^^ En revanche, dans le petit exemple de dessus je suis pas non plus certain que l'on puisse dire que c'est bien compliqué non plus^^

  7. #7
    Membre du Club
    Homme Profil pro
    Chercheur en maths appli
    Inscrit en
    Novembre 2013
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Chercheur en maths appli
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2013
    Messages : 29
    Points : 46
    Points
    46
    Par défaut
    Aaaah je comprends ta méprise !
    Ma fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let representation (nom, pouvoir) =
    prend bien un seul argument qui est un couple. Ce n'est pas la même syntaxe que le C (par exemple) où les paramètres sont séparés par des virgules. Ici on sépare les paramètres par des espaces. Donc je n'ai rien changé aux types des fonctions

  8. #8
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Points : 376
    Points
    376
    Par défaut
    Du tout il n'y a pas méprise^^

    Je voulais dire, lorsque vous faîtes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let pouvoir2string = function
      | E -> "eau"
      | F -> "feu"
      | T -> "terre"
      | A -> "air"
      | X -> "rien
     
    (* récupère la représentation d'un couple pour l'affichage *)
    let representation (nom, pouvoir) =
      (nom, pouvoir2string pouvoir)
    De mon coté je fais la même chose avec une unique fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    let abbreToRepre = fun c ->
    	match c with
    	|(n,p) -> match p with
    				|"E" -> (n,"eau")
    				|"F" -> (n,"feu")
    				|"T" -> (n,"terre")
    				|"A" -> (n,"air")
    				|"X" -> (n,"rien")
    				| _ -> failwith "Type inconnu";;
    Bien sûr, j'aurais pu m'éviter un match sur la fonction en écrivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    let abbreToRepre = fun (n,p) ->
                 match p with
    				|"E" -> (n,"eau")
    				|"F" -> (n,"feu")
    				|"T" -> (n,"terre")
    				|"A" -> (n,"air")
    				|"X" -> (n,"rien")
    				| _ -> failwith "Type inconnu";;
    Mais pour ma part, ça ne me gêne pas d'utiliser le filtrage pour dérouler une variable, je trouve ça plus "clair" mais j'ai bien conscience que c'est particulier à chacun.

  9. #9
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    Plusieurs remarques annexes à propos de ce bout de code, même si la discussion est marquée comme terminée. Il me semble qu'il y a beaucoup de choses à dire, surtout si l'objectif final est d'écrire plusieurs milliers de lignes de code.


    • Tout d'abord, la convention généralement admise en caml est d'utiliser foo_bar plutôt que fooBar pour les fonctions.
    • La concaténation avec ^ est à la fois peu lisible et peu performante. Pour plus de lisibilité, de souplesse, de performance et de maintenabilité (entre autres), utiliser le module Printf.
    • dans le cas du pattern matching, lorsque le motif est irréfutable (par exemple pour les couples (foo, bar)), la notation let f = fun x -> match x with (foo, bar) ... se simplifie en let f (foo, bar) = ... et ceci n'est pas exclusivement une affaire de goût.
    • Est-il vraiment nécessaire de commenter des fonctions d'une seule ligne ? Surtout les fonctions nom et pouvoir qui sont des synonymes de fst et snd déjà disponibles !
    • Forum français, discussion française, commentaires français, c'est tout bon, mais là encore, c'est une convention d'utiliser des noms anglais dans le code source.


    Citation Envoyé par Amnael
    Par exemple, le traitement que je fais en une fonction tu le fais en deux. Niveau lisibilité ta solution est clairement la meilleure, mais niveau ressource je pense que la mienne serait moins gourmande. Quoi que je n'ai aucune certitude là dessus =)
    Relire Knuth, Structured Programming With Go To Statements: "Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil"

    Pour ma part, je pars du principe qu'il vaut mieux appliquer le principe de moindre surprise. Tout lecteur d'un code source nouveau aura d'autant plus de temps à consacrer aux algorithmes et aux idées sous-jacentes s'il n'est pas distrait par la forme du code. C'est d'ailleurs pour cette raison que des recommandations sont généralement faites quant à la façon d'utiliser un langage. Il n'y a bien sûr aucune obligation à suivre ces bonnes pratiques, mais il ne faut pas oublier que ceci peut avoir un coût. Pensez, par exemple, au jour où le code doit être partagé avec d'autres programmeurs.

    Cordialement,
    Cacophrène

  10. #10
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Points : 376
    Points
    376
    Par défaut
    Bonsoir, merci pour ta remarque.

    Pour la façon de noter les fonctions, j'ai aussi l'habitude de noter avec les underscore en général, là je ne l'ai pas fais, à vrai dire je n'y ai même pas pensé.

    Je pense néanmoins qu'il est plus important de ne pas mélanger les conventions; du moment que je n'ai que des fooBar et pas un mélange des deux ça ira pour moi^^


    Pour first et second, je suis d'accord, en revanche je pense que quand on aborde un projet il est préférable de prendre des noms de fonctions plus parlant quitte à reproduire une fonction déjà existante.


    Là où j'ai un désaccord c'est au niveau des commentaires.

    En général, je trouve que les gens veulent mettre trop de commentaire ce qui nuit à la compréhension d'un code. Car lorsque quelqun reprend un code effectué, il est très rare qu'il reprenne le commentaire avec. Du coup on se retrouve parfois avec des commentaires qui n'ont plus lieu d'être après une maintenance ou autre.

    C'est pourquoi, je suis contre le fait de commenter le code. Pour moi si un algo est suffisamment clair il n'a pas besoin d'être commenté.

    Toutefois, je pense aussi que précéder chaque fonction d'un commentaire décrivant le rôle de la fonction est une bonne pratique et ce quel que soit la fonction en question. Sa permet surtout à ceux qui reliront le code derrière de comprendre le fonctionnement sans se plonger dans le code. Et puis, même personnellement, je fais parfois des choix sur certaines fonctions qui me semble logique sur le moment, mais si je reviens dessus un peu plus tard, ça peut me poser problème si je ne me remet pas dedans.
    Alors que là, on est directement fixé sur le rôle d'une fonction sans avoir à étudier/survoler son code.

    Sinon, pour les noms de fonctions etc etc le fait de tout mettre en anglais. Ok. Seulement, je me suis déjà retrouvé au cours d'un de mes travaux à l'université avec un code similaire à l'un de mes camarades. Quand je dis similaire, j'entends par là, même algo, même nom de fonction même nom de variable etc etc. C'était un simple tp noté donc c'était pas super grave, mais ça m'a valu un zéro ainsi qu'à la personne alors qu'en toute honnêteté, je n'avais jamais vu son code et inversement.

    Du coup, lorsque j'ai une note au bout, j'ai pris l'habitude de coder en français si je puis dire. Surtout, ça m'évite de me prendre des reproches comme quoi j'aurais pompé du code quelque part, au moins avec les noms de variables et compagnie, ça peut prouver la compréhension. Point de vue bizarre j'en suis conscient; mais que je te rassure lorsque je code en général pour moi je reste sur de l'anglais^^

    Encore merci pour le commentaire.

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

Discussions similaires

  1. Affichage simple d'un arbre en JSF
    Par suzchr dans le forum JSF
    Réponses: 9
    Dernier message: 03/12/2008, 10h56
  2. [arbre] affichage d'un simple arbre
    Par lichman dans le forum Débuter
    Réponses: 1
    Dernier message: 12/11/2008, 00h26
  3. affichage sous forme d'arbre
    Par bruman dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 05/09/2008, 14h14
  4. Problème d'affichage incompréhensible
    Par Bardack dans le forum AWT/Swing
    Réponses: 3
    Dernier message: 25/02/2007, 22h09
  5. Affichage incompréhensible sous IE
    Par trotters213 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 07/10/2006, 00h08

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