Skip to content

Commit

Permalink
Allow learners to use any locale's trig operators in the Expression w…
Browse files Browse the repository at this point in the history
…idget (#1006)

Previously, learners had to use the English versions of trig operators like
`tan` and `csc`, no matter what language they were learning in. This was
awkward because different languages use different names for these operators,
e.g. `tg` and `cosec`.

This commit updates the expression widget so learners can use the operators for
their locale.

Issue: https://khanacademy.atlassian.net/browse/LC-1632

## Test plan:

```
GIVEN I am looking at an expression widget (e.g. on Test Everything)
WHEN I type any of the trig operators listed in the spreadsheet linked from the Jira issue
THEN the operator is displayed in an upright font

GIVEN I have typed the correct answer to a trig problem using operators appropriate to my locale
WHEN I submit the answer
THEN it is accepted as correct
```

Author: benchristel

Reviewers: jeremywiebe

Required Reviewers:

Approved By: jeremywiebe

Checks: ✅ codecov/project, ✅ codecov/patch, ✅ Upload Coverage, ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Lint, Typecheck, Format, and Test (ubuntu-latest, 20.x), ✅ Extract i18n strings (ubuntu-latest, 20.x), ✅ Cypress (ubuntu-latest, 20.x), ✅ Jest Coverage (ubuntu-latest, 20.x), ✅ Publish Storybook to Chromatic (ubuntu-latest, 20.x), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ Check builds for changes in size (ubuntu-latest, 20.x), ✅ gerald

Pull Request URL: #1006
  • Loading branch information
benchristel authored Feb 20, 2024
1 parent f8432af commit 17c38bf
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 11 deletions.
6 changes: 6 additions & 0 deletions .changeset/soft-pans-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@khanacademy/math-input": minor
"@khanacademy/perseus": minor
---

Allow learners to type trig operators in any language in the Expression widget
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ const createBaseConfig = (): MathFieldConfig => ({
"arccos",
"arcsin",
"arctan",
"arctg",
"arg",
"cos",
"cosec",
"cossec",
"cosh",
"cot",
"cotg",
"coth",
"csc",
"ctg",
"deg",
"det",
"dim",
Expand All @@ -58,6 +63,7 @@ const createBaseConfig = (): MathFieldConfig => ({
"sup",
"tan",
"tanh",
"tg",
].join(" "),

// Pop the cursor out of super/subscripts on arithmetic operators
Expand Down
52 changes: 42 additions & 10 deletions packages/perseus/src/widgets/__tests__/expression.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,6 @@ describe("Expression Widget", function () {
const item = expressionItemWithAnswer("sin(x)");
assertIncorrect(item, "2");
});

it("treats sen as equivalent to sin", () => {
const item = expressionItemWithAnswer("sin(x)");
assertCorrect(item, "sen x");
});

it("treats multiple usages of sen as equivalent to sin", () => {
const item = expressionItemWithAnswer("sin(sin(x))");
assertCorrect(item, "sen(sen(x))");
});
});

describe("analytics", () => {
Expand Down Expand Up @@ -256,6 +246,48 @@ describe("Expression Widget", function () {
assertKeypadVersion(Object.freeze({}), "MATH_INPUT_KEYPAD_V2");
});
});

describe("international trig operators", () => {
it("treats sen as equivalent to sin", () => {
const item = expressionItemWithAnswer("sin(x)");
assertCorrect(item, "sen x");
});

it("works when multiple operators are present", () => {
const item = expressionItemWithAnswer("sin(sin(x))");
assertCorrect(item, "sen(sen(x))");
});

it("treats arctg as equivalent to arctan", () => {
const item = expressionItemWithAnswer("arctan(x)");
assertCorrect(item, "arctg x");
});

it("treats cosec as equivalent to csc", () => {
const item = expressionItemWithAnswer("csc(x)");
assertCorrect(item, "cosec x");
});

it("treats cossec as equivalent to csc", () => {
const item = expressionItemWithAnswer("csc(x)");
assertCorrect(item, "cossec x");
});

it("treats cotg as equivalent to cot", () => {
const item = expressionItemWithAnswer("cot(x)");
assertCorrect(item, "cotg x");
});

it("treats ctg as equivalent to cot", () => {
const item = expressionItemWithAnswer("cot(x)");
assertCorrect(item, "ctg x");
});

it("treats tg as equivalent to tan", () => {
const item = expressionItemWithAnswer("tan(x)");
assertCorrect(item, "tg x");
});
});
});

describe("getOneCorrectAnswerFromRubric", () => {
Expand Down
16 changes: 15 additions & 1 deletion packages/perseus/src/widgets/expression.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,25 @@ type InputPath = ReadonlyArray<string>;
const ERROR_TITLE = i18n._("Oops!");
const ERROR_MESSAGE = i18n._("Sorry, I don't understand that!");

// Map of international operator names to their English equivalents
const englishOperators = {
arctg: "arctan",
cosec: "csc",
cossec: "csc",
cotg: "cot",
ctg: "cot",
sen: "sin",
tg: "tan",
};

const anglicizeOperators = (tex: string): string => {
// sen is used instead of sin in some languages, e.g. Portuguese.
// To ensure that answers in various languages are graded correctly, we
// convert operators to their Englishy forms.
return tex.replace(/\\operatorname{sen}/g, "\\sin ");
return tex.replace(
/\\operatorname{([a-z]+)}/g,
(_, op) => `\\${englishOperators[op] ?? op} `,
);
};

const normalizeTex = (tex: string): string => {
Expand Down

0 comments on commit 17c38bf

Please sign in to comment.