Handle justified MCQ in admin and sync part
This commit is contained in:
parent
488a032eba
commit
d7553f0392
@ -27,7 +27,7 @@ Tous les textes doivent utiliser l'encodage UTF8.
|
|||||||
* `label = "Intitulé du groupe"` : (facultatif) intitulé du groupe de choix ;
|
* `label = "Intitulé du groupe"` : (facultatif) intitulé du groupe de choix ;
|
||||||
* `[[flag_mcq.choice]]` : représente un choix, répétez autant de fois qu'il y a de choix :
|
* `[[flag_mcq.choice]]` : représente un choix, répétez autant de fois qu'il y a de choix :
|
||||||
+ `label = "Intitulé de la réponse"`,
|
+ `label = "Intitulé de la réponse"`,
|
||||||
+ `value = true` : (facultatif, par défaut `false`) valeur attendue pour ce choix ;
|
+ `value = true` : (facultatif, par défaut `false`) valeur attendue pour ce choix ; pour un QCM justifié, utilisez une chaîne de caractères (notez qu'il n'est pas possible de combiner des réponses vraies justifiées et justifiées) ;
|
||||||
- `[[flag_ucq]]` : drapeau sous forme de question à choix unique :
|
- `[[flag_ucq]]` : drapeau sous forme de question à choix unique :
|
||||||
* `label = "Intitulé du groupe"` : (facultatif) intitulé du groupe de choix ;
|
* `label = "Intitulé du groupe"` : (facultatif) intitulé du groupe de choix ;
|
||||||
* `raw = 'MieH2athxuPhai6u'` : drapeau attendu parmi les propositions ;
|
* `raw = 'MieH2athxuPhai6u'` : drapeau attendu parmi les propositions ;
|
||||||
@ -221,5 +221,5 @@ Exemple `DIGESTS.txt` {#exemple-digeststxt}
|
|||||||
---
|
---
|
||||||
title: Format des répertoires pour la synchronisation
|
title: Format des répertoires pour la synchronisation
|
||||||
author: FIC team 2019
|
author: FIC team 2019
|
||||||
date: "Dernière mise à jour du document : 17 août 2018"
|
date: "Dernière mise à jour du document : 27 novembre 2018"
|
||||||
---
|
---
|
||||||
|
@ -38,7 +38,7 @@ type ExerciceFlag struct {
|
|||||||
// ExerciceFlagMCQChoice holds a choice for an MCQ flag.
|
// ExerciceFlagMCQChoice holds a choice for an MCQ flag.
|
||||||
type ExerciceFlagMCQChoice struct {
|
type ExerciceFlagMCQChoice struct {
|
||||||
Label string
|
Label string
|
||||||
Value bool `toml:",omitempty"`
|
Value interface{} `toml:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExerciceFlagMCQ holds information about a MCQ flag.
|
// ExerciceFlagMCQ holds information about a MCQ flag.
|
||||||
|
@ -120,13 +120,39 @@ func SyncExerciceFlags(i Importer, exercice fic.Exercice) (errs []string) {
|
|||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
hasOne := false
|
hasOne := false
|
||||||
|
isJustified := false
|
||||||
for cid, choice := range quest.Choice {
|
for cid, choice := range quest.Choice {
|
||||||
if _, err := flag.AddEntry(choice.Label, choice.Value); err != nil {
|
var val bool
|
||||||
|
if choice.Value == nil {
|
||||||
|
val = false
|
||||||
|
} else if p, ok := choice.Value.(bool); ok {
|
||||||
|
val = p
|
||||||
|
if isJustified {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: all true items has to be justified in this MCQ.", path.Base(exercice.Path), nline + 1))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if p, ok := choice.Value.(string); ok {
|
||||||
|
val = true
|
||||||
|
if hasOne && !isJustified {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: all true items has to be justified in this MCQ.", path.Base(exercice.Path), nline + 1))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
isJustified = true
|
||||||
|
if _, err := exercice.AddRawFlag("%" + quest.Label + "%" + choice.Label, "", false, nil, []byte(p)); err != nil {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: error MCQ #%d: %s", path.Base(exercice.Path), nline + 1, err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errs = append(errs, fmt.Sprintf("%q: error in MCQ %d choice %d: has an invalid type. Expected true, false or a string", path.Base(exercice.Path), nline + 1, cid))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := flag.AddEntry(choice.Label, val); err != nil {
|
||||||
errs = append(errs, fmt.Sprintf("%q: error in MCQ %d choice %d: %s", path.Base(exercice.Path), nline + 1, cid, err))
|
errs = append(errs, fmt.Sprintf("%q: error in MCQ %d choice %d: %s", path.Base(exercice.Path), nline + 1, cid, err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if choice.Value {
|
if val {
|
||||||
hasOne = true
|
hasOne = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ type myTeamHint struct {
|
|||||||
}
|
}
|
||||||
type myTeamMCQ struct {
|
type myTeamMCQ struct {
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
|
Justify bool `json:"justify,omitempty"`
|
||||||
Choices map[int64]string `json:"choices,omitempty"`
|
Choices map[int64]string `json:"choices,omitempty"`
|
||||||
Solved *time.Time `json:"solved,omitempty"`
|
Solved *time.Time `json:"solved,omitempty"`
|
||||||
}
|
}
|
||||||
@ -146,6 +147,28 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expose exercice flags
|
||||||
|
|
||||||
|
var justifiedMCQ map[string]bool
|
||||||
|
exercice.Flags = []string{}
|
||||||
|
|
||||||
|
if flags, err := e.GetFlags(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
for _, k := range flags {
|
||||||
|
if k.Label[0] == '%' {
|
||||||
|
justifiedMCQ[k.Label[1:]] = true
|
||||||
|
} else if t == nil {
|
||||||
|
exercice.Flags = append(exercice.Flags, fmt.Sprintf("%x", k.Checksum)+k.Label)
|
||||||
|
} else {
|
||||||
|
exercice.Flags = append(exercice.Flags, k.Label)
|
||||||
|
if PartialValidation {
|
||||||
|
exercice.SolvedMat = append(exercice.SolvedMat, t.HasPartiallySolved(k) != nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Expose exercice MCQs
|
// Expose exercice MCQs
|
||||||
|
|
||||||
exercice.MCQs = []myTeamMCQ{}
|
exercice.MCQs = []myTeamMCQ{}
|
||||||
@ -155,33 +178,18 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) {
|
|||||||
} else {
|
} else {
|
||||||
for _, mcq := range mcqs {
|
for _, mcq := range mcqs {
|
||||||
choices := map[int64]string{}
|
choices := map[int64]string{}
|
||||||
|
justified := false
|
||||||
for _, e := range mcq.Entries {
|
for _, e := range mcq.Entries {
|
||||||
choices[e.Id] = e.Label
|
choices[e.Id] = e.Label
|
||||||
}
|
if _, ok := justifiedMCQ[m.Title + "%" + e.Label]; ok {
|
||||||
if t == nil {
|
justified = true
|
||||||
exercice.MCQs = append(exercice.MCQs, myTeamMCQ{mcq.Title, choices, nil})
|
|
||||||
} else {
|
|
||||||
exercice.MCQs = append(exercice.MCQs, myTeamMCQ{mcq.Title, choices, t.HasPartiallyRespond(mcq)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expose exercice flags
|
|
||||||
|
|
||||||
exercice.Flags = []string{}
|
|
||||||
|
|
||||||
if flags, err := e.GetFlags(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
for _, k := range flags {
|
|
||||||
if t == nil {
|
|
||||||
exercice.Flags = append(exercice.Flags, fmt.Sprintf("%x", k.Checksum)+k.Label)
|
|
||||||
} else {
|
|
||||||
exercice.Flags = append(exercice.Flags, k.Label)
|
|
||||||
if PartialValidation {
|
|
||||||
exercice.SolvedMat = append(exercice.SolvedMat, t.HasPartiallySolved(k) != nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if t == nil {
|
||||||
|
exercice.MCQs = append(exercice.MCQs, myTeamMCQ{mcq.Title, justified, choices, nil})
|
||||||
|
} else {
|
||||||
|
exercice.MCQs = append(exercice.MCQs, myTeamMCQ{mcq.Title, justified, choices, t.HasPartiallyRespond(mcq)})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user