Commit c56a122c authored by Bruno Burke's avatar Bruno Burke 😁

add basic check (with fixed points) for text-correction, also check if corrections are still valid

parent 94c23c52
Pipeline #26310 passed with stages
in 2 minutes and 40 seconds
......@@ -64,6 +64,7 @@
:list
:simple-text
:sorting
:text-correction
} #_(get-types-set))
(s/def :exercise/answers (s/coll-of ::answer :kind vector? :min-count 1 :distinct true))
......
(ns lernmeister.components.exercise-types.text-correction.check
(:require [lernmeister.components.exercise-types.check :as e-check]))
(:require [lernmeister.components.exercise-types.check :as e-check]
[lernmeister.components.exercise-types.text-correction.common :refer [split-text]]
[clojure.string :refer [join]]))
(defn sc-get-points [answer-options answer]
(reduce +
(map (fn [ao]
(if (= (:id ao) answer)
(:selected-points ao)
(:unselected-points ao)))
answer-options)))
(defn single-choice-check [exercise answer callback]
(let [answer-options (get-in exercise [:core :answers])
points (sc-get-points answer-options answer)]
(defn apply-corrections [text corrections]
(join
(map-indexed
(fn [index text-fragment]
(let [fragment-id (str index "-" text-fragment)]
(if-let [correction (get corrections fragment-id)]
correction
text-fragment)
))
(split-text text))))
(defn text-correction-check [exercise answer callback]
(let [text (get-in exercise [:core :correction-text])
reference-corrections (into {}
(map (fn [[id correction]]
(vector id (:correct-word correction)))
(get-in exercise [:core :corrections])))
user-corrections (into {}
(map (fn [[id correction]]
(vector id (:correct-word correction)))
answer))
reference-text (apply-corrections text reference-corrections)
user-text (apply-corrections text user-corrections)
points (if (= reference-text user-text)
5
0)]
(println reference-corrections)
(println reference-text)
(println user-corrections)
(println user-text)
(callback)
{:answer-id answer
{:corrections answer
:correct (pos? points)
:points points
:points-max (apply max
(map #(sc-get-points answer-options (:id %))
answer-options))}))
:points-max 5}))
(defmethod e-check/check-answer :text-correction [exercise answer callback]
(single-choice-check exercise answer callback))
(text-correction-check exercise answer callback))
(ns lernmeister.components.exercise-types.text-correction.common
(:require [clojure.string :refer [split]]))
(defn split-text [text]
(-> text
;;(split #"(\ |\. |\,)")
(split #"(\b[\wäÄöÖüÜß]+|\W)")
(->>
(filter not-empty)
)
))
(defn valid-correction? [text correction]
(let [fragments (split-text text)]
(and
(>= (count fragments) (:index correction))
(= (nth fragments (:index correction))
(:word correction)))))
......@@ -16,6 +16,6 @@
:additional-forms #?(:cljs edit-view/additional-forms :clj nil)}
:prepare prepare/prepare
:renderer #?(:cljs show-view/exercise-renderer :clj nil)
:checker check/single-choice-check
:spec ::tc-spec/single-choice})
:checker check/text-correction-check
:spec ::tc-spec/text-correction})
......@@ -4,25 +4,22 @@
:clj
(:require [clojure.spec.alpha :as s])))
(s/def :text-correction/unselected-points number?)
(s/def :text-correction/selected-points number?)
(s/def :text-correction/answer (s/keys :req-un [:answer/id
:answer/text
:text-correction/selected-points
:text-correction/unselected-points]))
(s/def :text-correction/answers (s/and
(s/coll-of :text-correction/answer
:kind vector?
:min-count 1
:distinct true)
#(= 1 (count (filter (comp pos? :selected-points) %)))))
(s/def :correction/word string?)
(s/def :correction/index number?)
(s/def :correction/correct-word string?)
(s/def :text-correction/correction-text string?)
(s/def :text-correction/correction (s/keys :req-un [:correction/word
:correction/index
:correction/correct-word]))
(s/def :text-correction/corrections (s/and
(s/map-of string?
:text-correction/correction)))
(s/def :text-correction/type #{:text-correction})
(s/def :text-correction/core (s/and (s/keys :req-un [:text-correction/answers
:text-correction/type]
:opt-un [:exercise/shuffled
:exercise/voting])
#(= 1 (count (filter (comp pos? :selected-points) (:answers %))))))
(s/def :text-correction/core (s/and (s/keys :req-un [:text-correction/correction-text
:text-correction/corrections
:text-correction/type])))
(s/def ::text-correction (s/keys :req-un [:text-correction/core]))
......@@ -2,7 +2,7 @@
(:require [reagent.core :as reagent]
[lernmeister.components.ui :as ui]
[lernmeister.components.exercise-types.edit :as e-edit]
[clojure.string :refer [split]])
[lernmeister.components.exercise-types.text-correction.common :refer [split-text valid-correction?]])
(:use [lernmeister.components.jshelper :only [get-unique-id try-number-parse]]
[lernmeister.components.helper :only [vec-remove]]))
......@@ -48,24 +48,24 @@
#(swap! all-options vec-remove index)} [:i.material-icons "remove"]]]]))
(defn selectable-text [text & {:keys []}]
(let [component-id (gensym "selectable-text")]
(fn [text & {:keys [on-select]}]
[:<>
[:div
(map-indexed
(fn [index text-fragment]
(let [fragment-id (str index "-" text-fragment)]
^{:key (str component-id "-" fragment-id)}
[:span.text-fragment
{:id fragment-id
:on-click #(on-select fragment-id text-fragment index)}
text-fragment
]))
(-> text
(split #"(\ |\. |\,)")
)
(split-text text)
)
]]
)
)
))
(defn new-exercise-form [core]
(let [edit-text (reagent/atom nil)]
......@@ -105,11 +105,16 @@
[:th {:width "10%"} ""]
]]
[:tbody
(for [[id c] (:corrections @core)]
(doall
(for [[id c] (sort-by :index (:corrections @core))]
^{:key (str "tcorrection_" id)}
[:tr
[:td (:word c)]
[:td (str (:index c))]
[:td
(if (valid-correction? (:correction-text @core) c)
(str (:index c))
[:span [:i.material-icons.left "error"] "Korrektur nicht mehr gültig"])
]
[:td [:input {:type :text
:on-change #(swap! core
update-in [:corrections id]
......@@ -119,7 +124,7 @@
[:td [:a.btn.btn.flat
{:on-click #(swap! core update :corrections dissoc id)}
[:i.material-icons "delete"]]]]
)
))
]]
])})))
......
......@@ -6,11 +6,13 @@
[lernmeister.components.content-elements.exercise.show :as ce-ex]
[lernmeister.components.content-elements.exercise.task-description
:refer [default-task-description]]
[lernmeister.components.exercise-types.text-correction.common :refer [split-text]]
[clojure.string :refer [split]]))
(defn correctable-text [text & {:keys []}]
(let [edit? (reagent/atom nil)
edit-text (reagent/atom nil)]
edit-text (reagent/atom nil)
component-id (gensym "correctable-text")]
(fn [text & {:keys [on-select corrections
on-delete]}]
[:<>
......@@ -22,23 +24,24 @@
correction (get corrections fragment-id)
edit-fragment? (= @edit? fragment-id)]
(if-not edit-fragment?
^{:key (str fragment-id "-" edit-fragment?)}
^{:key (str component-id "-" fragment-id "-" edit-fragment?)}
[:span.text-fragment
{:id fragment-id
:class (when correction
"corrected")
:on-click #(do
(reset! edit? fragment-id)
(reset! edit-text (or correction
(reset! edit-text (or (:correct-word correction)
text-fragment)))}
(or correction text-fragment)
(or (:correct-word correction)
text-fragment)
]
^{:key (str fragment-id "-" edit-fragment?)}
^{:key (str component-id "-" fragment-id "-" edit-fragment?)}
[:div.input-field.inline {:style {:margin "0px"}}
[:input.browser-default {:type :text
:value @edit-text
:on-change #(reset! edit-text (-> % .-target .-value))
}]
:value @edit-text
:on-change #(reset! edit-text (-> % .-target .-value))
:auto-focus true}]
[:a.btn.btn-flat
{:on-click #(do
(on-delete fragment-id)
......@@ -53,10 +56,8 @@
[:i.material-icons.center "save"]]
]
)))
(-> text
(split #"(\ |\. |\,)")
))
)))
(split-text text))
)
]]
)
......@@ -78,7 +79,7 @@
[default-task-description (:task-description exercise)]
[correctable-text (:correction-text exercise)
:corrections answer
:on-select #(on-change (assoc answer %1 %2))
:on-select #(on-change (assoc answer %1 {:correct-word %2}))
:on-delete #(on-change (dissoc answer %1))]
(when result
[:span.secondary-content [:b (str (:points result) "P")]])]]))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment