Export des notes sous forme de tableau OrgMode

pull/1/head
Jean-Christophe Jameux 4 years ago
parent d5316f40e2
commit 9afce0fef2
  1. BIN
      elm-stuff/0.19.1/CalculateurDeNotes.elmi
  2. BIN
      elm-stuff/0.19.1/CalculateurDeNotes.elmo
  3. BIN
      elm-stuff/0.19.1/d.dat
  4. BIN
      elm-stuff/0.19.1/i.dat
  5. 2
      elm.json
  6. 317
      src/CalculateurDeNotes.elm
  7. 168
      src/Fraction.elm
  8. 545
      src/GenerateurDeProblemes.elm
  9. 30
      src/ParserMaths.elm
  10. 43
      src/Test.elm

Binary file not shown.

Binary file not shown.

@ -8,6 +8,7 @@
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/file": "1.0.5",
"elm/html": "1.0.0",
"elm/parser": "1.1.0",
"elm/random": "1.0.0",
@ -21,7 +22,6 @@
"Janiczek/elm-bidict": "2.0.1",
"andre-dietrich/parser-combinators": "3.2.0",
"elm/bytes": "1.0.8",
"elm/file": "1.0.5",
"elm/http": "2.0.0",
"elm/json": "1.1.3",
"elm/regex": "1.0.0",

@ -1,12 +1,13 @@
module CalculateurDeNotes exposing (..)
import Array exposing (..)
import Browser
import Html exposing (Html)
import Element exposing (..)
import Element.Input as Input
import Set
import Array exposing (..)
import File.Download
import Html exposing (Html)
import Parser exposing (..)
import Set
@ -18,6 +19,7 @@ import Parser exposing (..)
-}
main =
Browser.element
{ init = init
@ -36,6 +38,7 @@ main =
-}
type alias Model =
{ bareme : String
, reponsesCorrectes : String
@ -43,6 +46,7 @@ type alias Model =
, eleves : Eleves
}
init : () -> ( Model, Cmd Msg )
init _ =
( { bareme = ""
@ -63,23 +67,31 @@ init _ =
-}
type Msg
= NouveauBareme String
| NouvellesReponsesCorrectes String
| NouvellesReponsesEleves String
-- | CalculerNotes
| TelechargerNotes
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
let
brms = unsafeRun baremeSujet [] model.bareme
rpnCorrectes = unsafeRun reponsesCorrectes Array.empty model.reponsesCorrectes
rpnEleves = unsafeRun reponsesEleves [] model.reponsesEleves
brms =
unsafeRun baremeSujet [] model.bareme
rpnCorrectes =
unsafeRun reponsesCorrectes Array.empty model.reponsesCorrectes
rpnEleves =
unsafeRun reponsesEleves [] model.reponsesEleves
in
case msg of
NouveauBareme nouveauBareme ->
let
brmss = unsafeRun baremeSujet [] nouveauBareme
brmss =
unsafeRun baremeSujet [] nouveauBareme
in
( { model
| bareme = nouveauBareme
@ -87,9 +99,11 @@ update msg model =
}
, Cmd.none
)
NouvellesReponsesCorrectes nouvellesReponsesCorrectes ->
let
rpnCorrectess = unsafeRun reponsesCorrectes Array.empty nouvellesReponsesCorrectes
rpnCorrectess =
unsafeRun reponsesCorrectes Array.empty nouvellesReponsesCorrectes
in
( { model
| reponsesCorrectes = nouvellesReponsesCorrectes
@ -97,9 +111,11 @@ update msg model =
}
, Cmd.none
)
NouvellesReponsesEleves nouvellesReponsesEleves ->
let
rpnElevess = unsafeRun reponsesEleves [] nouvellesReponsesEleves
rpnElevess =
unsafeRun reponsesEleves [] nouvellesReponsesEleves
in
( { model
| reponsesEleves = nouvellesReponsesEleves
@ -108,19 +124,31 @@ update msg model =
, Cmd.none
)
TelechargerNotes ->
( model
, File.Download.string "Notes.org" "text/org" <| voirNotesOrg model.eleves
)
unsafeRun prsr defaut texte =
case run prsr texte of
Ok x -> x
_ -> defaut
Ok x ->
x
_ ->
defaut
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
{-
@ -130,18 +158,32 @@ subscriptions model =
-}
view : Model -> Html Msg
view model =
layout [ width fill, height fill ] <|
row [spacing grandEspacement, padding tresGrandEspacement, height fill, width fill, clip, scrollbars]
[ column [spacing petitEspacement, height fill, width fill, clip, scrollbars]
row
[ spacing grandEspacement
, padding tresGrandEspacement
, height fill
, width fill
, clip
, scrollbars
]
[ column
[ spacing petitEspacement
, height fill
, width fill
, clip
, scrollbars
]
[ Input.multiline [ height <| maximum 300 fill, clip, scrollbars ]
{ onChange = NouveauBareme
, label = Input.labelAbove [] <| text "Barème"
, placeholder =
Just
<| Input.placeholder []
<| text "Entrer le barème sous la forme +3 -1, +2 -1"
Just <|
Input.placeholder [] <|
text "Entrer le barème sous la forme +3 -1, +2 -1"
, text = model.bareme
, spellcheck = False
}
@ -149,9 +191,9 @@ view model =
{ onChange = NouvellesReponsesCorrectes
, label = Input.labelAbove [] <| text "Réponses correctes"
, placeholder =
Just
<| Input.placeholder []
<| text "Entrer les réponses correctes pour chaque sujet"
Just <|
Input.placeholder [] <|
text "Entrer les réponses correctes pour chaque sujet"
, text = model.reponsesCorrectes
, spellcheck = False
}
@ -159,26 +201,28 @@ view model =
{ onChange = NouvellesReponsesEleves
, label = Input.labelAbove [] <| text "Réponses des élèves"
, placeholder =
Just
<| Input.placeholder []
<| text "Entrer les réponses des élèves"
Just <|
Input.placeholder [] <|
text "Entrer les réponses des élèves"
, text = model.reponsesEleves
, spellcheck = False
}
]
, column [ spacing petitEspacement, height fill, width fill ]
[ {-- Input.button []
{ onPress = Just CalculerNotes
, label = text "Calculer les notes"
[ text <|
"Moyenne : "
++ String.fromFloat (moyenne model.eleves)
++ " Écart type : "
++ String.fromFloat (ecartType model.eleves)
, Input.button []
{ onPress = Just TelechargerNotes
, label = text "Télécharger le fichier de notes"
}
--}
text
<| "Moyenne : " ++ String.fromFloat (moyenne model.eleves)
++ " Écart type : " ++ String.fromFloat (ecartType model.eleves)
, voirNotes model.eleves
]
]
voirNotes : Eleves -> Element Msg
voirNotes rpnsEleves =
table []
@ -195,17 +239,57 @@ voirNotes rpnsEleves =
, view =
\rpns ->
case rpns.note of
Nothing -> Element.text ""
Just nt -> Element.text <| String.fromFloat nt
Nothing ->
Element.text ""
Just nt ->
Element.text <| String.fromFloat nt
}
]
}
petitEspacement = 20
grandEspacement = 5*petitEspacement // 4
voirNotesOrg : Eleves -> String
voirNotesOrg rpnsEleves =
let
numero rpns =
rpns.numeroEtudiant
voirNote rpns =
case rpns.note of
Nothing ->
""
Just nt ->
String.fromFloat nt
ligne rpns =
"|"
++ rpns.numeroEtudiant
++ "|"
++ rpns.nomEtudiant
++ "|"
++ rpns.prenomEtudiant
++ "|"
++ voirNote rpns
++ "|\n"
in
"|Numéro|Nom|Prénom|Note|\n"
++ String.concat (List.map ligne rpnsEleves)
petitEspacement =
20
grandEspacement =
5 * petitEspacement // 4
tresGrandEspacement =
25 * petitEspacement // 16
tresGrandEspacement = 25*petitEspacement // 16
{-
@ -214,8 +298,6 @@ tresGrandEspacement = 25*petitEspacement // 16
-}
{--
baremeEtReponses =
succeed (\brm rpn -> BaremeEtReponses brm (List.map (String.split "") rpn))
@ -224,7 +306,9 @@ baremeEtReponses =
--}
type alias BaremeSujet = List BaremeQuestion
type alias BaremeSujet =
List BaremeQuestion
baremeSujet =
sequence
@ -236,6 +320,7 @@ baremeSujet =
, trailing = Forbidden
}
espaces =
chompWhile <| (==) ' '
@ -245,12 +330,14 @@ type alias BaremeQuestion =
, mauvaiseReponse : Float
}
baremeQuestion =
succeed BaremeQuestion
|= nombre
|. spaces
|= nombre
nombre : Parser Float
nombre =
oneOf
@ -262,6 +349,8 @@ nombre =
|= float
]
{-
@ -269,7 +358,11 @@ nombre =
-}
type alias ReponsesCorrectes = Array Reponses
type alias ReponsesCorrectes =
Array Reponses
reponsesCorrectes : Parser ReponsesCorrectes
reponsesCorrectes =
@ -284,7 +377,9 @@ reponsesCorrectes =
}
type alias Reponses = List String
type alias Reponses =
List String
reponses =
sequence
@ -292,8 +387,9 @@ reponses =
, separator = ""
, end = ""
, spaces = espaces
, item = variable
{ start = ( \ x -> x /= '\n' && x /= ';' )
, item =
variable
{ start = \x -> x /= '\n' && x /= ';'
, inner = \_ -> False
, reserved = Set.fromList []
}
@ -301,7 +397,9 @@ reponses =
}
type alias Eleves = List Eleve
type alias Eleves =
List Eleve
reponsesEleves : Parser Eleves
reponsesEleves =
@ -328,116 +426,181 @@ reponsesEleves =
type alias Eleve =
{ numeroEtudiant : String
, numeroSujet : Int
, nomEtudiant : String
, prenomEtudiant : String
, reponses : Reponses
, note : Maybe Float
}
reponsesEleve =
succeed Eleve
|= etudiant
|= int
|. champzInteret
|. champzInteret
|= champ
|= champ
|= reponsesQuizScan
|= champzInteret
etudiant =
getChompedString
<| chompIf Char.isDigit
getChompedString <|
chompIf Char.isDigit
|. chompIf Char.isDigit
|. chompIf Char.isDigit
|. chompIf Char.isDigit
|. chompIf Char.isDigit
champ =
succeed identity
|. symbol ";"
|= getChompedString (chompWhile ((/=) ';'))
champzInteret =
succeed Nothing
|. symbol ";"
|. chompWhile (\x -> x /= '\n' && x /= ';')
reponsesQuizScan =
sequence
{ start = ";"
, separator = ";"
, end = ""
, spaces = espaces
, item = variable
{ start = ( \ x -> x /= '\n' && x /= ';' )
, item =
variable
{ start = \x -> x /= '\n' && x /= ';'
, inner = \_ -> False
, reserved = Set.fromList []
}
, trailing = Mandatory
}
notes : BaremeSujet -> ReponsesCorrectes -> Eleves -> Eleves
notes brms rpnCorrectes rpnEleves =
let
f rpnEleve =
case Array.get (rpnEleve.numeroSujet - 11) rpnCorrectes of
Nothing -> rpnEleve
Nothing ->
rpnEleve
Just bonneRpns ->
{ rpnEleve | note = noteSujet brms bonneRpns rpnEleve.reponses }
in
List.map f rpnEleves
noteSujet : BaremeSujet -> Reponses -> Reponses -> Maybe Float
noteSujet brms bonneRpns rpnsEleve =
case brms of
[] -> Just 0
[] ->
Just 0
brm :: brmss ->
let
bonneRpn = List.head bonneRpns
bonneRpnSuite = List.tail bonneRpns
rpnEleve = List.head rpnsEleve
rpnEleveSuite = List.tail rpnsEleve
bonneRpn =
List.head bonneRpns
bonneRpnSuite =
List.tail bonneRpns
rpnEleve =
List.head rpnsEleve
rpnEleveSuite =
List.tail rpnsEleve
in
case ( ( bonneRpn, bonneRpnSuite ), ( rpnEleve, rpnEleveSuite ) ) of
( ( Just bnRpn, Just bnRpnSuite ), ( Just rpnElv, Just rpnElvSuite ) ) ->
noteSujet brmss bnRpnSuite rpnElvSuite
|> Maybe.andThen (Just << (+) (noteQuestion brm bnRpn rpnElv))
_ -> Nothing
_ ->
Nothing
noteQuestion brm bonneRpn rpnEleve =
case bonneRpn of
"V" ->
if rpnEleve == "A" then brm.bonneReponse
else if rpnEleve == "B" then 2*brm.bonneReponse/3
else if rpnEleve == "C" then brm.mauvaiseReponse/3
else if rpnEleve == "D" then brm.mauvaiseReponse
else 0
if rpnEleve == "A" then
brm.bonneReponse
else if rpnEleve == "B" then
2 * brm.bonneReponse / 3
else if rpnEleve == "C" then
brm.mauvaiseReponse / 3
else if rpnEleve == "D" then
brm.mauvaiseReponse
else
0
"F" ->
if rpnEleve == "D" then brm.bonneReponse
else if rpnEleve == "C" then 2*brm.bonneReponse/3
else if rpnEleve == "B" then brm.mauvaiseReponse/3
else if rpnEleve == "A" then brm.mauvaiseReponse
else 0
if rpnEleve == "D" then
brm.bonneReponse
else if rpnEleve == "C" then
2 * brm.bonneReponse / 3
else if rpnEleve == "B" then
brm.mauvaiseReponse / 3
else if rpnEleve == "A" then
brm.mauvaiseReponse
else
0
_ ->
if bonnerpn == rpneleve then
brm.bonnereponse
else if rpneleve == "-" then
if bonneRpn == rpnEleve then
brm.bonneReponse
else if rpnEleve == "-" then
0
else
brm.mauvaisereponse
brm.mauvaiseReponse
moyenne elvs =
let
moy nts = List.sum nts / toFloat (List.length nts)
moy nts =
List.sum nts / toFloat (List.length nts)
in
List.map .note elvs
|> expurgerNotesManquantes
|> moy
ecartType elvs =
let
moy nts = List.sum nts / toFloat (List.length nts)
moyCarre = moy << List.map (\x -> x^2)
ecTp nts = sqrt <| moyCarre nts - (moy nts)^2
moy nts =
List.sum nts / toFloat (List.length nts)
moyCarre =
moy << List.map (\x -> x ^ 2)
ecTp nts =
sqrt <| moyCarre nts - moy nts ^ 2
in
List.map .note elvs
|> expurgerNotesManquantes
|> ecTp
expurgerNotesManquantes nts =
case nts of
[] -> []
Nothing :: ntss -> expurgerNotesManquantes ntss
Just nt :: ntss -> nt :: expurgerNotesManquantes ntss
[] ->
[]
Nothing :: ntss ->
expurgerNotesManquantes ntss
(Just nt) :: ntss ->
nt :: expurgerNotesManquantes ntss

@ -1,130 +1,206 @@
module Fraction exposing
( Fraction
( Erreur
, Fraction
, Resultat
, Erreur
, frac
, num
, add
, den
, div
, estEntier
, opp
, add
, exp
, frac
, inv
, mul
, neg
, num
, opp
, raw
, sub
, mul
, inv
, div
, exp
, teX
, raw
)
import Arithmetic exposing (gcd)
type alias Fraction =
{ num : Int, den : Int }
type alias Resultat =
Result Erreur Fraction
type alias Fraction = { num : Int, den : Int }
type alias Resultat = Result Erreur Fraction
type alias Erreur = String
type alias Erreur =
String
frac : Int -> Int -> Resultat
frac a b =
let
min = 1 - 2^31
max = 2^31 - 1
min =
1 - 2 ^ 31
max =
2 ^ 31 - 1
in
case b of
0 -> Err "Division par zéro."
0 ->
Err "Division par zéro."
_ ->
if a > max || b > max || a < min || b < min then
Err "Certains calculs font intervenir des valeurs trop grandes pour être prises en charge."
else
Ok <| simplifier <| Fraction a b
simplifier : Fraction -> Fraction
simplifier a =
let
pgcd = gcd a.num a.den
pgcd =
gcd a.num a.den
sgnDuDen =
if a.den < 0 then -1 else 1
if a.den < 0 then
-1
else
1
in
{ a
| num = sgnDuDen * (a.num // pgcd)
, den = sgnDuDen * (a.den // pgcd)
}
num a = a.num
den a = a.den
num a =
a.num
den a =
a.den
estEntier a =
a.den == 1
estEntier a = a.den == 1
opp : (Fraction -> Fraction -> Resultat) -> Resultat -> Resultat -> Resultat
opp operation resultat1 resultat2 =
case ( resultat1, resultat2 ) of
(Ok fraction1, Ok fraction2) -> operation fraction1 fraction2
(Err erreur, _) -> Err erreur
(_, Err erreur) -> Err erreur
( Ok fraction1, Ok fraction2 ) ->
operation fraction1 fraction2
( Err erreur, _ ) ->
Err erreur
( _, Err erreur ) ->
Err erreur
add : Fraction -> Fraction -> Resultat
add a b =
let
pgcd = gcd a.den b.den
aDenBis = a.den // pgcd
bDenBis = b.den // pgcd
pgcd =
gcd a.den b.den
aDenBis =
a.den // pgcd
bDenBis =
b.den // pgcd
in
frac (a.num * bDenBis + b.num * aDenBis) (a.den * bDenBis)
neg : Fraction -> Fraction
neg a = Fraction (-a.num) a.den
neg a =
Fraction -a.num a.den
sub : Fraction -> Fraction -> Resultat
sub a b = add a (neg b)
sub a b =
add a (neg b)
mul : Fraction -> Fraction -> Resultat
mul a b =
let
pgcd = gcd a.num b.den
pgcdBis = gcd b.num a.den
aNum = a.num // pgcd
aDen = a.den // pgcdBis
bNum = b.num // pgcdBis
bDen = b.den // pgcd
pgcd =
gcd a.num b.den
pgcdBis =
gcd b.num a.den
aNum =
a.num // pgcd
aDen =
a.den // pgcdBis
bNum =
b.num // pgcdBis
bDen =
b.den // pgcd
in
frac (aNum * bNum) (aDen * bDen)
inv : Fraction -> Resultat
inv a =
case a.num of
0 -> Err "Division par zéro"
_ -> Ok <| Fraction a.den a.num
0 ->
Err "Division par zéro"
_ ->
Ok <| Fraction a.den a.num
div : Fraction -> Fraction -> Resultat
div a b = Result.andThen (mul a) <| inv b
div a b =
Result.andThen (mul a) <| inv b
exp : Fraction -> Fraction -> Resultat
exp a b =
let
sgnDeA =
if a.num < 0 then -1 else 1
if a.num < 0 then
-1
else
1
sgnDeB =
if b.num < 0 then -1 else 1
if b.num < 0 then
-1
else
1
in
if b.den == 1 && b.num < 0 then
frac ((sgnDeA * a.den) ^ (sgnDeB * b.num)) ((sgnDeA * a.num) ^ (sgnDeB * b.num))
else if b.den == 1 then
frac (a.num ^ b.num) (a.den ^ b.num)
else
Err "Extraction de racine impossible"
teX a
= case a.den of
1 -> String.fromInt a.num
teX a =
case a.den of
1 ->
String.fromInt a.num
_ ->
if a.num < 0 then
"-\\frac{" ++ String.fromInt (-a.num) ++ "}{" ++ String.fromInt a.den ++ "}"
"-\\frac{" ++ String.fromInt -a.num ++ "}{" ++ String.fromInt a.den ++ "}"
else
"\\frac{" ++ String.fromInt a.num ++ "}{" ++ String.fromInt a.den ++ "}"
raw a = "(" ++ String.fromInt a.num ++ "/" ++ String.fromInt a.den ++ ")"
raw a =
"(" ++ String.fromInt a.num ++ "/" ++ String.fromInt a.den ++ ")"

File diff suppressed because it is too large Load Diff

@ -1,9 +1,9 @@
module ParserMaths exposing (parseMaths, evaluer, evaluerBis, montrerErreurs, expr)
module ParserMaths exposing (evaluer, evaluerBis, expr, montrerErreurs, parseMaths)
import Fraction as F exposing (Fraction, Resultat, frac, opp)
import Maybe as M
import Set
import Parser exposing (..)
import Set
montrerErreurs : String -> List DeadEnd -> String
@ -11,6 +11,7 @@ montrerErreurs source errs =
case List.head errs of
Nothing ->
""
Just firstErr ->
source
++ "\n"
@ -27,16 +28,23 @@ montrerAttendu err =
case err.problem of
ExpectingNumber ->
"un nombre entier"
ExpectingSymbol s ->
"un \"" ++ s ++ "\""
_ ->
"une expression"
evaluerBis : Expr -> Fraction
evaluerBis expression =
case evaluer expression of
Err _ -> { num = 666, den = 1 }
Ok a -> a
Err _ ->
{ num = 666, den = 1 }
Ok a ->
a
evaluer : Expr -> Resultat
evaluer expression =
@ -68,13 +76,14 @@ evaluer expression =
Poly a_i x ->
Err "Les polynômes ne sont pas encore pris en charge."
{--
appliquerAuResultat f a b =
case (a,b) of
(Ok aa, Ok bb) -> Ok <| f aa bb
(Err aa, _) -> Err aa
--}
{--
type Expr
= Const Fraction
@ -92,6 +101,7 @@ type Expr
| Opp Expr
--}
type Expr
= Add Expr Expr
| Sub Expr Expr
@ -127,10 +137,13 @@ type Operand
| Operand Operator Expr
{-
En quelque sorte, décurryfie une expression binaire
binary e_1 (Operand MulOp e_2) == Mul e_1 e_2
-}
binary : Expr -> Operand -> Expr
binary a b =
case b of
@ -164,7 +177,10 @@ add =
|= loop [] addHelper
--
foldBinary : Expr -> List Operand -> Expr
foldBinary left operands =
List.foldr
@ -231,7 +247,8 @@ exp =
primary : Parser Expr
primary =
succeed (\op literal ->
succeed
(\op literal ->
case op of
Nothing ->
literal
@ -262,6 +279,7 @@ nombre =
, float = Nothing
}
poly : Parser Expr
poly =
succeed Poly

@ -1,10 +1,10 @@
module Test exposing (..)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
import MiniLatex
--import MiniLatex.Render exposing(MathJaxRenderOption(..))
import Element exposing (..)
import Element.Input as Input
import Html exposing (Html)
-- MAIN
@ -13,19 +13,17 @@ import MiniLatex
main =
Browser.sandbox { init = init, update = update, view = view }
texteLaTeX = "Pythagoras says: $a^2 + b^2 = c^2$"
-- MODEL
type alias Model = Int
type alias Model =
{ texte : String }
init : Model
init =
0
{ texte = "" }
@ -33,18 +31,12 @@ init =
type Msg
= Increment
| Decrement
= NouveauTexte String
update : Msg -> Model -> Model
update msg model =
case msg of
Increment ->
model + 1
Decrement ->
model - 1
update (NouveauTexte texte) model =
{ texte = texte }
@ -53,4 +45,17 @@ update msg model =
view : Model -> Html Msg
view model =
MiniLatex.render "" NoDelay texteLaTeX
layout [ width fill, height fill ] <|
row []
[ Input.multiline [ height <| maximum 300 fill, clip, scrollbars ]
{ onChange = NouveauTexte
, label = Input.labelAbove [] <| text "Test"
, placeholder =
Just <|
Input.placeholder [] <|
text "Entrer le texte"
, text = String.toUpper model.texte
, spellcheck = False
}
, text model.texte
]

Loading…
Cancel
Save