inflection games started

This commit is contained in:
lingdocs 2022-09-12 20:59:45 +04:00
parent ce7c477218
commit d40cf10144
8 changed files with 200 additions and 58 deletions

View File

@ -7,7 +7,7 @@
"@formkit/auto-animate": "^1.0.0-beta.1", "@formkit/auto-animate": "^1.0.0-beta.1",
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@lingdocs/lingdocs-main": "^0.3.3", "@lingdocs/lingdocs-main": "^0.3.3",
"@lingdocs/pashto-inflector": "^3.9.0", "@lingdocs/pashto-inflector": "^3.9.4",
"@testing-library/jest-dom": "^5.11.4", "@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10", "@testing-library/user-event": "^12.1.10",

View File

@ -101,8 +101,6 @@ import * as directionalPronouns from "!babel-loader!@lingdocs/mdx-loader!./prono
import * as inflectionIntro from "!babel-loader!@lingdocs/mdx-loader!./inflection/inflection-intro.mdx"; import * as inflectionIntro from "!babel-loader!@lingdocs/mdx-loader!./inflection/inflection-intro.mdx";
// @ts-ignore // @ts-ignore
import * as inflectionPatterns from "!babel-loader!@lingdocs/mdx-loader!./inflection/inflection-patterns.mdx"; import * as inflectionPatterns from "!babel-loader!@lingdocs/mdx-loader!./inflection/inflection-patterns.mdx";
// @ts-ignore
import * as feminineInflection from "!babel-loader!@lingdocs/mdx-loader!./inflection/feminine-inflection.mdx";
// @ts-ignore // @ts-ignore
import * as sandwiches from "!babel-loader!@lingdocs/mdx-loader!./sandwiches/sandwiches.mdx"; import * as sandwiches from "!babel-loader!@lingdocs/mdx-loader!./sandwiches/sandwiches.mdx";
@ -360,10 +358,6 @@ const contentTree: (ChapterSection | ChaptersSection)[] = [
import: inflectionPatterns, import: inflectionPatterns,
slug: "inflection-patterns", slug: "inflection-patterns",
}, },
{
import: feminineInflection,
slug: "feminine-inflection",
},
], ],
}, },
{ {

View File

@ -1,44 +0,0 @@
---
title: Feminine Inflection Patterns
---
<!--
Copyright (c) 2021 lingdocs.com
The content of the chapters/book is licensed by a
Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0)
https://creativecommons.org/licenses/by-sa/4.0/
https://creativecommons.org/licenses/by-sa/4.0/legalcode
-->
import {
defaultTextOptions as opts,
Examples,
InlinePs,
grammarUnits,
removeFVarients,
InflectionsTable,
inflectWord,
typePredicates as tp,
} from "@lingdocs/pashto-inflector";
import shuffle from "../../lib/shuffle-array";
import InflectionCarousel from "../../components/InflectionCarousel";
import { nouns } from "../../words/words";
import Link from "../../components/Link";
import Table from "../../components/Table";
import { startingWord } from "../../lib/starting-word";
export const femNouns = nouns.filter(tp.isFemNounEntry);
The <Link to="/inflection/inflection-patterns/">5 basic patterns in the last chapter</Link> work with both masculine and feminine words (nouns and adjectives).
There are also a few more patterns that are only for **feminine nouns**.
## Feminine Nouns Ending in ي - ee
<InflectionCarousel items={startingWord(femNouns.filter(tp.isPattern6FemEntry), "آزادي")} />
**Note:** This only works with **inanimate nouns**. (ie. words for people like <InlinePs opts={opts} ps={{ p: "باجي", f: "baajée", e: "older sister" }} /> will not inflect like this.)

View File

@ -32,12 +32,18 @@ export const words = [
...nouns.filter(tp.isUnisexNounEntry), ...nouns.filter(tp.isUnisexNounEntry),
...adjectives, ...adjectives,
]; ];
export const femNouns = nouns.filter(tp.isFemNounEntry);
import {
inflectionPatternsGame1,
inflectionPatternsGame2,
} from "../../games/games";
import GameDisplay from "../../games/GameDisplay";
In the <Link to="/inflection/inflection-intro/">previous chapter</Link> we talked about **why** words inflect. Now we will explain **how** words inflect. What actualy happens to them? How do they change? In the <Link to="/inflection/inflection-intro/">previous chapter</Link> we talked about **why** words inflect. Now we will explain **how** words inflect. What actualy happens to them? How do they change?
Like many things in Pashto, inflection can seem mysterious and intimidating. Why do the words change so much, and how!? 😩 But, we'll see that there are just a few basic patterns that the words follow, and it's not so scary or confusing after all. Like many things in Pashto, inflection can seem mysterious and intimidating. Why do the words change so much, and how!? 😩 But, we'll see that there are just a few basic patterns that the words follow, and it's not so scary or confusing after all.
Below are the **5 basic patterns for inflecting** nouns and adjectives. Notice how all these patterns work with both masculine and feminine genders. Below are the **6 basic patterns for inflecting** nouns and adjectives. Notice how all these patterns work with both masculine and feminine genders.
Don't worry about memorizing them all perfectly to start. Instead keep looking back and use them as guides to help you as you get familiar with the inflections over time. Don't worry about memorizing them all perfectly to start. Instead keep looking back and use them as guides to help you as you get familiar with the inflections over time.
@ -94,9 +100,17 @@ These are also a little irregular but instead of lengthening the 1st masculine i
"غل", "غل",
)} /> )} />
## 6. Inanimate feminine nouns ending in ي - ee
There is one more pattern which only works for **inanimate feminine nouns ending in <InlinePs opts={opts} ps={{ p: "ي", f: "ee", e: "" }} />**.
<InflectionCarousel items={startingWord(femNouns.filter(tp.isPattern6FemEntry), "آزادي")} />
Animate nouns like <InlinePs opts={opts} ps={{ p: "بي بي", f: "beebee", e: "grandmother" }} /> will not inflect like this, and masculine nouns like <InlinePs ps={{ p: "قاضي", f: "qaazee", e: "judge" }} opts={opts} /> also will not inflect.
## Not all words inflect ## Not all words inflect
It's important to know that *not all words can be inflected*. If a word doesn't fit into one of these 5 patterns, you can't inflect it. For example, if an adjective ends in an <InlinePs opts={opts} ps={{ p: "ـه", f: "-a" }} /> in the masculine form, you can't inflect it because it doesn't fit any of the patterns above. 🙅‍♂️ It's important to know that *not all words can be inflected*. If a word doesn't fit into one of these 6 patterns, you can't inflect it. For example, if an adjective ends in an <InlinePs opts={opts} ps={{ p: "ـه", f: "-a" }} /> in the masculine form, you can't inflect it because it doesn't fit any of the patterns above. 🙅‍♂️
<Examples opts={opts}>{[ <Examples opts={opts}>{[
{ p: "خفه", f: "khufa", e: "sad", sub: "...is also sad because it can't inflect like all the other words 😢" }, { p: "خفه", f: "khufa", e: "sad", sub: "...is also sad because it can't inflect like all the other words 😢" },
@ -210,3 +224,7 @@ But these words will *always* use the first inflection for the plural.
e: "This is **the Pashtuns'** custom" e: "This is **the Pashtuns'** custom"
}, },
])}</Examples> ])}</Examples>
<GameDisplay record={inflectionPatternsGame1} />
<GameDisplay record={inflectionPatternsGame2} />

View File

@ -6,6 +6,7 @@ import EquativeSituations from "./sub-cores/EquativeSituations";
import VerbSituations from "./sub-cores/VerbSituations"; import VerbSituations from "./sub-cores/VerbSituations";
import EquativeIdentify from "./sub-cores/EquativeIdentify"; import EquativeIdentify from "./sub-cores/EquativeIdentify";
import VerbFormulas from "./sub-cores/VerbFormulas"; import VerbFormulas from "./sub-cores/VerbFormulas";
import InflectionPatterns from "./sub-cores/InflectionPatterns";
// NOUNS // NOUNS
export const nounGenderGame1 = makeGameRecord({ export const nounGenderGame1 = makeGameRecord({
@ -30,6 +31,22 @@ export const unisexNounGame = makeGameRecord({
SubCore: UnisexNounGame, SubCore: UnisexNounGame,
}); });
// INFLECTIONS
export const inflectionPatternsGame1 = makeGameRecord({
title: "Identify the inflection pattern (Level 1)",
id: "inflection-patterns-1",
link: "/inflection/inflection-patterns/",
level: 1,
SubCore: InflectionPatterns,
});
export const inflectionPatternsGame2 = makeGameRecord({
title: "Identify the inflection pattern (Level 2)",
id: "inflection-patterns-2",
link: "/inflection/inflection-patterns/",
level: 2,
SubCore: InflectionPatterns,
});
// EQUATIVES // EQUATIVES
export const equativeGamePresent = makeGameRecord({ export const equativeGamePresent = makeGameRecord({
title: "Write the present equative", title: "Write the present equative",
@ -288,6 +305,13 @@ const games: { chapter: string, items: GameRecord[] }[] = [
unisexNounGame, unisexNounGame,
], ],
}, },
{
chapter: "Inflection",
items: [
inflectionPatternsGame1,
inflectionPatternsGame2,
],
},
{ {
chapter: "Equatives", chapter: "Equatives",
items: [ items: [

View File

@ -0,0 +1,150 @@
import GameCore from "../GameCore";
import {
Types as T,
getInflectionPattern,
Examples,
defaultTextOptions as opts,
firstVariation,
} from "@lingdocs/pashto-inflector";
import { makePool } from "../../lib/pool";
import { nouns, adjectives } from "../../words/words";
import * as tp from "@lingdocs/pashto-inflector/dist/lib/type-predicates";
const amount = 20;
const timeLimit = 150;
type Question = {
entry: T.NounEntry | T.AdjectiveEntry,
pattern: T.InflectionPattern,
}
const categories: { label: string, value: T.InflectionPattern }[] = [
{
label: "#1 Basic",
value: T.InflectionPattern.Basic,
},
{
label: "#2 Unstressed ی",
value: T.InflectionPattern.UnstressedEy,
},
{
label: "#3 Stressed ی",
value: T.InflectionPattern.StressedEy,
},
{
label: `#4 "Pashtoon"`,
value: T.InflectionPattern.Pashtun,
},
{
label: `#5 Short Squish`,
value: T.InflectionPattern.Squish,
},
{
label: "#6 Inan. Fem. ي",
value: T.InflectionPattern.FemInanEe,
},
{
label: "No Inflection",
value: T.InflectionPattern.None,
},
];
export default function InflectionPatterns({ inChapter, id, link, level }: { inChapter: boolean, id: string, link: string, level: 1 | 2 }) {
const w = [...nouns, ...adjectives]
.filter(level === 2 ? x => x : x => (tp.isUnisexNounEntry(x) || tp.isAdjectiveEntry(x) || (tp.isFemNounEntry(x) && tp.isPattern6FemEntry(x))))
.map(x => ({ entry: x, pattern: getInflectionPattern(x) }));
const words: Record<T.InflectionPattern, (T.NounEntry | T.AdjectiveEntry)[]> = {
0: w.filter(x => x.pattern === 0).map(x => x.entry),
1: w.filter(x => x.pattern === 1).map(x => x.entry),
2: w.filter(x => x.pattern === 2).map(x => x.entry),
3: w.filter(x => x.pattern === 3).map(x => x.entry),
4: w.filter(x => x.pattern === 4).map(x => x.entry),
5: w.filter(x => x.pattern === 5).map(x => x.entry),
6: w.filter(x => x.pattern === 6).map(x => x.entry),
};
const pools: Record<T.InflectionPattern, () => (T.NounEntry | T.AdjectiveEntry)> = {
0: makePool(words[0]),
1: makePool(words[1]),
2: makePool(words[2]),
3: makePool(words[3]),
4: makePool(words[4]),
5: makePool(words[5]),
6: makePool(words[6]),
}
const patternPool = makePool([
T.InflectionPattern.None,
T.InflectionPattern.Basic,
T.InflectionPattern.UnstressedEy,
T.InflectionPattern.StressedEy,
T.InflectionPattern.Pashtun,
T.InflectionPattern.Squish,
T.InflectionPattern.FemInanEe,
]);
function getQuestion(): Question {
const pattern = patternPool();
const entry = pools[pattern]();
if (getInflectionPattern(entry) !== pattern) {
throw Error("wrong pattern on word");
}
return { entry, pattern };
};
function Display({ question, callback }: QuestionDisplayProps<Question>) {
function handleChoice(ic: T.InflectionPattern) {
return callback(ic === question.pattern);
}
return <div>
<div className="mb-2" style={{ maxWidth: "300px", margin: "0 auto" }}>
<Examples opts={opts}>{[
{
p: firstVariation(question.entry.p),
f: firstVariation(question.entry.f),
e: `${firstVariation(question.entry.e)} - ${question.entry.c}`,
}
]}</Examples>
</div>
<div className="text-center">
<div className="row">
{categories.map(c => <div className="col" key={Math.random()}>
<button
style={{ width: "8rem", height: "4rem" }}
className="btn btn-outline-secondary mb-3"
onClick={() => handleChoice(c.value)}
>
{c.label}
</button>
</div>)}
</div>
</div>
</div>
}
function Instructions() {
return <div>
<p className="lead">Choose the inflection pattern that each noun/adjective follows</p>
</div>
}
return <GameCore
inChapter={inChapter}
studyLink={link}
getQuestion={getQuestion}
id={id}
Display={Display}
DisplayCorrectAnswer={DisplayCorrectAnswer}
timeLimit={timeLimit}
amount={amount}
Instructions={Instructions}
/>
};
function DisplayCorrectAnswer({ question }: { question: Question }): JSX.Element {
// callback(<div className="lead">
// {possibleCorrect.map(humanReadableTense).join(" or ")}
// </div>)
return <div>
<p className="lead">{categories.find(c => c.value === question.pattern)?.label}</p>
</div>;
}

View File

@ -1804,10 +1804,10 @@
rambda "^6.7.0" rambda "^6.7.0"
react-select "^5.2.2" react-select "^5.2.2"
"@lingdocs/pashto-inflector@^3.9.0": "@lingdocs/pashto-inflector@^3.9.4":
version "3.9.0" version "3.9.4"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-3.9.0.tgz#abcea34db1d7031e7915c1bc6281b88df6c8ca2b" resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-3.9.4.tgz#b85bd8b9c235da1b77a04bd4178be91371a94726"
integrity sha512-6KARwTVmt/qJaOrvIbQlQhIfseB0sM9HrfWGpkRUQZK4eGmo6Qpnne8PBJQe1CQZCuAKgDjpwDHz3CssFIOegA== integrity sha512-bthgBbzkFHIYUOTFNUNcwWFuhCkFlX7RCPQIbZdXFPOdUoEGtlngqJkECKm+pIShQioEGuMxhW0plhXDIccA8w==
dependencies: dependencies:
"@formkit/auto-animate" "^1.0.0-beta.1" "@formkit/auto-animate" "^1.0.0-beta.1"
classnames "^2.2.6" classnames "^2.2.6"