From 6fb9d7c09fd349bfed9af2084eb100633229501e Mon Sep 17 00:00:00 2001 From: Casper Bollen Date: Wed, 1 Nov 2023 21:45:56 +0100 Subject: [PATCH] chore: updating comments for GenOrder, removed unnecessary loop in solve --- src/Informedica.GenOrder.Lib/Exceptions.fs | 4 +- src/Informedica.GenOrder.Lib/Logging.fs | 17 ++++ src/Informedica.GenOrder.Lib/Order.fs | 15 ++-- src/Informedica.GenOrder.Lib/OrderVariable.fs | 80 +++++++++++++++---- src/Informedica.GenOrder.Lib/Scripts/Api2.fsx | 2 + src/Informedica.GenOrder.Lib/Scripts/load.fsx | 1 + src/Informedica.GenOrder.Lib/Utils.fs | 10 +++ src/Informedica.GenOrder.Lib/ValueUnit.fs | 30 +++++-- src/Informedica.GenOrder.Lib/Variable.fs | 32 +++++--- src/Informedica.GenOrder.Lib/WrappedString.fs | 31 ++++++- src/Informedica.GenSolver.Lib/Exceptions.fs | 9 +++ .../Scripts/Pick.fsx | 3 +- .../Scripts/Solver.fsx | 1 - .../Scripts/load.fsx | 2 + 14 files changed, 195 insertions(+), 42 deletions(-) diff --git a/src/Informedica.GenOrder.Lib/Exceptions.fs b/src/Informedica.GenOrder.Lib/Exceptions.fs index 631f661..7ff1923 100644 --- a/src/Informedica.GenOrder.Lib/Exceptions.fs +++ b/src/Informedica.GenOrder.Lib/Exceptions.fs @@ -7,6 +7,7 @@ module Exceptions = /// Equation exception exception OrderException of Exceptions.Message + /// Raise an `EquationException` with `Message` `m`. let raiseExc log m o = match log with @@ -30,4 +31,5 @@ module Exceptions = match m.Data0 with | Exceptions.OrderCouldNotBeSolved(m, o) -> $"{o} could not be resolved because: {m}" - | _ -> $"cannot turn {exn} to string" \ No newline at end of file + | _ -> + exn.ToString() \ No newline at end of file diff --git a/src/Informedica.GenOrder.Lib/Logging.fs b/src/Informedica.GenOrder.Lib/Logging.fs index f41f8f3..35c7cfd 100644 --- a/src/Informedica.GenOrder.Lib/Logging.fs +++ b/src/Informedica.GenOrder.Lib/Logging.fs @@ -20,17 +20,34 @@ module Logging = |> logger.Log + /// + /// Log an informative message + /// + /// The logger + /// The message let logInfo logger msg = msg |> Logging.OrderEvent |> log LoggingType.Informative logger + /// + /// Log a warning message + /// + /// The logger + /// The message let logWarning logger msg = msg |> Logging.OrderEvent |> log LoggingType.Warning logger + + + /// + /// Log an error message + /// + /// The logger + /// The message let logError (logger : LoggingType.Logger) msg = msg |> Logging.OrderException diff --git a/src/Informedica.GenOrder.Lib/Order.fs b/src/Informedica.GenOrder.Lib/Order.fs index 14e5c49..3af1092 100644 --- a/src/Informedica.GenOrder.Lib/Order.fs +++ b/src/Informedica.GenOrder.Lib/Order.fs @@ -1461,13 +1461,14 @@ module Order = ovar |> OrderVariable.minIncrMaxToValues n ) - - ord - |> fromOrdVars ovars - |> solveOrder false logger - |> function - | Ok ord -> loop flag ord - | Error _ -> ord + if not flag then ord + else + ord + |> fromOrdVars ovars + |> solveOrder false logger + |> function + | Ok ord -> loop flag ord + | Error _ -> ord loop true ord // |> fun ord -> diff --git a/src/Informedica.GenOrder.Lib/OrderVariable.fs b/src/Informedica.GenOrder.Lib/OrderVariable.fs index 40e520b..2115ff1 100644 --- a/src/Informedica.GenOrder.Lib/OrderVariable.fs +++ b/src/Informedica.GenOrder.Lib/OrderVariable.fs @@ -1,11 +1,10 @@ namespace Informedica.GenOrder.Lib - - /// Functions that deal with the `VariableUnit` type module OrderVariable = + open MathNet.Numerics open Informedica.Utils.Lib @@ -14,6 +13,7 @@ module OrderVariable = open Informedica.GenSolver.Lib open Informedica.GenUnits.Lib + module ValueRange = Variable.ValueRange module Minimum = ValueRange.Minimum module Maximum = ValueRange.Maximum @@ -28,6 +28,13 @@ module OrderVariable = module Constraints = + /// + /// Create a `Constraints` record + /// + /// An optional Minimum + /// An optional Increment + /// An optional Maximum + /// An optional ValueSet let create min incr max vs = { Min = min @@ -36,6 +43,21 @@ module OrderVariable = Values = vs } + + /// + /// Get the string representation of a `Constraints` record (in Dutch) + /// + /// The Constraints record + /// + /// + /// let min = 1N |> ValueUnit.singleWithUnit Units.Mass.milliGram |> Minimum.create true + /// let max = 10N |> ValueUnit.singleWithUnit Units.Mass.milliGram |> Maximum.create false + /// let incr = 1N |> ValueUnit.singleWithUnit Units.Mass.milliGram |> Increment.create + /// let cs = Constraints.create (Some min) (Some incr) (Some max) None + /// cs |> toString + /// // vanaf 1 mg[Mass] per 1 mg[Mass] tot 10 mg[Mass] + /// + /// let toString (cs : Constraints) = let toStr = ValueUnit.toStringDutchShort @@ -55,17 +77,32 @@ module OrderVariable = |> ValueUnit.toStringDutchShort + /// + /// Map the functions, fMin, fMax, fIncr and fVals over the `Constraints` record + /// + /// The function to map the Min + /// The function to map the Max + /// The function to map the Incr + /// The function to map the Values + /// The Constraints record let map fMin fMax fIncr fVals (cs : Constraints) = { cs with Min = cs.Min |> Option.map fMin Max = cs.Max |> Option.map fMax Incr = cs.Incr |> Option.map fIncr Values = cs.Values |> Option.map fVals - } - /// Create a `OrderVariable` with preset values + /// + /// Create an OrderVariable, an OrderVariable is a Variable with Constraints + /// + /// The Name of the Variable + /// An optional Minimum of the Variable + /// An optional Increment of the Variable + /// An optional Maximum of the Variable + /// An optional ValueSet of the Variable + /// The Constraints for the OrderVariable let create n min incr max vs cs = ValueRange.create min incr max vs |> fun vlr -> @@ -76,8 +113,12 @@ module OrderVariable = } - /// Create a new `VariableUnit` with - /// `Name` **nm** and `Unit` **un** + /// + /// Create a new OrderVariable. The OrderVariable will have an exclusive + /// Minimum of zero and a Constraints with an exclusive Minimum of zero + /// + /// The Name of the Variable + /// The Unit of the Values in the Variable and Constraints let createNew n un = let vu = 0N |> ValueUnit.createSingle un let min = Minimum.create false vu |> Some @@ -85,10 +126,13 @@ module OrderVariable = Constraints.create min None None None |> create n min None None None - /// Apply **f** to `VariableUnit` **vru** - let apply f (ovar: OrderVariable) = ovar |> f - + /// + /// Map a function f to the Values (i.e. ValueUnit) of the Variable + /// of the OrderVariable + /// + /// The function to map + /// The OrderVariable let map f (ovar: OrderVariable) = { ovar with Variable = @@ -101,21 +145,27 @@ module OrderVariable = } - /// Utility function to facilitate type inference - let get = apply id - - - /// Get the `Variable` from a `VariableUnit` + /// Get the `Variable` from an OrderVariable let getVar { Variable = var } = var - /// Get the `Variable.Name` from a `VariableUnit` **vru** + /// Get the `Variable.Name` from an OrderVariable let getName ovar = (ovar |> getVar).Name + /// Check whether two OrderVariables have the same name let eqsName ovar1 ovar2 = (ovar1 |> getName) = (ovar2 |> getName) + /// + /// Apply the constraints of an OrderVariable to the Variable + /// of the OrderVariable. + /// + /// The OrderVariable + /// + /// If the Constraints have an Increment and a ValueSet, then the + /// only the Increment is applied to the Variable. + /// let applyConstraints (ovar : OrderVariable) = { ovar with Variable = diff --git a/src/Informedica.GenOrder.Lib/Scripts/Api2.fsx b/src/Informedica.GenOrder.Lib/Scripts/Api2.fsx index 77d7f45..ab6d075 100644 --- a/src/Informedica.GenOrder.Lib/Scripts/Api2.fsx +++ b/src/Informedica.GenOrder.Lib/Scripts/Api2.fsx @@ -18,6 +18,8 @@ open Informedica.GenOrder.Lib let path = Some $"{__SOURCE_DIRECTORY__}/log.txt" + + let startLogger () = // Start the logger at an informative level OrderLogger.logger.Start path Logging.Level.Informative diff --git a/src/Informedica.GenOrder.Lib/Scripts/load.fsx b/src/Informedica.GenOrder.Lib/Scripts/load.fsx index 750868e..b777c90 100644 --- a/src/Informedica.GenOrder.Lib/Scripts/load.fsx +++ b/src/Informedica.GenOrder.Lib/Scripts/load.fsx @@ -43,3 +43,4 @@ open Informedica.Utils.Lib let zindexPath = __SOURCE_DIRECTORY__ |> Path.combineWith "../../../" Environment.CurrentDirectory <- zindexPath + diff --git a/src/Informedica.GenOrder.Lib/Utils.fs b/src/Informedica.GenOrder.Lib/Utils.fs index 830656e..af55685 100644 --- a/src/Informedica.GenOrder.Lib/Utils.fs +++ b/src/Informedica.GenOrder.Lib/Utils.fs @@ -24,9 +24,19 @@ module Utils = + /// + /// Get data from a google sheet containing constraints + /// + /// The sheet to get + /// A array table of string arrays let getDataFromConstraints sheet = GoogleSheets.getDataFromSheet constraints sheet + /// + /// Get data from a google sheet containing data for GenPres + /// + /// The sheet to get + /// A array table of string arrays let getDataFromGenPres sheet = GoogleSheets.getDataFromSheet genpres sheet diff --git a/src/Informedica.GenOrder.Lib/ValueUnit.fs b/src/Informedica.GenOrder.Lib/ValueUnit.fs index 83f7ae2..cb67bf0 100644 --- a/src/Informedica.GenOrder.Lib/ValueUnit.fs +++ b/src/Informedica.GenOrder.Lib/ValueUnit.fs @@ -7,24 +7,44 @@ namespace Informedica.GenOrder.Lib /// `Informedica.GenUnits.Lib` module ValueUnit = - open MathNet.Numerics - open Informedica.Utils.Lib.BCL open Informedica.GenUnits.Lib - open ValueUnit - - + /// + /// Return a Unit as a short Dutch string + /// let unitToString = Units.toString Units.Dutch Units.Short + /// + /// Check if a Unit is an adjust unit, i.e. + /// kg or m2. + /// + /// The Unit let isAdjust (u : Unit) = u |> Group.eqsGroup (Units.Weight.kiloGram) || u |> Group.eqsGroup (Units.BSA.m2) + /// + /// Put an adjust unit in the middle of a combined unit. + /// + /// The ValueUnit + /// + /// + /// let u1 = Units.Mass.milliGram + /// let u2 = Units.Weight.kiloGram + /// let u3 = Units.Time.day + /// // mg/day/kg + /// let vu1 = withValue [|1N|] (u1 |> per u3 |> per u2) + /// // = mg/kg/day + /// let vu2 = vu1 |> correctAdjustOrder + /// // check + /// vu1 |> eqsGroup vu2 + /// + /// let correctAdjustOrder vu = let v, u = vu |> get match u |> getUnits with diff --git a/src/Informedica.GenOrder.Lib/Variable.fs b/src/Informedica.GenOrder.Lib/Variable.fs index c1bbd0f..527512a 100644 --- a/src/Informedica.GenOrder.Lib/Variable.fs +++ b/src/Informedica.GenOrder.Lib/Variable.fs @@ -9,27 +9,41 @@ module Variable = open Informedica.GenSolver.Lib.Variable.ValueRange - let inline setOpt m set vr = + let inline private setOpt aOption set vr = try - match m with + match aOption with | Some m -> vr |> set m | None -> vr with | _ -> vr // TODO: ugly fix need to refactor + /// + /// Sets an optional minimum value for the value range + /// + /// The optional Minimum + /// The ValueRange let setOptMin min vr = vr |> setOpt min setMin + /// + /// Sets an optional maximum value for the value range + /// + /// The optional Maximum + /// The ValueRange let setOptMax max vr = vr |> setOpt max setMax + /// + /// Sets an optional increment value for the value range + /// + /// The optional Increment + /// The ValueRange let setOptIncr incr vr = vr |> setOpt incr setIncr - let setOptVs vs vr = - try - match vs with - | Some vs -> vr |> setValueSet vs - | None -> vr - - with | _ -> vr // TODO: ugly fix need to refactor + /// + /// Sets an optional value set for the value range + /// + /// The optional ValueSet + /// The ValueRange + let setOptVs vs vr = vr |> setOpt vs setValueSet diff --git a/src/Informedica.GenOrder.Lib/WrappedString.fs b/src/Informedica.GenOrder.Lib/WrappedString.fs index 03c7091..ae73b80 100644 --- a/src/Informedica.GenOrder.Lib/WrappedString.fs +++ b/src/Informedica.GenOrder.Lib/WrappedString.fs @@ -14,10 +14,24 @@ module WrappedString = /// deal with an identifier module Id = + /// + /// Create an Id from a string + /// + /// The id string let create s = s |> Id + + /// + /// Lift a function to hande the identifier string + /// + /// The function + /// A function that handles the identifier let lift f = fun (Id s) -> s |> f |> create + + /// + /// Get the string from an Id + /// let toString (Id s) = s @@ -34,7 +48,10 @@ module WrappedString = let [] addWith = "_" - /// Create a `Name` from a list of strings that + /// + /// Create a `Name` from a list of strings. The strings + /// will be concatenated with a dot. + /// let create ns = try $"[{ns |> String.concat concatWith}]" |> Name.createExc @@ -43,12 +60,15 @@ module WrappedString = printfn $"cannot create name with {ns}" raise e + /// Get the string from a `Name` let toString = Name.toString + /// Create a `Name` from a string let fromString = Name.createExc + /// Return a Name as string list let toStringList = Name.toString >> (String.replace "[" "") @@ -57,9 +77,16 @@ module WrappedString = >> (String.split concatWith) + /// + /// Add a string to a `Name`. The string will be + /// added with an underscore. + /// + /// The string to add + /// The Name + /// The new Name let add s n = try - $"{n |> toString}{addWith}{s}" |> Name.createExc + $"{n |> toString}{addWith}%s{s}" |> Name.createExc with | e -> printfn $"cannot add name with {s} and {n}" diff --git a/src/Informedica.GenSolver.Lib/Exceptions.fs b/src/Informedica.GenSolver.Lib/Exceptions.fs index 9a64cb2..25806d3 100644 --- a/src/Informedica.GenSolver.Lib/Exceptions.fs +++ b/src/Informedica.GenSolver.Lib/Exceptions.fs @@ -7,6 +7,7 @@ module Exceptions = exception SolverException of Exceptions.Message list + /// Raise an `EquationException` with `Message` `m` and adds it to /// the list of `errs`. let raiseExc log errs m = @@ -18,3 +19,11 @@ module Exceptions = m::errs |> SolverException |> raise + + let toString (exn : exn) = + match exn with + | :? SolverException as m -> + m.Data0 + |> List.map (fun m -> m.ToString()) |> String.concat "\n" + | _ -> + exn.ToString() \ No newline at end of file diff --git a/src/Informedica.GenSolver.Lib/Scripts/Pick.fsx b/src/Informedica.GenSolver.Lib/Scripts/Pick.fsx index ac51ce7..41f11e0 100644 --- a/src/Informedica.GenSolver.Lib/Scripts/Pick.fsx +++ b/src/Informedica.GenSolver.Lib/Scripts/Pick.fsx @@ -307,7 +307,6 @@ module Solve = open Solve - let gentaEqs = { Components = @@ -368,7 +367,7 @@ gentaEqs // find min/max scenarios gentaEqs // patient -|> solveValues "ord_adj" [1N] "kg[Weight]" +|> solveValues "ord_adj" [800N/1000N] "kg[Weight]" //|> printEqs // product |> solveValues "genta_sol_qty" [2N; 10N] "ml[Volume]" diff --git a/src/Informedica.GenSolver.Lib/Scripts/Solver.fsx b/src/Informedica.GenSolver.Lib/Scripts/Solver.fsx index 2bfe530..6e6e5fc 100644 --- a/src/Informedica.GenSolver.Lib/Scripts/Solver.fsx +++ b/src/Informedica.GenSolver.Lib/Scripts/Solver.fsx @@ -1,6 +1,5 @@ #load "load.fsx" - #time diff --git a/src/Informedica.GenSolver.Lib/Scripts/load.fsx b/src/Informedica.GenSolver.Lib/Scripts/load.fsx index cea9f13..ae36401 100644 --- a/src/Informedica.GenSolver.Lib/Scripts/load.fsx +++ b/src/Informedica.GenSolver.Lib/Scripts/load.fsx @@ -26,3 +26,5 @@ open ValueRange open Variable.Dto *) + +