Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
components
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
7
Issues
7
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Test Cases
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Wandelwerk-Software
libraries
components
Commits
02a3dea7
Commit
02a3dea7
authored
Sep 14, 2020
by
Bruno Burke
😁
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'converge-calculation-and-multistep-calculation-exercise' into develop
parents
6dd5cae3
27308077
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
331 additions
and
904 deletions
+331
-904
src/cljc/lernmeister/components/exercise_types/calculation/check.cljc
...nmeister/components/exercise_types/calculation/check.cljc
+47
-231
src/cljc/lernmeister/components/exercise_types/calculation/migrate.cljc
...eister/components/exercise_types/calculation/migrate.cljc
+1
-1
src/cljc/lernmeister/components/exercise_types/calculation/migrate_answer.cljc
...components/exercise_types/calculation/migrate_answer.cljc
+0
-4
src/cljc/lernmeister/components/exercise_types/calculation/spec.cljc
...rnmeister/components/exercise_types/calculation/spec.cljc
+1
-2
src/cljc/lernmeister/components/exercise_types/multistep_calculation/check.cljc
...omponents/exercise_types/multistep_calculation/check.cljc
+26
-22
src/cljc/lernmeister/components/exercise_types/multistep_calculation/migrate.cljc
...ponents/exercise_types/multistep_calculation/migrate.cljc
+9
-3
src/cljc/lernmeister/components/helper.cljc
src/cljc/lernmeister/components/helper.cljc
+5
-0
src/cljs/lernmeister/components/exercise_types/calculation/views/edit.cljs
...ter/components/exercise_types/calculation/views/edit.cljs
+1
-1
src/cljs/lernmeister/components/exercise_types/calculation/views/helper.cljs
...r/components/exercise_types/calculation/views/helper.cljs
+0
-158
src/cljs/lernmeister/components/exercise_types/calculation/views/show.cljs
...ter/components/exercise_types/calculation/views/show.cljs
+3
-3
src/cljs/lernmeister/components/exercise_types/calculation/views/unit_input.cljs
...mponents/exercise_types/calculation/views/unit_input.cljs
+0
-168
src/cljs/lernmeister/components/exercise_types/calculation/views/value_input.cljs
...ponents/exercise_types/calculation/views/value_input.cljs
+0
-86
test/cljc/lernmeister/components/exercise_types/calculation/checker_test.cljc
...r/components/exercise_types/calculation/checker_test.cljc
+228
-215
test/cljc/lernmeister/components/exercise_types/calculation/migrater_test.cljc
.../components/exercise_types/calculation/migrater_test.cljc
+10
-10
No files found.
src/cljc/lernmeister/components/exercise_types/calculation/check.cljc
View file @
02a3dea7
(
ns
lernmeister.components.exercise-types.calculation.check
(
:require
[
clojure.string
:as
string
]
(
:require
[
lernmeister.components.exercise-types.calculation.migrate-answer
:refer
[
answer-scheme-version
migrate-answer
]]
[
lernmeister.components.exercise-types.check
:as
e-check
]
[
clojure.tools.reader.edn
:as
edn
]
[
lernmeister.components.helper
:refer
[
math-abs
]]))
(
def
prefix-mapping
{
"Y"
24
"Z"
21
"E"
18
"P"
15
"T"
12
"G"
9
"M"
6
"k"
3
"h"
2
"d"
-1
"c"
-2
"m"
-3
"µ"
-6
"n"
-9
"p"
-12
"f"
-15
"a"
-18
"z"
-21
"y"
-24
""
0
nil
0
})
(
def
si-unit-mapping
{
"m"
[{
:factor
1
:oom
0
:unit
"m"
:expo
1
}]
"g"
[{
:factor
1
:oom
-3
:unit
"kg"
:expo
1
}]
"s"
[{
:factor
1
:oom
0
:unit
"s"
:expo
1
}]
"A"
[{
:factor
1
:oom
0
:unit
"A"
:expo
1
}]
"K"
[{
:factor
1
:oom
0
:unit
"K"
:expo
1
}]
"mol"
[{
:factor
1
:oom
0
:unit
"mol"
:expo
1
}]
"cd"
[{
:factor
1
:oom
0
:unit
"cd"
:expo
1
}]
"rad"
[]
"sr"
[]
"Hz"
[{
:factor
1
:oom
0
:unit
"s"
:expo
-1
}]
"N"
[{
:factor
1
:oom
0
:unit
"m"
:expo
1
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-2
}]
"Pa"
[{
:factor
1
:oom
0
:unit
"m"
:expo
-1
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-2
}]
"J"
[{
:factor
1
:oom
0
:unit
"m"
:expo
2
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-2
}]
"W"
[{
:factor
1
:oom
0
:unit
"m"
:expo
2
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-3
}]
"C"
[{
:factor
1
:oom
0
:unit
"s"
:expo
1
}
{
:factor
1
:oom
0
:unit
"A"
:expo
1
}]
"V"
[{
:factor
1
:oom
0
:unit
"m"
:expo
2
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-3
}
{
:factor
1
:oom
0
:unit
"A"
:expo
-1
}]
"F"
[{
:factor
1
:oom
0
:unit
"m"
:expo
-2
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
-1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
4
}
{
:factor
1
:oom
0
:unit
"A"
:expo
2
}]
"Ω"
[{
:factor
1
:oom
0
:unit
"m"
:expo
2
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-3
}
{
:factor
1
:oom
0
:unit
"A"
:expo
-2
}]
"S"
[{
:factor
1
:oom
0
:unit
"m"
:expo
-2
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
-1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
3
}
{
:factor
1
:oom
0
:unit
"A"
:expo
2
}]
"Wb"
[{
:factor
1
:oom
0
:unit
"m"
:expo
2
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-2
}
{
:factor
1
:oom
0
:unit
"A"
:expo
-2
}]
"T"
[{
:factor
1
:oom
0
:unit
"kg"
:expo
1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-2
}
{
:factor
1
:oom
0
:unit
"A"
:expo
-1
}]
"H"
[{
:factor
1
:oom
0
:unit
"m"
:expo
2
}
{
:factor
1
:oom
0
:unit
"kg"
:expo
1
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-2
}
{
:factor
1
:oom
0
:unit
"A"
:expo
-2
}]
"lm"
[{
:factor
1
:oom
0
:unit
"cd"
:expo
1
}]
"lx"
[{
:factor
1
:oom
0
:unit
"m"
:expo
-2
}
{
:factor
1
:oom
0
:unit
"cd"
:expo
1
}]
"Bq"
[{
:factor
1
:oom
0
:unit
"s"
:expo
-1
}]
"Gy"
[{
:factor
1
:oom
0
:unit
"m"
:expo
2
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-2
}]
"Sv"
[{
:factor
1
:oom
0
:unit
"m"
:expo
2
}
{
:factor
1
:oom
0
:unit
"s"
:expo
-2
}]
"kat"
[{
:factor
1
:oom
0
:unit
"s"
:expo
-1
}
{
:factor
1
:oom
0
:unit
"mol"
:expo
1
}]
"h"
[{
:factor
3.6
:oom
3
:unit
"s"
:expo
1
}]
"d"
[{
:factor
8.64
:oom
4
:unit
"s"
:expo
1
}]
"l"
[{
:factor
1
:oom
-1
:unit
"m"
:expo
3
}]})
(
def
additional-unit-mappings
{
"B"
[{
:factor
1
:oom
1
:unit
"dB"
:expo
1
}]
"°"
[{
:factor
1
:oom
0
:unit
"°"
:expo
1
}]})
(
def
base-unit-set
#
{
"m"
"kg"
"s"
"A"
"K"
"mol"
"cd"
"dB"
"°"
})
(
def
unit-replace-map
{
"kg"
{
:unit
"g"
:prefix
"k"
}
"dB"
{
:unit
"B"
:prefix
"d"
}})
(
def
unit-replace-set
(
set
(
keys
unit-replace-map
)))
(
def
base-unit-map
(
reduce
(
fn
[
res-map
base-unit
]
(
assoc
res-map
(
keyword
base-unit
)
0
))
{}
base-unit-set
))
(
def
unit-mapping
(
merge
si-unit-mapping
additional-unit-mappings
))
(
def
prefix-set
(
set
(
keys
prefix-mapping
)))
(
def
unit-set
(
set
(
keys
unit-mapping
)))
(
defn
not-empty-or-minus
[
number
]
((
every-pred
#
((
complement
empty?
)
%
)
#
(
not=
"-"
%
))
number
))
(
defn
get-number-part
[{
:keys
[
number
order-of-magnitude
]}
with-oom
target
result
]
(
when
(
not-empty-or-minus
number
)
(
let
[
parsed-number
(
edn/read-string
(
string/replace
number
","
"."
))]
(
if
with-oom
(
when
(
not-empty-or-minus
order-of-magnitude
)
(
let
[
parsed-oom
(
edn/read-string
order-of-magnitude
)]
(
assoc
result
target
{
:number
parsed-number
:oom
parsed-oom
})))
(
assoc
result
target
{
:number
parsed-number
:oom
0
})))))
(
defn
reduce-to-base-units
[
outer-multiplier
result
base-unit
]
(
let
[
multiplier
(
*
outer-multiplier
(
:expo
base-unit
))
unit-key
(
keyword
(
:unit
base-unit
))
unit-factor
(
:factor
base-unit
)
unit-oom
(
:oom
base-unit
)]
(
->
result
(
update
unit-key
+
multiplier
)
(
update
:factor
*
(
Math/pow
unit-factor
multiplier
))
(
update
:oom
+
(
*
multiplier
unit-oom
)))))
(
defn
reduce-unit-mapping
[
result-map
unit
]
(
let
[
parsed-expo
(
edn/read-string
(
:expo
unit
))
prefix-oom
(
get
prefix-mapping
(
:prefix
unit
))
calculated-oom
(
*
parsed-expo
prefix-oom
)]
(
let
[
reduce-fn
(
fn
[
result
base-unit
]
((
partial
reduce-to-base-units
parsed-expo
)
result
base-unit
))]
(
reduce
reduce-fn
(
update
result-map
:oom
+
calculated-oom
)
(
get
unit-mapping
(
:unit
unit
))))))
(
defn
reduce-units
[
units
]
(
let
[
result-map
(
merge
base-unit-map
{
:factor
1
:oom
0
})]
(
reduce
reduce-unit-mapping
result-map
units
)))
(
defn
get-units-part
[
units
with-units
target
result
]
(
if
with-units
(
let
[
reduced-units
(
reduce-units
units
)
base-units
(
select-keys
reduced-units
(
reduce
(
fn
[
res
base-unit
]
(
conj
res
(
keyword
base-unit
)))
[]
base-unit-set
))
units-factor
(
:factor
reduced-units
)
units-oom
(
:oom
reduced-units
)]
(
update
result
target
merge
{
:base-units
base-units
:units-factor
units-factor
:units-oom
units-oom
}))
result
))
(
defn
compare-base-units
[
with-units
result
]
(
if
with-units
(
let
[
calc-units
(
get-in
result
[
:calc
:base-units
])
ans-units
(
get-in
result
[
:ans
:base-units
])]
(
when
(
=
calc-units
ans-units
)
result
))
[
lernmeister.components.exercise-types.multistep-calculation.check
:refer
[
check-phys-vals
tolerable-error?
]]
[
lernmeister.components.helper
:refer
[
migrate-if-necessary
]]))
(
defn
get-calculation-ids
[
exercise
]
(
reduce
(
fn
[
res
item
]
(
conj
res
(
:id
item
)))
#
{}
(
get-in
exercise
[
:core
:calculations
])))
(
defn
no-negative-points
[
result
]
(
if
(
neg?
(
:points
result
))
(
assoc
result
:points
0
)
result
))
(
defn
compare-numbers
[
with-oom
with-units
error-factor
result
]
(
let
[
get-combined-number
(
fn
[
oom-key
]
(
let
[
number
(
get-in
result
[
oom-key
:number
])]
(
if
with-units
(
let
[
units-factor
(
get-in
result
[
oom-key
:units-factor
])]
(
*
number
units-factor
))
number
)))
get-combined-oom
(
fn
[
oom-key
]
(
let
[
units-oom
(
get-in
result
[
oom-key
:units-oom
]
0
)]
(
if
with-oom
(
let
[
oom
(
get-in
result
[
oom-key
:oom
])]
(
+
oom
units-oom
))
units-oom
)))]
(
let
[
calc-number
(
get-combined-number
:calc
)
ans-number
(
get-combined-number
:ans
)
calc-oom
(
get-combined-oom
:calc
)
ans-oom
(
get-combined-oom
:ans
)
oom-difference
(
-
calc-oom
ans-oom
)
calc-multiplier
(
Math/pow
10
oom-difference
)]
(
when
(
<=
(
math-abs
(
-
ans-number
(
*
calc-multiplier
calc-number
)))
(
math-abs
(
*
error-factor
ans-number
)))
true
))))
(
defn
check-answer
[
cur-calc
cur-ans
&
{
:keys
[
with-oom
with-units
]}]
(
let
[
error-factor
(
/
(
:error-relative
cur-calc
1
)
100
)]
;;is it okay to keep this as ratio-datatype?
(
some->>
{}
(
get-number-part
cur-calc
with-oom
:calc
)
(
get-number-part
cur-ans
with-oom
:ans
)
(
get-units-part
(
:units
cur-calc
)
with-units
:calc
)
(
get-units-part
(
:units
cur-ans
)
with-units
:ans
)
(
compare-base-units
with-units
)
(
compare-numbers
with-oom
with-units
error-factor
))))
(
defn
check-calculation
[
id
ans-obj
ex-obj
res-map
with-oom
with-units
]
(
let
[
phys-val-check-res
(
check-phys-vals
ex-obj
ans-obj
:with-oom
with-oom
:with-units
with-units
)
is-correct?
(
tolerable-error?
(
:calculation-error
phys-val-check-res
)
(
or
(
:error-relative
ex-obj
)
1
))]
(
assoc
res-map
id
{
:correct
is-correct?
:points
(
if
is-correct?
(
:correct-points
ex-obj
)
(
:incorrect-points
ex-obj
))
:points-max
(
:correct-points
ex-obj
)})))
(
defn
calculation-check
[
exercise
answer
callback
]
(
let
[
no-negative-points
(
fn
[
result
]
(
if
(
neg?
(
:points
result
))
(
assoc
result
:points
0
)
result
))]
(
let
[
core
(
:core
exercise
)
calculations
(
:calculations
core
)
with-oom
(
:with-oom
core
)
with-units
(
:with-units
core
)]
(
callback
)
(
->>
(
map
(
fn
[
calculation
]
(
let
[
cur-correct-points
(
:correct-points
calculation
)
cur-incorrect-points
(
:incorrect-points
calculation
)
cur-id
(
:id
calculation
)
cur-answer
(
get
answer
cur-id
)]
(
if
(
and
cur-answer
(
check-answer
calculation
cur-answer
:with-oom
with-oom
:with-units
with-units
))
{
:points
cur-correct-points
:points-max
cur-correct-points
:correct-id
cur-id
}
{
:points
cur-incorrect-points
:points-max
cur-correct-points
})))
calculations
)
(
reduce
(
fn
[
result
cur-result
]
(
let
[
update-correct-calculations
(
fn
[
result
]
(
if
(
contains?
cur-result
:correct-id
)
(
update
result
:correct-calculations
conj
(
:correct-id
cur-result
))
result
))]
(
->
result
(
update
:points
+
(
:points
cur-result
))
(
update
:points-max
+
(
:points-max
cur-result
))
update-correct-calculations
)))
{
:points
0
:points-max
0
:correct-calculations
#
{}})
no-negative-points
))))
(
let
[
answer-calculations
(
:calculations
answer
)
calculations
(
get-in
exercise
[
:core
:calculations
])
with-oom
(
get-in
exercise
[
:core
:with-oom
])
with-units
(
get-in
exercise
[
:core
:with-units
])
res-map
(
reduce
(
fn
[
r-map
calculation
]
(
let
[
id
(
:id
calculation
)
answer
(
get
answer-calculations
id
)]
(
check-calculation
id
answer
calculation
r-map
with-oom
with-units
)))
{}
calculations
)
update-correct-calcs
(
fn
[
result
id
calculation-check
]
(
if
(
:correct
calculation-check
)
(
update
result
:correct-calculations
conj
id
)
result
))]
(
callback
)
(
->>
res-map
(
reduce-kv
(
fn
[
result
k
v
]
(
->
result
(
update
:points
+
(
:points
v
))
(
update
:points-max
+
(
:points-max
v
))
(
update-correct-calcs
k
v
)))
{
:points
0
:points-max
0
:correct-calculations
#
{}})
no-negative-points
)))
(
defmethod
e-check/check-answer
:calculation
[
exercise
answer
callback
]
(
calculation-check
exercise
answer
callback
))
(
let
[
calculation-ids
(
get-calculation-ids
exercise
)
migrated-answer
(
migrate-if-necessary
answer
:answer-scheme
"calculation"
answer-scheme-version
(
partial
migrate-answer
calculation-ids
))]
(
calculation-check
exercise
migrated-answer
callback
)))
src/cljc/lernmeister/components/exercise_types/calculation/migrate.cljc
View file @
02a3dea7
...
...
@@ -11,7 +11,7 @@
(
partial
modify-exercise-field-vec
exercise
[
:core
:calculations
]))
(
defn
set-missing-error-relative
[
exercise
]
((
modify-calculations
exercise
)
#
(
assoc
%
:error-relative
(
or
(
:error-relative
%
)
"1"
))))
((
modify-calculations
exercise
)
#
(
assoc
%
:error-relative
(
or
(
:error-relative
%
)
1
))))
(
defn
convert-numbers
[
exercise
]
((
modify-calculations
exercise
)
convert-number-to-object
))
...
...
src/cljc/lernmeister/components/exercise_types/calculation/migrate_answer.cljc
View file @
02a3dea7
...
...
@@ -9,9 +9,6 @@
(
defn
set-current-scheme
[
answer
]
(
assoc
answer
:answer-scheme
{
:type
"calculation"
:version
answer-scheme-version
}))
(
defn
remove-ooms
[
answer
]
(
update
answer
:calculations
(
fn
[
calcs
]
(
migrate-object
#
(
dissoc
%
:order-of-magnitude
)
calcs
))))
(
defn
convert-calculation-numbers
[
answer
]
(
update
answer
:calculations
(
fn
[
calcs
]
(
migrate-object
convert-number-to-object
calcs
))))
...
...
@@ -32,5 +29,4 @@
wrap-answer-calculations
(
add-missing-calculation-objects
calculation-ids
)
convert-calculation-numbers
remove-ooms
set-current-scheme
))
src/cljc/lernmeister/components/exercise_types/calculation/spec.cljc
View file @
02a3dea7
(
ns
lernmeister.components.exercise-types.calculation.spec
(
:require
#
?
(
:cljs
[
cljs.spec.alpha
:as
s
]
:clj
[
clojure.spec.alpha
:as
s
])
[
lernmeister.components.exercise-types.calculation.check
:refer
[
prefix-set
unit-set
]]))
[
lernmeister.components.exercise-types.
multistep-
calculation.check
:refer
[
prefix-set
unit-set
]]))
(
s/def
:calculation/name
(
s/and
string?
#
(
not
(
empty?
%
))))
(
s/def
:calculation/number
(
s/and
string?
#
(
re-matches
#
"^\-?((((0\,)|([1-9]\d*\,?))\d*)|0)$"
%
)))
...
...
@@ -27,4 +27,3 @@
:exercise/task-description
:exercise/shuffled
]))
(
s/def
::calculation-question
(
s/keys
:req-un
[
:calculation-question/core
]))
src/cljc/lernmeister/components/exercise_types/multistep_calculation/check.cljc
View file @
02a3dea7
...
...
@@ -12,7 +12,7 @@
[
answer-scheme-version
migrate-answer
]]
[
lernmeister.components.helper
:refer
[
math-abs
migrate-if-necessary
]])]
[
double-division
math-abs
migrate-if-necessary
]])]
:cljs
[(
:require
[
clojure.string
:as
clj-str
:refer
[
join
split
trim
]]
...
...
@@ -23,7 +23,7 @@
[
answer-scheme-version
migrate-answer
]]
[
lernmeister.components.helper
:refer
[
math-abs
migrate-if-necessary
]])]))
[
double-division
math-abs
migrate-if-necessary
]])]))
(
def
prefix-mapping
{
"Y"
24
"Z"
21
...
...
@@ -169,10 +169,14 @@
:factor
(
:factor
based-units-map
)
:oom
(
:oom
based-units-map
)}))
(
defn
tolerable-error?
[
calculation-error
error-relative
]
(
when
(
every?
#
(
and
(
number?
%
)
(
not
(
neg?
%
)))
[
calculation-error
error-relative
])
(
<=
(
*
calculation-error
100
)
error-relative
)))
(
defn
convert-phys-val-to-ref-units
[
phys-val
ref-units
]
(
let
[
phys-val-base-unit-map
(
units-to-baseunits
(
:units
phys-val
))
ref-base-unit-map
(
units-to-baseunits
ref-units
)
convert-factor
(
/
(
:factor
phys-val-base-unit-map
)
(
:factor
ref-base-unit-map
))
convert-factor
(
double-division
(
:factor
phys-val-base-unit-map
)
(
:factor
ref-base-unit-map
))
convert-oom
(
-
(
:oom
phys-val-base-unit-map
)
(
:oom
ref-base-unit-map
))
significand
(
edn/read-string
(
get-in
phys-val
[
:number
:significand
]))
oom
(
edn/read-string
(
get-in
phys-val
[
:number
:order-of-magnitude
]))]
...
...
@@ -294,14 +298,13 @@
ans-significand
(
get-combined-significand
:ans
)
calc-oom
(
get-combined-oom
:calc
)
ans-oom
(
get-combined-oom
:ans
)
oom-difference
(
-
calc-oom
ans-oom
)
calc-multiplier
(
Math/pow
10
oom-difference
)]
(
when
(
<=
(
math-abs
(
-
ans-significand
(
*
calc-multiplier
calc-significand
)))
(
math-abs
(
*
(
/
1
100
)
ans-significand
)))
true
)))
(
defn
check-answer
[
cur-calc
cur-ans
&
{
:keys
[
with-oom
with-units
]}]
oom-difference
(
-
ans-oom
calc-oom
)
ans-multiplier
(
Math/pow
10
oom-difference
)]
(
assoc
result
:calculation-error
(
math-abs
(
double-division
(
-
calc-significand
(
*
ans-significand
ans-multiplier
))
calc-significand
)))))
(
defn
check-phys-vals
[
cur-calc
cur-ans
&
{
:keys
[
with-oom
with-units
]}]
(
some->>
{}
(
get-number-part
cur-calc
with-oom
:calc
)
(
get-number-part
cur-ans
with-oom
:ans
)
...
...
@@ -368,12 +371,13 @@
(
defmethod
check-step
:constant
[
_
{
:keys
[
ans-id
ans-obj
ex-obj
assignment
res-map
]}]
(
let
[
update-res-map
(
fn
[
points
]
(
assoc
res-map
ans-id
{
:points
points
:points-max
4
}))]
(
if
(
and
(
get-in
ans-obj
[
:number
:significand
])
(
check-answer
{
:number
(
:number
ex-obj
)
:units
(
:units
assignment
)}
(
select-keys
ans-obj
[
:number
:units
])
:with-oom
true
:with-units
true
))
(
update-res-map
4
)
(
if
(
get-in
ans-obj
[
:number
:significand
])
(
let
[
phys-val-check-res
(
check-phys-vals
{
:number
(
:number
ex-obj
)
:units
(
:units
assignment
)}
(
select-keys
ans-obj
[
:number
:units
])
:with-oom
true
:with-units
true
)]
(
if
(
tolerable-error?
(
:calculation-error
phys-val-check-res
)
1
)
(
update-res-map
4
)
(
update-res-map
2
)))
(
update-res-map
2
))))
(
defmethod
check-step
:formula
[
_
{
:keys
[
ans-id
ans-obj
ex-obj
assignment
param-id-map
ex-id-map
...
...
@@ -389,11 +393,11 @@
(
if-not
(
some
(
comp
nil?
val
)
match-var-map
)
(
let
[
calc-mapping
(
:calc-mapping
assignment
)
formula-vec
(
formula-to-vec
(
:formula
assignment
))
calc-number
(
mathjs-str-to-number-obj
(
calc-step
formula-vec
calc-mapping
match-var-map
))
]
(
if
(
check-answer
{
:number
calc-number
:units
(
:units
assignment
)}
(
select-keys
ans-obj
[
:number
:units
])
:with-oom
true
:with-units
true
)
calc-number
(
mathjs-str-to-number-obj
(
calc-step
formula-vec
calc-mapping
match-var-map
))
phys-val-check-res
(
check-phys-vals
{
:number
calc-number
:units
(
:units
assignment
)}
(
select-keys
ans-obj
[
:number
:units
])
:with-oom
true
:with-units
true
)]
(
if
(
tolerable-error?
(
:calculation-error
phys-val-check-res
)
1
)
(
update-res-map
6
)
(
update-res-map
4
)))
(
update-res-map
2
))))
...
...
src/cljc/lernmeister/components/exercise_types/multistep_calculation/migrate.cljc
View file @
02a3dea7
(
ns
lernmeister.components.exercise-types.multistep-calculation.migrate
(
:require
[
clojure.tools.reader.edn
:as
edn
]
(
:require
[
clojure.string
:as
string
]
[
clojure.tools.reader.edn
:as
edn
]
[
lernmeister.components.helper
:refer
[
find-in-vec-by-id
]]))
(
def
exercise-scheme-version
"2019-11-22"
)
...
...
@@ -9,6 +10,11 @@
(
assoc-in
[
:authoring
:migration-status
]
:current
)
(
assoc
:exercise-scheme
{
:type
type
:version
version
})))
(
defn
normalize-decimal-separator
[
number-string
]
(
if
(
string?
number-string
)
(
string/replace
number-string
#
","
"."
)
number-string
))
(
defn
migrate-object
[
migrate-fn
obj
]
(
reduce-kv
(
fn
[
res-obj
obj-k
obj-v
]
(
assoc
res-obj
obj-k
(
migrate-fn
obj-v
)))
{}
obj
))
...
...
@@ -26,7 +32,7 @@
(
defn
convert-number-obj
[
obj
]
(
if
(
contains?
obj
:number
)
(
let
[
significand
(
:number
obj
)
(
let
[
significand
(
normalize-decimal-separator
(
:number
obj
)
)
order-of-magnitude
(
or
(
:order-of-magnitude
obj
)
"0"
)]
{
:significand
significand
:order-of-magnitude
order-of-magnitude
})
obj
))
...
...
@@ -34,7 +40,7 @@
(
defn
convert-number-to-object
[
obj
]
(
if
(
contains?
obj
:number
)
(
if-not
(
map?
(
:number
obj
))
(
let
[
significand
(
:number
obj
)
(
let
[
significand
(
normalize-decimal-separator
(
:number
obj
)
)
order-of-magnitude
(
or
(
:order-of-magnitude
obj
)
"0"
)]
(
->
obj
(
dissoc
:order-of-magnitude
)
...
...
src/cljc/lernmeister/components/helper.cljc
View file @
02a3dea7
...
...
@@ -11,6 +11,11 @@
:cljs
(
js/console.debug
message
)))
(
defn
double-division
"returns double-value in any case"
[
divident
divisor
]
(
/
(
double
divident
)
divisor
))
(
defn
math-abs
"returns math-abs-val for clj&cljs"
[
value
]
...
...
src/cljs/lernmeister/components/exercise_types/calculation/views/edit.cljs
View file @
02a3dea7
...
...
@@ -28,7 +28,7 @@
:number
{
:significand
nil
:order-of-magnitude
"0"
}
:correct-points
0
:incorrect-points
0
:error-relative
"1"
})
:error-relative
1
})
(
defn
set-prop-in-all-calcs
[
prop-key
value
calc-cursor
]
(
dorun
(
map-indexed
...
...
src/cljs/lernmeister/components/exercise_types/calculation/views/helper.cljs
deleted
100644 → 0
View file @
6dd5cae3
(
ns
lernmeister.components.exercise-types.calculation.views.helper
(
:require
[
clojure.string
:refer
[
trim
replace
join
]]
[
lernmeister.components.exercise-types.calculation.check
:refer
[
prefix-mapping
prefix-set
unit-set
not-empty-or-minus
]]
[
reagent.core
:as
reagent
]
[
reagent.dom
:as
rdom
]
[
lernmeister.components.ui
:as
ui
]
[
lernmeister.components.helper
:refer
[
vec-remove
]]))
(
defn
parse-unit
[
string
]
(
when
(
string?
string
)
(
when-let
[
matched-string
(
re-matches
#
"^[a-zA-ZΩ°]*"
string
)]
(
replace
(
subs
matched-string
0
3
)
#
"Ohm|ohm"
"Ω"
))))
(
defn
parse-prefix
[
string
]
(
when
(
string?
string
)
(
when-let
[
replaced-string
(
replace
string
"u"
"µ"
)]
(
let
[
last-char
(
or
(
last
replaced-string
)
""
)]
(
when
(
contains?
prefix-set
last-char
)
last-char
)))))
(
defn
parse-float
[
string
]
(
when
(
string?
string
)
(
when-let
[[
match
sign
int-part
float-part
]
(
re-matches
#
"^(\-?)(\d*)([\.|,]?\d*)$"
string
)]
(
if-let
[[
match
stripped-int-part
]
(
re-matches
#
"^0*(\d+)$"
int-part
)]
(
str
sign
stripped-int-part
(
replace
float-part
"."
","
))
(
if
(
=
float-part
""
)
sign
(
str
sign
"0"
(
replace
float-part
"."
","
)))))))
(
defn
parse-int
[
string
]
(
when
(
string?
string
)
(
when-let
[[
match
sign
int-part
]
(
re-matches
#
"^(\-?)(\d*)$"
string
)]
(
if-let
[[
match
stripped-int-part
]
(
re-matches
#
"^0*(\d+)$"
int-part
)]
(
str
sign
stripped-int-part
)
(
str
sign
)))))
(
defn
append-to-string-vec
[
arg
append-string
]
(
update
arg
:string-vec
conj
append-string
))
(
defn
add-number
[
arg
]
(
let
[
number
(
:number
arg
)]
(
when
(
not-empty-or-minus
number
)
(
if
(
re-matches
#
"^\-?0,?0*$"
number
)
(
->
arg
(
assoc
:number
"0"
)
(
append-to-string-vec
"0"
))
(
append-to-string-vec
arg
(
->
number
(
replace
#
",$"
""
)
(
replace
","
"{,}"
)))))))
(
defn
add-oom
[
arg
]
(
let
[
number
(
:number
arg
)
oom
(
:order-of-magnitude
arg
)
with-oom
(
:with-oom
arg
)]
(
if
with-oom
(
when
(
not-empty-or-minus
oom
)
(
letfn
[(
build-oom-string
[
oom
number
]
(
if
(
or
(
=
"0"
number
)
(
re-matches
#
"^\-?0?$"
oom
))
""
(
str
"\\cdot 10^{"
oom
"}"
)))]
(
append-to-string-vec
arg
(
build-oom-string
oom
number
))))
(
append-to-string-vec
arg
""
))))
(
defn
append-unit-str
[
frac-map
position
unit
expo
]
(
update
frac-map
position
conj
(
if
(
=
"1"
expo
)
unit
(
str
unit
"^{"
expo
"}"
))))
(
defn
join-with-sep
[
fraction-map
map-key
]
(
join
"{\\cdot}"
(
map-key
fraction-map
)))
(
defn
latex-replace-unit
[
unit
]
(
->
unit
(
replace
"Ω"
"\\Omega "
)