summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/xsim/code/xsim.grades.code.tex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/xsim/code/xsim.grades.code.tex
Initial commit
Diffstat (limited to 'macros/latex/contrib/xsim/code/xsim.grades.code.tex')
-rw-r--r--macros/latex/contrib/xsim/code/xsim.grades.code.tex153
1 files changed, 153 insertions, 0 deletions
diff --git a/macros/latex/contrib/xsim/code/xsim.grades.code.tex b/macros/latex/contrib/xsim/code/xsim.grades.code.tex
new file mode 100644
index 0000000000..4c25e99b45
--- /dev/null
+++ b/macros/latex/contrib/xsim/code/xsim.grades.code.tex
@@ -0,0 +1,153 @@
+% ----------------------------------------------------------------------------
+% the XSIM package - grades module
+%
+% eXercise Sheets IMproved
+%
+% ----------------------------------------------------------------------------
+% Clemens Niederberger
+% Web: https://github.com/cgnieder/xsim
+% E-Mail: contact@mychemistry.eu
+% ----------------------------------------------------------------------------
+% Copyright 2017--2018 Clemens Niederberger
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Clemens Niederberger.
+% ----------------------------------------------------------------------------
+% If you have any ideas, questions, suggestions or bugs to report, please
+% feel free to contact me.
+% ----------------------------------------------------------------------------
+\XSIMmodule{grades}{distribute goal sums to grades}
+
+\xsim_load_modules:n {goals}
+
+\msg_new:nnn {xsim} {grade-unknown}
+ { The~ grade~ `#1'~ has~ never~ been~ declared~ \msg_line_context: }
+
+\bool_new:N \l__xsim_grades_half_bool
+\fp_new:N \l__xsim_grade_round_fp
+\fp_zero:N \l__xsim_grade_round_fp
+\prop_new:N \l__xsim_relative_grades_prop
+\tl_new:N \l__xsim_grade_split_tl
+
+\cs_new:Npn \__xsim_fp_round_to_half:n #1
+ { round( 2*(#1),0)/2 }
+
+\cs_new:Npn \__xsim_grades_round:n #1
+ { round ( #1 , \l__xsim_grade_round_fp ) }
+
+% #1: factor
+% #2: goal sum
+\cs_new:Npn \__xsim_grade_rounded:nn #1#2
+ {
+ \bool_if:NTF \l__xsim_grades_half_bool
+ { \__xsim_fp_round_to_half:n }
+ { \__xsim_grades_round:n }
+ { (#1) * (#2) }
+ }
+
+\cs_new_protected:Npn \xsim_declare_relative_grades:n #1
+ {
+ \seq_set_split:NVn \l__xsim_tmpa_seq \l__xsim_grade_split_tl {#1}
+ \seq_map_inline:Nn \l__xsim_tmpa_seq
+ { \__xsim_declare_relative_grade:w ##1 \q_stop }
+ \xsim_verbose:n {Declaring~ relative~ grade~ distribution}
+ }
+
+\cs_new_protected:Npn \__xsim_declare_relative_grade:w #1 = #2 \q_stop
+ {
+ \tl_set:Nx \l__xsim_tmpa_tl { \tl_trim_spaces:n {#1} }
+ \tl_set:Nx \l__xsim_tmpb_tl { \tl_trim_spaces:n {#2} }
+ \prop_put:NVV \l__xsim_relative_grades_prop
+ \l__xsim_tmpa_tl
+ \l__xsim_tmpb_tl
+ }
+
+% #1: grade
+% #2: sum of points
+% #3: code after grade requirement if == 1
+% #4: code after grade requirement if != 1
+\cs_new_protected:Npn \xsim_get_grade:nnnn #1#2#3#4
+ {
+ \prop_get:NnNTF \l__xsim_relative_grades_prop {#1} \l__xsim_tmpa_tl
+ {
+ \xsim_print_goal:nnn
+ {
+ min(
+ \__xsim_grade_rounded:nn
+ { \l__xsim_tmpa_tl }
+ {#2} ,
+ #2
+ )
+ }
+ {#3}
+ {#4}
+ }
+ { \msg_error:nnn {xsim} {grade-unknown} {#1} }
+ }
+
+% #1: grade
+% #2: goal
+% #3: code after grade requirement if == 1
+% #4: code after grade requirement if != 1
+\cs_new_protected:Npn \xsim_get_grade_goal:nnnn #1#2#3#4
+ {
+ \xsim_if_goal_exists:nTF {#2}
+ {
+ \xsim_get_grade:nnnn
+ {#1}
+ { \use:c {g__xsim_total_goal_#2_fp} }
+ {#3}
+ {#4}
+ }
+ { \msg_error:nnn {xsim} {goal-unknown} {#2} }
+ }
+
+% #1: grade
+% #2: goal list (separated with +)
+% #3: code after grade requirement if == 1
+% #4: code after grade requirement if != 1
+\cs_new_protected:Npn \xsim_get_grade_requirement:nnnn #1#2#3#4
+ {
+ \seq_set_split:Nnn \l__xsim_tmpa_seq {+} {#2}
+ \fp_zero:N \l__xsim_tmpa_fp
+ \seq_map_inline:Nn \l__xsim_tmpa_seq
+ {
+ \fp_add:Nn \l__xsim_tmpa_fp
+ { \use:c {g__xsim_total_goal_\tl_trim_spaces:n {##1} _fp} }
+ }
+ \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#3} {#4}
+ }
+
+% #1: grade
+% #2: code after grade requirement if == 1
+% #3: code after grade requirement if != 1
+\cs_new_protected:Npn \xsim_get_absolute_grade_requirement:nnn #1#2#3
+ {
+ \fp_zero:N \l__xsim_tmpa_fp
+ \xsim_foreach_goal:n
+ {
+ \fp_add:Nn \l__xsim_tmpa_fp
+ { \use:c {g__xsim_total_goal_##1_fp} }
+ }
+ \xsim_get_grade:nnnn {#1} { \l__xsim_tmpa_fp } {#2} {#3}
+ }
+
+\keys_define:nn {xsim/grades}
+ {
+ round .fp_set:N = \l__xsim_grade_round_fp ,
+ half .bool_set:N = \l__xsim_grades_half_bool ,
+ split .tl_set:N = \l__xsim_grade_split_tl ,
+ split .initial:n = {,}
+ }
+
+% ----------------------------------------------------------------------------
+\file_input_stop: