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 @@
} #_(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)))
(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]
(fn [index text-fragment]
(let [fragment-id (str index "-" text-fragment)]
(if-let [correction (get corrections fragment-id)]
(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)))
reference-text (apply-corrections text reference-corrections)
user-text (apply-corrections text user-corrections)
points (if (= reference-text user-text)
(println reference-corrections)
(println reference-text)
(println user-corrections)
(println user-text)
{:answer-id answer
{:corrections answer
:correct (pos? points)
:points points
:points-max (apply max
(map #(sc-get-points answer-options (:id %))
: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)]
(>= (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 @@
(: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
(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
(s/def :text-correction/corrections (s/and
(s/map-of string?
(s/def :text-correction/type #{:text-correction})
(s/def :text-correction/core (s/and (s/keys :req-un [:text-correction/answers
:opt-un [:exercise/shuffled
#(= 1 (count (filter (comp pos? :selected-points) (:answers %))))))
(s/def :text-correction/core (s/and (s/keys :req-un [:text-correction/correction-text
(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]}]
(fn [index text-fragment]
(let [fragment-id (str index "-" text-fragment)]
^{:key (str component-id "-" fragment-id)}
{:id fragment-id
:on-click #(on-select fragment-id text-fragment index)}
(-> text
(split #"(\ |\. |\,)")
(split-text text)
(defn new-exercise-form [core]
(let [edit-text (reagent/atom nil)]
......@@ -105,11 +105,16 @@
[:th {:width "10%"} ""]
(for [[id c] (:corrections @core)]
(for [[id c] (sort-by :index (:corrections @core))]
^{:key (str "tcorrection_" id)}
[:td (:word c)]
[:td (str (:index c))]
(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 @@
[ :as ce-ex]
: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
......@@ -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?)}
{:id fragment-id
:class (when correction
:on-click #(do
(reset! edit? fragment-id)
(reset! edit-text (or correction
(reset! edit-text (or (:correct-word correction)
(or correction text-fragment)
(or (:correct-word correction)
^{: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}]
{:on-click #(do
(on-delete fragment-id)
......@@ -53,10 +56,8 @@
[ "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