Réponse multidraw avec canvasdraw

Accueil Forums Programmation WIMS Programmation d’exercices OEF Réponse multidraw avec canvasdraw

Vous lisez 9 fils de discussion
  • Auteur
    Messages
    • #8776
      Sévan Polteau
      Participant
      Up
      0
      Down
      ::

      Bonjour,

      Je souhaiterais programmer un exercice où un dessin est à reproduire en traçant des segments, mais où il serait possible de tracer des droites qui n’entreraient pas en compte dans le calcul du score (ces droites seraient donc des traits de construction qui serviraient à identifier des alignements par les élèves).

      J’ai tenté quelque chose avec le type de réponse multidraw et en programmant une condition. Cette condition fonctionne sauf quand la fin d’un segment est le début d’un autre. Dans ce cas, la réponse donnée n’apparait pas complètement dans \reply, et donc l’analyse de la réponse est fausse.

      En augmentant la valeur de la précision, le problème s’atténue, mais en double cliquant pour que la fin d’un segment soit le début du suivant, les coordonnées des points cliqués ne sont pas tous pris en compte…

      Est-ce-que ce problème sur canvasdraw avec analyse des réponses a déjà été soulevé ? Quelqu’un aurait une idée de quoi faire pour résoudre ce problème ?

      D’avance merci,

      Sévan

       

      Voici mon fichier source, où le dessin à reproduire est dessiné en gris sur le modèle… Le source est un peu long, en particulier pour la partie concernant la condition que j’ai essayé d’expliquer étape par étape…

       

       

      \integer{size=400}
      \real{xmin=-1.2}  \real{xmax=1.2}
      \real{ymin=\xmin} \real{ymax=\xmax}
      \real{taille_unite=\size/(\xmax-\xmin)}
      \real{z=1/\taille_unite}  :% Dans le repère, largeur 1 pixel
      \real{prec=10*\z}   :% Précision en pixels pour les points
      
      :%%%%%%%%%%%%%% Valeurs aléatoires
      
      \text{x_pts=1,0,-1,0}
      \text{y_pts=0,1,0,-1}
      \integer{nb_pts=items(\x_pts)}
      \text{pts=}
      \for{j=1 to \nb_pts}{
        \text{pts=\pts,\x_pts[\j],\y_pts[\j]}
      }
      
      \text{pts=wims(nonempty items \pts)}
      \text{x_pts=wims(nonempty items \x_pts)}
      \text{y_pts=wims(nonempty items \y_pts)}
      
      :% Coord intersections importantes
      \text{x_pts=\x_pts,0}
      \text{y_pts=\y_pts,0}
      
      :%Points pour polyline à tracer (modèle)
      \text{n_pts_dessin=1,2,3,4,1,5,2}
      \integer{n_items_temp=items(\n_pts_dessin)}
      \text{pts_dessin=}
      \for{j=1 to \n_items_temp}{
        \real{x1=\x_pts[\n_pts_dessin[\j]]    }
        \real{y1=\y_pts[\n_pts_dessin[\j]]    }
        \text{pts_dessin=\pts_dessin,\x1,\y1}
      }
      \text{pts_dessin=wims(nonempty items \pts_dessin)}
      
      :%%%% Segments attendus
      Definir \segments comme une matrice du type
      x1 y1 x2 y2
      x'1 y'1 x'2 y'2
      k segments
      \integer{nb_segments_answer=items(\pts_dessin)/2}
      \text{segments=}
      \integer{compteur=0}
      \for{j=1 to \nb_segments_answer}{
        \integer{compteur=\compteur+1}
        \text{segments=\segments;\x_pts[\n_pts_dessin[\j]],\y_pts[\n_pts_dessin[\j]],\x_pts[\n_pts_dessin[\j+1]],\y_pts[\n_pts_dessin[\j+1]]}
      }
      \text{segments=row(2..\nb_segments_answer,\segments)}
      \integer{k=rows(\segments)}
      
      :%%%% Préparation dessin
      
      \text{canvas_code=xrange \xmin,\xmax
        yrange \ymin,\ymax
        linewidth 1
        opacity 255,255
        crosshairs black, \pts
        polyline grey,\pts_dessin
        precision 1000
        linewidth 2
        multistrokecolors orange,cyan
      }
      
      :%%%%%% Statement
      \statement{segments,\segments
      <br>
      \embed{r1,\size x \size
      lines segments
      [\canvas_code]}
      }
      
      :%%%%%%%%%% Answer
      \answer{}{\rep}{type=multidraw}
      
      :%%%%%%%%%%%%%% Condition pour validité de la réponse
      :%%%% Test précision
      Pour un nombre donné xA
      Tester chaque coordonnée de la réponse pour savoir si elle est dans l'intervalle [xA-prec,xA+prec]
      Si oui, indiquer l'emplacement de ce nombre dans le vecteur réponse
      
      A,B : réponses attendues
      x1,y1, x2,y2 : réponses données et testées
      
      :%%% Test des segments
      \text{reponse_segments=row(2,\reply1)}
      \integer{nb_items=items(\reponse_segments)}       
      \text{reponse_segments=item(2..\nb_items,\reponse_segments)}    :%% Réponse donnée par l'élève (liste des coordonnées des extrémités des segments) (on enlève le premier terme qui est "segments")
      \text{reussite_segment=}
      \for{j=1 to \k}{
          \text{position=}              :%% On teste pour chacun des segments attendus, pour obtenir les positions des coordonnées proches de xA  (notons [AB] le segment pour les commentaires)
          \integer{test_reussite=0} 
        \real{xA=\segments[\j;1]} \real{xA_min=\xA-\prec} \real{xA_max=\xA+\prec}       :%% On recherche les valeurs "proches" de xA
        \real{yA=\segments[\j;2]} \real{yA_min=\yA-\prec} \real{yA_max=\yA+\prec}
        \real{xB=\segments[\j;3]} \real{xB_min=\xB-\prec} \real{xB_max=\xB+\prec}
        \real{yB=\segments[\j;4]} \real{yB_min=\yB-\prec} \real{yB_max=\yB+\prec}
      
        \for{q=1 to \nb_items}{
          \real{x1=item(\q,\reponse_segments)}      :%% x1, nombre à tester (tester si elle est proche de l'abscisse de A...)
          \if{\x1>\xA_min and \x1<\xA_max}{     :%% Si le nombre est proche de xA, 
            \text{position=\position,\q}        :%% On le rajoute à la liste des positions à tester
          } 
        \text{position=wims(nonempty item \position)}
        }
      
      \integer{nb_tests=items(\position)}
      \if{\nb_tests=0}{\integer{test_reussite=0}}       :%% Si l'abscisse de A n'apparait pas, 0 au test de réussite
        
      \for{p=1 to \nb_tests}{\integer{test_position=(\position[\p]-1)%2}  :%% 0 si c'est bien une position en abscisse
        \if{\test_position=0}{            :%% Si l'abscisse de A a une place "d'abscisse"         
          \real{y1=\reponse_segments[\position[\p]+1]}      :%% On définit l'ordonnée donnée en réponse
          \if{\y1>\yA_min and \y1<\yA_max}{         :%% On teste si l'ordonnée de A correspond à la réponse (y2) (et donc si A apparait bien dans la réponse avec une précision suffisante)
            \integer{test_position2=(\position[\p]-1)%4}      :%% On teste si A est répondu en premier (valeur 0), ou en 2e (valeur 2)
            \if{\test_position2=0}{           :%% Si A est répondu en premier
              \real{x2=\reponse_segments[\position[\p]+2]}      :%% On définit les coordonnées du points de l'autre extrémité répondue
              \real{y2=\reponse_segments[\position[\p]+3]}
              \if{\x2>\xB_min and \x2<\xB_max}{       :%% On vérifie que ce point est bien B
          \if{\y2>\yB_min and \y2<\yB_max}{\integer{test_reussite=1}}
        }         
            }
            \if{\test_position2=2}{           :%% Si A est répondu en 2e
              \real{x2=\reponse_segments[\position[\p]-2]}      :%% On définit les coordonnées du point de l'autre extrémité répondue
              \real{y2=\reponse_segments[\position[\p]-1]}
              \if{\x2>\xB_min and \x2<\xB_max}{       :%% On vérifie que ce point est bien B
          \if{\y2>\yB_min and \y2<\yB_max}{\integer{test_reussite=1}}
        }         
            } 
          }
        }
      }
        \text{reussite_segment=\reussite_segment,\test_reussite}    :%% On rajoute la valeur du test à la liste (pour produit plus tard)
      }
      \text{reussite_segment=wims(nonempty items \reussite_segment)}
      \integer{nb_items=items(\reussite_segment)}
      \integer{test_reussite=1}
      \for{j=1 to \nb_items}{\integer{test_reussite=\test_reussite*\reussite_segment[\j]}}  :%% On multiplie les coordonnées du vecteur réussite : Si un échec, le produit est nul. Si que des 1, le produit vaut 1.
      
      \condition{}{\test_reussite=1}        :%% Condition de réussite sur la answer n°1
      
      :%%%%%%%%%% Solution et feedback
      
      \feedback{1=1}{
      \reply1
      }
      
    • #8777
      bernadette
      Maître des clés
      Up
      0
      Down
      ::

      Simplifie ton code:
      Si c’est un bogue du type de réponse multidraw , on n’a besoin que de la valeur de reply1 comme tu le mets à la fin, pas de ton analyse.
      De même le bogue dépend-t-il de tes conditions initiales et alors donne-nous juste le cas avec les conditions initiales en question ou de la manière dont on répond.
      Mets-nous le cas dans lequel il apparait.

      Bernadette

    • #8778
      Sévan Polteau
      Participant
      Up
      0
      Down
      ::

      L’analyse me permet de vérifier la validité des segments (comme le fait multidraw tout seul sans analyse), mais sans tenir compte des droites car je ne souhaite pas que cela rentre en compte dans la note de l’exercice (et je n’ai pas trouvé la possibilité de tracer des droites sans que cela entre en jeu dans la notation) .

       

      La situation qui provoque le bug est quand il y a au moins un point en commun à deux segments, par exemple en reproduisant le dessin qui apparaît en gris en double cliquant pour passer de la fin d’un segment au début du suivant.

      Par exemple en cliquant surl les points

      1,0,0, 1 (segment 1)

      0,1,-1,0 (segment 2)

      -1,0,0,-1 (segment 3)

      Etc…

      Le segment 2 n’apparaît alors pas dans reply1, idem pour le segment 4…

       

      Alors que si on clique sur les points :

      1,0,0,1

      0.02,1.04,-1,0

      -1.03,0.05,0,-1

      Tout apparaît dans reply1

    • #8779
      jm.evers
      Participant
      Up
      0
      Down
      ::

      ‘m not sure if I understand your issue, but there is a keyword you could use to « allow duplicate answers »
      from doc’s:
      ###############
      duplicates || allowdups
      keyword (no arguments)
      — only useful in case of a multidraw student reply.
      — only useful in default replyformat (eg in case of a not specified replyformat).
      — if set, duplicate (x:y) coordinates will not be removed from the student reply.
      — technical: a javascript variable « allow_duplicate_answer = 1; » is declared.
      — default for command multidraw is: removal of duplicates.
      #############

      joke

    • #8780
      bernadette
      Maître des clés
      Up
      0
      Down
      ::

      J’ai bien compris que dans ton exercice tu as besoin d’analyser la réponse. Mais pour savoir si le type de réponse multidraw donne dans reply1 ce que tu penses y être, on n’en a pas besoin. Mais la réponse est peut-être dans ce que dit Joke mais je ne suis pas sûre que ces options soient possibles dans le type de réponse multidraw (voir fichier dans public_html/scripts/anstype)
      Bernadette

      • Cette réponse a été modifiée le il y a 1 mois et 1 semaine par bernadette.
    • #8782
      bernadette
      Maître des clés
      Up
      0
      Down
      ::

      L’option duplicates est en effet utilisée dans le type de réponse multidraw dans oef pour les types arrows, arrows2, curvedarrows, curvedarrows2, segments,lines
      mais visiblement cela ne fonctionne pas (il est marqué non testé dans le code!!!). Je vais regarder (mais avec un exerice court sans aléatoire c’est plus facile …)

      • Cette réponse a été modifiée le il y a 1 mois et 1 semaine par bernadette.
    • #8785
      bernadette
      Maître des clés
      Up
      0
      Down
      ::

      J’ai commis dans le svn de wims une modification du type multidraw : à part l’histoire de duplicate (merci à joke) qui existe maintenant même si la réponse n’est pas donnée, j’ai permis d’utiliser des outils de forme qui ne sont pas pris en compte dans l’analyse de la réponse. Cela sera dans la version de wims de ce soir, merci de vérifier (mais le type de réponse n’a été que peu utilisé en tout cas dans les modules publics).
      Bernadette

    • #8786
      Sévan Polteau
      Participant
      Up
      0
      Down
      ::

      Merci pour vos retours très rapides !

      En effet Joke, ce que tu évoques correspondrait bien à la solution à mon problème. En revanche, je ne sais pas comme faire en sorte de déclarer « allow_duplicate_answer = 1 ».

    • #8789
      jm.evers
      Participant
      Up
      0
      Down
      ::

      just use keyword « duplicate » somewhere in your script…
      for example:
      \text{canvas_code=xrange \xmin,\xmax
      yrange \ymin,\ymax
      linewidth 1
      duplicate
      opacity 255,255
      crosshairs black, \pts
      polyline grey,\pts_dessin
      precision 1000
      linewidth 2
      multistrokecolors orange,cyan
      }

      joke

    • #8800
      Sévan Polteau
      Participant
      Up
      0
      Down
      ::

      Parfait, merci beaucoup !

      Avec un « duplicates » ça fonctionne bien.

      Sévan

Vous lisez 9 fils de discussion
  • Vous devez être connecté pour répondre à ce sujet.