Skip to content

Commit

Permalink
[C] change equation to distanceMly
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgoff authored and blnkt committed Apr 4, 2024
1 parent 2d6c31d commit 9b8b89c
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 136 deletions.
7 changes: 3 additions & 4 deletions components/calculators/Interactive/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const InteractiveCalculator: FunctionComponent<InteractiveCalculatorProps> = ({
i18n: { language },
} = useTranslation();

const { fields = {}, result, latex } = Calculator(equation, value, language);
const { inputs = [], result, latex } = Calculator(equation, value, language);

const handleChange = (event: FormEvent<HTMLInputElement>, key: string) => {
onChangeCallback &&
Expand All @@ -31,12 +31,11 @@ const InteractiveCalculator: FunctionComponent<InteractiveCalculatorProps> = ({
return (
<Styled.MathContainer>
<Styled.Inputs id={id}>
{Object.keys(fields).map((key: string) => {
const { label, precision } = fields[key];
{inputs.map(({ key, precision, placeholder }) => {
return (
<Styled.InputRow key={key}>
<label htmlFor={key}>
<Equation latex={label} />
<Equation latex={`${placeholder} =`} />
</label>
<MathInput
value={value[key] ?? ""}
Expand Down
7 changes: 3 additions & 4 deletions components/calculators/interactive/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const InteractiveCalculator: FunctionComponent<InteractiveCalculatorProps> = ({
i18n: { language },
} = useTranslation();

const { fields = {}, result, latex } = Calculator(equation, value, language);
const { inputs = [], result, latex } = Calculator(equation, value, language);

const handleChange = (event: FormEvent<HTMLInputElement>, key: string) => {
onChangeCallback &&
Expand All @@ -31,12 +31,11 @@ const InteractiveCalculator: FunctionComponent<InteractiveCalculatorProps> = ({
return (
<Styled.MathContainer>
<Styled.Inputs id={id}>
{Object.keys(fields).map((key: string) => {
const { label, precision } = fields[key];
{inputs.map(({ key, precision, placeholder }) => {
return (
<Styled.InputRow key={key}>
<label htmlFor={key}>
<Equation latex={label} />
<Equation latex={`${placeholder} =`} />
</label>
<MathInput
value={value[key] ?? ""}
Expand Down
51 changes: 51 additions & 0 deletions components/calculators/lib/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Variable, EquationConfig, Equation } from "@/types/calculators";

export const Variables: Record<string, Variable> = {
distanceMly: {
key: "distanceMly",
precision: 1,
sigFigs: 3,
placeholder: "d",
},
m15: { key: "m15", precision: 2, placeholder: "\\Delta m_{15}" },
peakApparentMagnitude: {
key: "peakApparentMagnitude",
precision: 1,
placeholder: "m",
},
peakAbsoluteMagnitude: {
key: "peakAbsoluteMagnitude",
precision: 1,
placeholder: "M",
},
};

const Config: Record<Equation, EquationConfig> = {
peakAbsoluteMagnitude: {
latex: ({ result, constants, variables }) =>
`${result} = ${constants.A} + ${constants.B}\\left ( ${variables.m15} \\right )`,
constants: {
A: { value: -23.598, precision: 2 },
B: { value: 6.457, precision: 2 },
},
inputs: [Variables.m15],
result: Variables.peakAbsoluteMagnitude,
},
distanceMly: {
latex: ({ result, constants, variables }) =>
`${result} = \\left (${constants.A}\\right )${constants.B}^{\\frac{${variables.peakApparentMagnitude} - ${variables.peakAbsoluteMagnitude}}{${constants.C}}} + ${constants.D}`,
constants: {
A: { value: 3.26, precision: 2 },
B: { value: 10 },
C: { value: 5 },
D: { value: 1 },
},
inputs: [Variables.peakApparentMagnitude, Variables.peakAbsoluteMagnitude],
result: {
...Variables.distanceMly,
addUnit: (value) => `${value}\\space\\text{Mly}`,
},
},
};

export default Config;
37 changes: 16 additions & 21 deletions components/calculators/lib/equations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,36 @@ import round from "lodash/round";
import isNumber from "lodash/isNumber";
import { Equation, EquationComposer } from "@/types/calculators";

const peakAbsoluteMagnitude: EquationComposer = ({ m15 }) => {
const A = -23.598;
const B = 6.457;

const peakAbsoluteMagnitude: EquationComposer = ({ m15 }, { A, B }) => {
if (isNumber(m15)) {
const result = round(A + B * m15, 1);
const result = round(A.value + B.value * m15, 1);

return { constants: { A, B }, result };
return result;
}

return { constants: { A, B } };
return undefined;
};

const supernovaDistance: EquationComposer = ({
peakApparentMagnitude,
peakAbsoluteMagnitude,
}) => {
const A = 3.26;
const B = 10;
const C = 5;
const D = 1;

const distanceMly: EquationComposer = (
{ peakApparentMagnitude, peakAbsoluteMagnitude },
{ A, B, C, D }
) => {
if (isNumber(peakApparentMagnitude) && isNumber(peakAbsoluteMagnitude)) {
const exponent = (peakApparentMagnitude - peakAbsoluteMagnitude) / C + D;
const result = round((A * Math.pow(B, exponent)) / Math.pow(B, 6));
const exponent =
(peakApparentMagnitude - peakAbsoluteMagnitude) / C.value + D.value;
const result = round(
(A.value * Math.pow(B.value, exponent)) / Math.pow(10, 6)
);

return { constants: { A, B, C, D }, result };
return result;
}

return { constants: { A, B, C, D } };
return undefined;
};

const Equations: Record<Equation, EquationComposer> = {
peakAbsoluteMagnitude,
supernovaDistance,
distanceMly,
};

export default Equations;
22 changes: 0 additions & 22 deletions components/calculators/lib/fields.ts

This file was deleted.

22 changes: 15 additions & 7 deletions components/calculators/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
NonNullableCalculatorValues,
} from "@/types/calculators";
import Equations from "./equations";
import LaTeX from "./latex";
import FormFields from "./fields";
import LaTeXComposer from "./latex";
import Config from "./config";

const cleanInput = (values: CalculatorValues): NonNullableCalculatorValues => {
const nonNullValues: NonNullableCalculatorValues = {};
Expand All @@ -19,16 +19,24 @@ const cleanInput = (values: CalculatorValues): NonNullableCalculatorValues => {
};

const Calculator: Calculator = (equation, value, locale = fallbackLng) => {
const cleaned = cleanInput(value);
const variables = cleanInput(value);
const config = Config[equation];

const { result } = Equations[equation](cleaned);
if (typeof config === "undefined") {
console.error(`Equation ${equation} does not exist`);
}

const { inputs, constants } = config;

const result = Equations[equation](variables, constants);

return {
fields: FormFields[equation],
inputs,
result,
latex: LaTeX[equation](
latex: LaTeXComposer(
config,
{
...cleaned,
variables,
result,
},
locale
Expand Down
131 changes: 73 additions & 58 deletions components/calculators/lib/latex.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,91 @@
import isNumber from "lodash/isNumber";
import { fallbackLng } from "@/lib/i18n/settings";
import { LaTeXComposer } from "@/types/calculators";
import placeholders from "./placeholders";
import Equations from "./equations";
import {
Variable,
Constant,
Result,
EquationConfig,
} from "@/types/calculators";
import { Variables } from "./config";

const withClass = (value: string) => `\\class{calc-output}{${value}}`;

const peakAbsoluteMagnitude: LaTeXComposer = (
{ result = placeholders.peakAbsoluteMagnitude, m15 = placeholders.m15 },
locale = fallbackLng
) => {
const {
constants: { A, B },
} = Equations.peakAbsoluteMagnitude({});
const formatConstant = ({ precision, value }: Constant, locale = fallbackLng) =>
Intl.NumberFormat(locale, {
minimumFractionDigits: precision,
maximumFractionDigits: precision,
}).format(value);

const { format } = new Intl.NumberFormat(locale, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
const { format: resultFormat } = new Intl.NumberFormat(locale, {
minimumFractionDigits: 1,
maximumFractionDigits: 1,
});
const formatVariable = ({
variable,
config: { precision, sigFigs, placeholder },
locale = fallbackLng,
}: {
variable?: number;
config: Variable;
locale?: string;
}) => {
if (isNumber(variable)) {
return Intl.NumberFormat(locale, {
minimumFractionDigits: precision,
maximumFractionDigits: precision,
maximumSignificantDigits: sigFigs,
}).format(variable);
}

return placeholder;
};

const displayResult = isNumber(result) ? resultFormat(result) : result;
const displayM15 = isNumber(m15) ? format(m15) : m15;
const formatResult = ({
result: variable,
config: { addUnit, ...config },
locale = fallbackLng,
}: {
result?: number;
config: Result;
locale?: string;
}) => {
if (isNumber(variable) && addUnit) {
return withClass(addUnit(formatVariable({ variable, config, locale })));
}

return `${withClass(displayResult)} = ${format(A)} + ${format(
B
)}\\left ( ${displayM15} \\right )`;
return withClass(
formatVariable({
variable,
config,
locale,
})
);
};

const supernovaDistance: LaTeXComposer = (
{
result = placeholders.distance,
peakAbsoluteMagnitude = placeholders.peakAbsoluteMagnitude,
peakApparentMagnitude = placeholders.peakApparentMagnitude,
},
const LaTeXComposer = (
equation: EquationConfig,
values: { result?: number; variables: Record<string, number | undefined> },
locale = fallbackLng
) => {
const {
constants: { A, B, C, D },
} = Equations.supernovaDistance({});
const { latex, constants, result: resultConfig } = equation;
const { result, variables } = values;

const { format } = new Intl.NumberFormat(locale, {
minimumFractionDigits: 1,
maximumFractionDigits: 1,
});
const formattedConstants: Record<string, string> = {};
const formattedVariables: Record<string, string> = {};

const displayResult = isNumber(result)
? `${Intl.NumberFormat(locale, {
maximumSignificantDigits: 3,
}).format(result)}\\space\\text{Mly}`
: result;
const displayPeakAbsolute = isNumber(peakAbsoluteMagnitude)
? format(peakAbsoluteMagnitude)
: peakAbsoluteMagnitude;
const displayPeakApparent = isNumber(peakApparentMagnitude)
? format(peakApparentMagnitude)
: peakApparentMagnitude;
Object.entries(constants).map(([key, constant]) => {
formattedConstants[key] = formatConstant(constant, locale);
});

return `${withClass(displayResult)} = \\left (${Intl.NumberFormat(locale, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(
A
)}\\right )${B}^{\\frac{${displayPeakApparent} - ${displayPeakAbsolute}}{${C}} + ${D}}`;
};
Object.entries(variables).map(([key, variable]) => {
formattedVariables[key] = formatVariable({
variable,
config: Variables[key],
locale,
});
});

const LaTeX = {
peakAbsoluteMagnitude,
supernovaDistance,
return latex({
result: formatResult({ result, config: resultConfig, locale }),
constants: formattedConstants,
variables: formattedVariables,
});
};

export default LaTeX;
export default LaTeXComposer;
6 changes: 0 additions & 6 deletions components/calculators/lib/placeholders.ts

This file was deleted.

2 changes: 1 addition & 1 deletion public/localeStrings/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@
},
"calculators": {
"output": {
"supernovaDistance": "{{result}} Mega light-years",
"distanceMly": "{{result}} Mega light-years",
"peakAbsoluteMagnitude": "Peak absolute magnitude {{result}}"
}
}
Expand Down
Loading

0 comments on commit 9b8b89c

Please sign in to comment.