Attempting to continue to flesh out Model

This commit is contained in:
Ozzie Gooen 2020-02-08 20:38:55 +00:00
parent 6d94cb3227
commit 949fcd86e6
6 changed files with 156 additions and 241 deletions

View File

@ -1,133 +1,8 @@
'use strict'; 'use strict';
var $$Array = require("bs-platform/lib/js/array.js");
var Curry = require("bs-platform/lib/js/curry.js");
var React = require("react");
var Antd_Radio = require("bs-ant-design-alt/src/Antd_Radio.js");
var Belt_Array = require("bs-platform/lib/js/belt_Array.js");
var EAFunds_Data$ProbExample = require("./EAFunds_Data.bs.js");
var EAFunds_Model$ProbExample = require("./EAFunds_Model.bs.js"); var EAFunds_Model$ProbExample = require("./EAFunds_Model.bs.js");
function handleChange(handleChange$1, $$event) { var model = EAFunds_Model$ProbExample.Interface.model;
return Curry._1(handleChange$1, $$event.target.value);
}
function get(state, field) { exports.model = model;
switch (field) { /* EAFunds_Model-ProbExample Not a pure module */
case /* Group */0 :
return state[/* group */0];
case /* Year */1 :
return state[/* year */1];
case /* Output */2 :
return state[/* output */2];
}
}
function set(state, field, value) {
switch (field) {
case /* Group */0 :
return /* record */[
/* group */value,
/* year */state[/* year */1],
/* output */state[/* output */2]
];
case /* Year */1 :
return /* record */[
/* group */state[/* group */0],
/* year */value,
/* output */state[/* output */2]
];
case /* Output */2 :
return /* record */[
/* group */state[/* group */0],
/* year */state[/* year */1],
/* output */value
];
}
}
var Form = {
get: get,
set: set
};
function EAFunds_Form(Props) {
var match = React.useState((function () {
return /* record */[
/* group */"Animal Welfare Fund",
/* year */2021,
/* output */"Donations"
];
}));
var setForm = match[1];
var form = match[0];
var match$1 = React.useState((function () {
return "Donations";
}));
var setProperty = match$1[1];
var property = match$1[0];
var foundGroup = Belt_Array.getBy(EAFunds_Data$ProbExample.funds, (function (r) {
return r[/* name */1] === form[/* group */0];
}));
var foundProperty;
switch (property) {
case "Donations" :
foundProperty = /* DONATIONS */0;
break;
case "Payouts" :
foundProperty = /* PAYOUTS */1;
break;
default:
foundProperty = undefined;
}
return React.createElement(React.Fragment, undefined, React.createElement("input", {
type: "number",
value: form[/* year */1].toString(),
onChange: (function (param) {
var r = param.target.value;
var r$1 = Number(r);
if (r$1 >= 2020.0 && r$1 <= 2050.0) {
return Curry._1(setForm, (function (param) {
return set(form, /* Year */1, r$1);
}));
} else {
return /* () */0;
}
})
}), React.createElement(Antd_Radio.Group.make, {
value: form[/* group */0],
onChange: (function (param) {
var r = param.target.value;
return Curry._1(setForm, (function (param) {
return set(form, /* Group */0, r);
}));
}),
children: $$Array.map((function (f) {
return React.createElement(Antd_Radio.make, {
value: f[/* name */1],
children: f[/* name */1]
});
}), EAFunds_Data$ProbExample.funds)
}), React.createElement(Antd_Radio.Group.make, {
value: property,
onChange: (function (param) {
return Curry._1(setProperty, param.target.value);
}),
children: null
}, React.createElement(Antd_Radio.make, {
value: "Donations",
children: "Donations"
}), React.createElement(Antd_Radio.make, {
value: "Payouts",
children: "Payouts"
})), foundGroup !== undefined && foundProperty !== undefined ? EAFunds_Model$ProbExample.run(foundGroup[/* group */0], form[/* year */1], foundProperty) : "");
}
var make = EAFunds_Form;
exports.handleChange = handleChange;
exports.Form = Form;
exports.make = make;
/* react Not a pure module */

View File

@ -1,72 +1 @@
open EAFunds_Data; let model = EAFunds_Model.Interface.model;
let handleChange = (handleChange, event) =>
handleChange(ReactEvent.Form.target(event)##value);
module Form = [%lenses
type state = {
group: string,
year: float,
output: string,
}
];
[@react.component]
let make = () => {
let (form, setForm) =
React.useState(() =>
{Form.group: "Animal Welfare Fund", year: 2021., output: "Donations"}
);
let (property, setProperty) = React.useState(() => "Donations");
let foundGroup =
Belt.Array.getBy(EAFunds_Data.funds, r => r.name === form.group);
let foundProperty =
switch (property) {
| "Donations" => Some(DONATIONS)
| "Payouts" => Some(PAYOUTS)
| _ => None
};
<>
<input
type_="number"
value={Form.get(form, Year) |> Js.Float.toString}
onChange={handleChange(r =>
switch (Js.Float.fromString(r)) {
| r when r >= 2020.0 && r <= 2050.0 =>
setForm(_ => Form.set(form, Form.Year, r))
| _ => ()
}
)}
/>
<Antd.Radio.Group
value={Form.get(form, Group)}
onChange={handleChange(r =>
setForm(_ => Form.set(form, Form.Group, r))
)}>
{EAFunds_Data.funds
|> Array.map(f =>
<Antd.Radio value={f.name}>
{f.name |> ReasonReact.string}
</Antd.Radio>
)
|> ReasonReact.array}
</Antd.Radio.Group>
<Antd.Radio.Group
value=property onChange={handleChange(r => setProperty(r))}>
<Antd.Radio value="Donations">
{"Donations" |> ReasonReact.string}
</Antd.Radio>
<Antd.Radio value="Payouts">
{"Payouts" |> ReasonReact.string}
</Antd.Radio>
</Antd.Radio.Group>
{(
switch (foundGroup, foundProperty) {
| (Some(g), Some(f)) =>
EAFunds_Model.run(g.group, Form.get(form, Year), f)
| _ => ""
}
)
|> ReasonReact.string}
</>;
};

View File

@ -34,11 +34,13 @@ let make = () => {
{r.name |> ReasonReact.string} {r.name |> ReasonReact.string}
</th> </th>
<th className="px-4 py-2 border font-normal"> <th className="px-4 py-2 border font-normal">
{EAFunds_Model.run(r.group, year, DONATIONS) {EAFunds_Model.go(r.group, year, DONATIONS)
|> Model.InputTypes.to_string
|> ReasonReact.string} |> ReasonReact.string}
</th> </th>
<th className="px-4 py-2 border font-normal"> <th className="px-4 py-2 border font-normal">
{EAFunds_Model.run(r.group, year, PAYOUTS) {EAFunds_Model.go(r.group, year, PAYOUTS)
|> Model.InputTypes.to_string
|> ReasonReact.string} |> ReasonReact.string}
</th> </th>
</tr> </tr>

View File

@ -1,8 +1,6 @@
'use strict'; 'use strict';
var Block = require("bs-platform/lib/js/block.js"); var Block = require("bs-platform/lib/js/block.js");
var Curry = require("bs-platform/lib/js/curry.js");
var CamlinternalOO = require("bs-platform/lib/js/camlinternalOO.js");
var Math$ProbExample = require("../Math.bs.js"); var Math$ProbExample = require("../Math.bs.js");
var Model$ProbExample = require("../Model.bs.js"); var Model$ProbExample = require("../Model.bs.js");
@ -67,11 +65,11 @@ var PayoutsIfAround = {
currentValue: currentValue currentValue: currentValue
}; };
function run(group, year, output) { function go(group, year, output) {
return calculateDifference(currentValue(group, output), year, /* record */[ return /* FloatCdf */Block.__(3, [calculateDifference(currentValue(group, output), year, /* record */[
/* meanDiff */1.1, /* meanDiff */1.1,
/* stdDiff */1.1 /* stdDiff */1.1
]); ])]);
} }
var model_002 = /* assumptions : :: */[ var model_002 = /* assumptions : :: */[
@ -102,12 +100,12 @@ var model_003 = /* inputs : :: */[
/* :: */[ /* :: */[
/* tuple */[ /* tuple */[
"Meta Fund", "Meta Fund",
"metaFund" "meta"
], ],
/* :: */[ /* :: */[
/* tuple */[ /* tuple */[
"Total", "All",
"total" "all"
], ],
/* [] */0 /* [] */0
] ]
@ -140,36 +138,71 @@ var model = /* record */[
/* author */"George Harrison", /* author */"George Harrison",
model_002, model_002,
model_003, model_003,
model_004 model_004,
/* outputConfig : Single */0
]; ];
var class_tables = [ function convertChoice(s) {
0, switch (s) {
0, case "animal" :
0 return /* Fund */[/* ANIMAL_WELFARE */0];
]; case "globalHealth" :
return /* Fund */[/* GLOBAL_HEALTH */1];
function run$1(a, i) { case "longTerm" :
if (!class_tables[0]) { return /* Fund */[/* LONG_TERM_FUTURE */2];
var $$class = CamlinternalOO.create_table(0); case "meta" :
var env = CamlinternalOO.new_variable($$class, ""); return /* Fund */[/* META */3];
var env_init = function (env$1) { default:
var self = CamlinternalOO.create_object_opt(0, $$class); return /* All */0;
self[env] = env$1;
return self;
};
CamlinternalOO.init_class($$class);
class_tables[0] = env_init;
} }
return Curry._1(class_tables[0], 0); }
function run(p) {
var match = p[/* assumptions */0];
var match$1 = p[/* inputs */1];
if (match) {
var match$2 = match[0];
if (match$2 !== undefined) {
var match$3 = match$2;
if (match$3.tag) {
return ;
} else {
var match$4 = match[1];
if (match$4) {
var match$5 = match$4[0];
if (match$5 !== undefined && !(match$5.tag || match$4[1] || !match$1)) {
var match$6 = match$1[0];
if (match$6 !== undefined) {
var match$7 = match$6;
if (match$7.tag === /* SingleChoice */1 && !match$1[1]) {
return go(convertChoice(match$7[0]), match$3[0], /* DONATIONS */0);
} else {
return ;
}
} else {
return ;
}
} else {
return ;
}
} else {
return ;
}
}
} else {
return ;
}
}
} }
var Interface = { var Interface = {
model: model, model: model,
run: run$1 convertChoice: convertChoice,
run: run
}; };
exports.PayoutsIfAround = PayoutsIfAround; exports.PayoutsIfAround = PayoutsIfAround;
exports.run = run; exports.go = go;
exports.Interface = Interface; exports.Interface = Interface;
/* model Not a pure module */ /* model Not a pure module */

View File

@ -42,18 +42,21 @@ module PayoutsIfAround = {
}; };
}; };
let run = (group: group, year: float, output: output) => { let go = (group: group, year: float, output: output) => {
PayoutsIfAround.( PayoutsIfAround.(
calculateDifference( Model.InputTypes.FloatCdf(
currentValue(group, output), calculateDifference(
year, currentValue(group, output),
yearlyMeanGrowthRateIfNotClosed(group), year,
yearlyMeanGrowthRateIfNotClosed(group),
),
) )
); );
}; };
module Interface = { module Interface = {
open Model; open Model;
let model = { let model = {
name: "Calculate the payments and payouts of EA Funds based on existing data.", name: "Calculate the payments and payouts of EA Funds based on existing data.",
author: "George Harrison", author: "George Harrison",
@ -71,8 +74,8 @@ module Interface = {
("Animal Welfare Fund", "animal"), ("Animal Welfare Fund", "animal"),
("Global Health Fund", "globalHealth"), ("Global Health Fund", "globalHealth"),
("Long Term Future Fund", "longTerm"), ("Long Term Future Fund", "longTerm"),
("Meta Fund", "metaFund"), ("Meta Fund", "meta"),
("Total", "total"), ("All", "all"),
], ],
}), }),
(), (),
@ -92,7 +95,26 @@ module Interface = {
Output.make(~name="Payments", ~parameterType=FloatCdf, ()), Output.make(~name="Payments", ~parameterType=FloatCdf, ()),
Output.make(~name="Payouts", ~parameterType=FloatCdf, ()), Output.make(~name="Payouts", ~parameterType=FloatCdf, ()),
], ],
outputConfig: Single,
}; };
let run = (a, i) => {}; let convertChoice = (s: string) =>
switch (s) {
| "animal" => Fund(ANIMAL_WELFARE)
| "globalHealth" => Fund(GLOBAL_HEALTH)
| "longTerm" => Fund(LONG_TERM_FUTURE)
| "meta" => Fund(META)
| _ => All
};
let run = (p: Model.modelParams) => {
switch (p.assumptions, p.inputs) {
| (
[Some(Year(intendedYear)), Some(Year(currentYear))],
[Some(SingleChoice(fund))],
) =>
Some(go(convertChoice(fund), intendedYear, DONATIONS))
| _ => None
};
};
}; };

View File

@ -1,3 +1,25 @@
module InputTypes = {
type t =
| Year(float)
| SingleChoice(string)
| FloatPoint(float)
| FloatCdf(string);
type withName = (string, t);
let withoutName = ((_, t): withName) => t;
type withNames = list(withName);
let getName = (r: withNames, name) =>
r->Belt.List.getBy(((n, _)) => n == name);
let to_string = (t: t) => {
switch (t) {
| SingleChoice(r) => r
| FloatCdf(r) => r
| Year(r) => r |> Js.Float.toFixed
| FloatPoint(r) => r |> Js.Float.toFixed
};
};
};
module IOTypes = { module IOTypes = {
type singleChoice = { type singleChoice = {
options: list((string, string)), options: list((string, string)),
@ -50,6 +72,9 @@ module Output = {
parameterType, parameterType,
}; };
type outputConfig =
| Single;
let make = (~name, ~parameterType, ~id=name, ()) => { let make = (~name, ~parameterType, ~id=name, ()) => {
id, id,
name, name,
@ -63,4 +88,33 @@ type model = {
assumptions: list(Input.parameter), assumptions: list(Input.parameter),
inputs: list(Input.parameter), inputs: list(Input.parameter),
outputs: list(Output.parameter), outputs: list(Output.parameter),
outputConfig: Output.outputConfig,
};
let gatherInputs = (m: model, a: list(InputTypes.withName)) => {
let getItem = (p: Input.parameter) => InputTypes.getName(a, p.id);
[
m.assumptions |> List.map(getItem),
m.inputs |> List.map(getItem),
[InputTypes.getName(a, "output")],
]
|> List.flatten;
};
type modelParams = {
assumptions: list(option(InputTypes.t)),
inputs: list(option(InputTypes.t)),
output: option(InputTypes.t),
};
let response = (m: model, a: list(InputTypes.withName)) => {
let getItem = (p: Input.parameter) =>
InputTypes.getName(a, p.id)->Belt.Option.map(InputTypes.withoutName);
{
assumptions: m.assumptions |> List.map(getItem),
inputs: m.inputs |> List.map(getItem),
output:
InputTypes.getName(a, "output")
->Belt.Option.map(InputTypes.withoutName),
};
}; };