Wolfram Language

Live Version Coming Soon Check out other examples

Correct and Grade Keyboard Practice

Automatically correct and grade text typed from dictation.


code

GradeText[txt_, ref_] := Framed[Column[{ Panel@Style[Row[{"Grade: ", Style[ LetterGrade[Round[100 4 Length[Cases[#, {___}, {1}]]/ StringLength[ref]]], Bold, Red]}], 20], Magnify[Row[Flatten[# /. {a_, b_} :> Overscript[Overlay[{Style[b, Blue], Style["/", 14, Red]}], Style[a, 12, Red]]]]] }], RoundingRadius -> 7] &[SequenceAlignment[ref, txt]]
LetterGrade[x_] := Piecewise[{{"A", 90 <= x}, {"B", 80 <= x}, {"C", 70 <= x}, {"D", 60 <= x}, {"F", True}}];

how it works

Text typed by a student from dictation is checked against the original, graded, and returned with clearly marked errors. Compact code derives from the built-in NeedlemanWunsch alignment algorithm for strings.

Here is a text dictated to students for keyboard practice:

referenceText = " Two roads diverged in a yellow wood, And sorry I could not travel both And be one traveler, long I stood And looked down one as far as I could To where it bent in the undergrowth";

And here is a text typed by a student from the dictation:

studentText = " Two roadz diverged in a yelow wud, And sory I could not travel bos And be one travller, long I stood And loocked down one as far as I cood to where it bant in the undegrowth";

The built-in global NeedlemanWunsch alignment algorithm finds student errors:

sa = SequenceAlignment[referenceText, studentText]

Format that result nicely using Overscript and Overlay:

Magnify[Row[Flatten[ sa /. {a_, b_} :> Overscript[Overlay[{Style[b, Blue], Style["/", 14, Red]}], Style[a, 12, Red]]]]]

Calculate a percentage grade by dividing the number of errors by one quarter of the total number of text characters:

grade = Round[ 100 Length[Cases[sa, {___}, {1}]]/(StringLength[referenceText]/4)]

Assign letter grades from percentage grades:

LetterGrade[x_] := Piecewise[{{"A", 90 <= x}, {"B", 80 <= x}, {"C", 70 <= x}, {"D", 60 <= x}, {"F", True}}];
LetterGrade[grade]

Combine the letter grade and corrected text into a framed presentation:

GradeText[txt_, ref_] := Framed[Column[{ Panel@Style[Row[{"Grade: ", Style[ LetterGrade[Round[100 4 Length[Cases[#, {___}, {1}]]/ StringLength[ref]]], Bold, Red]}], 20], Magnify[Row[Flatten[# /. {a_, b_} :> Overscript[Overlay[{Style[b, Blue], Style["/", 14, Red]}], Style[a, 12, Red]]]]] }], RoundingRadius -> 7] &[SequenceAlignment[ref, txt]]
GradeText[studentText, referenceText]