diff options
| author | aman333nolawz <amananudhiu@gmail.com> | 2026-03-02 21:49:13 +0530 |
|---|---|---|
| committer | aman333nolawz <amananudhiu@gmail.com> | 2026-03-02 21:49:13 +0530 |
| commit | d41eff9eccf66644c4c60f53cb516bf079937a28 (patch) | |
| tree | 248a0863a3181369f943d678ec4273911d35efac /src/content/blog/callouts-component | |
Using astro-erudite for static site generation
Diffstat (limited to 'src/content/blog/callouts-component')
| -rw-r--r-- | src/content/blog/callouts-component/banner.png | bin | 0 -> 94431 bytes | |||
| -rw-r--r-- | src/content/blog/callouts-component/index.mdx | 442 |
2 files changed, 442 insertions, 0 deletions
diff --git a/src/content/blog/callouts-component/banner.png b/src/content/blog/callouts-component/banner.png Binary files differnew file mode 100644 index 0000000..2ba53be --- /dev/null +++ b/src/content/blog/callouts-component/banner.png diff --git a/src/content/blog/callouts-component/index.mdx b/src/content/blog/callouts-component/index.mdx new file mode 100644 index 0000000..3d0bc25 --- /dev/null +++ b/src/content/blog/callouts-component/index.mdx @@ -0,0 +1,442 @@ +--- +title: 'v1.5.0: “A Callout Component for Nerds”' +description: 'A quick update introduces our first content-based component: the callout!' +date: 2025-04-24 +tags: ['v1.5.0'] +image: './banner.png' +authors: ['enscribe'] +--- + +import Callout from '@/components/Callout.astro' +import { Icon } from 'astro-icon/components' + +## Our (hesitantly) first content-based component + +This new version of astro-erudite, v1.5.0, introduces our first content-based component: the callout! I was a bit hesitant about adding this component because, frankly, the entire philosophy behind this project was to be as minimalistic as possible—I wanted to simply provide boilerplate to remove the "busy work" factor that often takes away from the writing process. + +However, just based on some blog posts I've seen that use this template, I felt like there would be a universal desire just to have this component around in the case where it'd be needed. The primary inspiration came when user [@rezaarezvan](https://github.com/rezaarezvan) sent in a PR to add their site, [rezaarezvan.com](https://rezaarezvan.com), to the examples section in the README. They had years upon years of accumulated notes and resources on their site, most of which were in the form of LaTeX-style academic content that requires "blocks" for things like definitions, theorems, and proofs. I sent in an encouraging reply to the PR and then started building the component: + +> [[@jktrn]](https://github.com/jktrn/astro-erudite/pull/29#issuecomment-2814894034) your blog posts are literally insane btw @rezaarezvan how have you written multiple textbooks worth of educational resources??? +> +> i think i might add latex-style theorem/lemma/corollary/def/proof/eg/ex/remark blocks to astro-erudite so i can accommodate for these academia-style blogs, like e.g. for exercises it'd just be a component with an expandable section to hide the answer + +### How does it work? + +I've added a simple `Callout.astro` to `src/components` that now comes shipped with the template. It's a very easy-to-read component that has an insanely long configuration scheme for all of the different types of callouts that I've added. Fundamentally, it follows the same paradigm as [shadcn/ui](https://ui.shadcn.com) which uses [class-variance-authority](https://cva.style/docs) to create different "variants" on top of a base styling scheme: + +```astro title="src/components/Callout.astro" collapse={12-126} {8-10,131} +--- +import { cn } from '@/lib/utils' +import { Icon } from 'astro-icon/components' +import { cva, type VariantProps } from 'class-variance-authority' + +const calloutConfig = { + note: { + style: 'border-blue-500 dark:bg-blue-950/5', + textColor: 'text-blue-700 dark:text-blue-300', + icon: 'lucide:info', + }, + tip: { + style: 'border-green-500 dark:bg-green-950/5', + textColor: 'text-green-700 dark:text-green-300', + icon: 'lucide:lightbulb', + }, + warning: { + style: 'border-amber-500 dark:bg-amber-950/5', + textColor: 'text-amber-700 dark:text-amber-300', + icon: 'lucide:alert-triangle', + }, + danger: { + style: 'border-red-500 dark:bg-red-950/5', + textColor: 'text-red-700 dark:text-red-300', + icon: 'lucide:shield-alert', + }, + important: { + style: 'border-purple-500 dark:bg-purple-950/5', + textColor: 'text-purple-700 dark:text-purple-300', + icon: 'lucide:message-square-warning', + }, + definition: { + style: 'border-purple-500 dark:bg-purple-950/5', + textColor: 'text-purple-700 dark:text-purple-300', + icon: 'lucide:book-open', + }, + theorem: { + style: 'border-teal-500 dark:bg-teal-950/5', + textColor: 'text-teal-700 dark:text-teal-300', + icon: 'lucide:check-circle', + }, + lemma: { + style: 'border-sky-400 dark:bg-sky-950/5', + textColor: 'text-sky-700 dark:text-sky-300', + icon: 'lucide:puzzle', + }, + proof: { + style: 'border-gray-500 dark:bg-gray-950/5', + textColor: 'text-gray-700 dark:text-gray-300', + icon: 'lucide:check-square', + }, + corollary: { + style: 'border-cyan-500 dark:bg-cyan-950/5', + textColor: 'text-cyan-700 dark:text-cyan-300', + icon: 'lucide:git-branch', + }, + proposition: { + style: 'border-slate-500 dark:bg-slate-950/5', + textColor: 'text-slate-700 dark:text-slate-300', + icon: 'lucide:file-text', + }, + axiom: { + style: 'border-violet-600 dark:bg-violet-950/5', + textColor: 'text-violet-700 dark:text-violet-300', + icon: 'lucide:anchor', + }, + conjecture: { + style: 'border-pink-500 dark:bg-pink-950/5', + textColor: 'text-pink-700 dark:text-pink-300', + icon: 'lucide:help-circle', + }, + notation: { + style: 'border-slate-400 dark:bg-slate-950/5', + textColor: 'text-slate-700 dark:text-slate-300', + icon: 'lucide:pen-tool', + }, + remark: { + style: 'border-gray-400 dark:bg-gray-950/5', + textColor: 'text-gray-700 dark:text-gray-300', + icon: 'lucide:message-circle', + }, + intuition: { + style: 'border-yellow-500 dark:bg-yellow-950/5', + textColor: 'text-yellow-700 dark:text-yellow-300', + icon: 'lucide:lightbulb', + }, + recall: { + style: 'border-blue-300 dark:bg-blue-950/5', + textColor: 'text-blue-600 dark:text-blue-300', + icon: 'lucide:rotate-ccw', + }, + explanation: { + style: 'border-lime-500 dark:bg-lime-950/5', + textColor: 'text-lime-700 dark:text-lime-300', + icon: 'lucide:help-circle', + }, + example: { + style: 'border-emerald-500 dark:bg-emerald-950/5', + textColor: 'text-emerald-700 dark:text-emerald-300', + icon: 'lucide:code', + }, + exercise: { + style: 'border-indigo-500 dark:bg-indigo-950/5', + textColor: 'text-indigo-700 dark:text-indigo-300', + icon: 'lucide:dumbbell', + }, + problem: { + style: 'border-orange-600 dark:bg-orange-950/5', + textColor: 'text-orange-700 dark:text-orange-300', + icon: 'lucide:alert-circle', + }, + answer: { + style: 'border-teal-500 dark:bg-teal-950/5', + textColor: 'text-teal-700 dark:text-teal-300', + icon: 'lucide:check', + }, + solution: { + style: 'border-emerald-600 dark:bg-emerald-950/5', + textColor: 'text-emerald-700 dark:text-emerald-300', + icon: 'lucide:check-circle-2', + }, + summary: { + style: 'border-sky-500 dark:bg-sky-950/5', + textColor: 'text-sky-700 dark:text-sky-300', + icon: 'lucide:list', + }, +} as const + +const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1) + +const calloutVariants = cva('relative px-4 py-3 my-6 border-l-4 text-sm', { + variants: { + variant: Object.fromEntries( + Object.entries(calloutConfig).map(([key, config]) => [key, config.style]), + ), + }, + defaultVariants: { + variant: 'note', + }, +}) +``` + +As such, if you feel like there's any variant that you're missing, it's insanely trivial to add it yourself. It's less trivial, however, to figure out what colors to use since I've essentially taken up every good Tailwind color for these! + +### How do I use these? + +Within any `src/content/blog/**/*.mdx` file, you can now use the `Callout` component by importing it like so underneath your frontmatter: + +```mdx title="src/content/blog/callouts-component/index.mdx" add={10} +--- +title: 'v1.5.0: “A Callout Component for Nerds”' +description: 'A quick update introduces our first content-based component: the callout!' +date: 2025-04-24 +tags: ['v1.5.0'] +image: './1200x630.png' +authors: ['enscribe'] +--- + +import Callout from '@/components/Callout.astro' +``` + +Then, you can use the component like so. This is just an example but you should actually read the text since it's relevant to the article: + +````mdx showLineNumbers=false collapse={3-11} +<Callout title="About Github-flavored alerts" variant="important"> + I know that Github typically uses the following syntax for "alerts" (which is what they call these callouts, you can see their documentation [here](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts)): + ```md showLineNumbers=false + > [!NOTE] + > Useful information that users should know, even when skimming content. + ``` + The above syntax is supposed to render like this: + <Callout> + Useful information that users should know, even when skimming content. + </Callout> + I believe they do this so they can keep you within the Markdown-like syntax system. However, since this is MDX, I thought we'd be better off just using the component paradigm since it's a bit impractical to make a rehype plugin that can parse this form of syntax (also, solutions for this already exist, such as [lin-stephanie/rehype-callouts](https://github.com/lin-stephanie/rehype-callouts)). Additionally, I find it a pain to work with the `>{:md}` (the `<blockquote>{:html}` indicators for Markdown) syntax, as it makes it difficult to nest things such as code blocks within them in pure Markdown. We'll use components for now! +</Callout> +```` + +<Callout title="About Github-flavored alerts" variant="important"> + I know that Github typically uses the following syntax for "alerts" (which is what they call these callouts, you can see their documentation [here](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts)): + ```md showLineNumbers=false + > [!NOTE] + > Useful information that users should know, even when skimming content. + ``` + The above syntax is supposed to render like this: + <Callout> + Useful information that users should know, even when skimming content. + </Callout> + I believe they do this so they can keep you within the Markdown-like syntax system. However, since this is MDX, I thought we'd be better off just using the component paradigm since it's a bit impractical to make a rehype plugin that can parse this form of syntax (also, solutions for this already exist, such as [lin-stephanie/rehype-callouts](https://github.com/lin-stephanie/rehype-callouts)). Additionally, I find it a pain to work with the `>{:md}` (the `<blockquote>{:html}` indicators for Markdown) syntax, as it makes it difficult to nest things such as code blocks within them in pure Markdown. We'll use components for now! +</Callout> + +Callout only supports three props: + +| Prop | Description | Default | +| ---- | ----------- | ------- | +| `title` | The title of the callout | `undefined{:js}` | +| `variant` | The variant of the callout | `"note"{:js}` | +| `defaultOpen` | Whether the callout `<details>{:html}` box is open by default | `true{:js}` | + +I've added an insane amount of variants to this component for potentially any use case you could think of. For the more general ones, you can use the following: + +<div class="[&_td]:align-middle"> +| Variant | Usage | +| ------- | ----- | +| <span class="flex items-center gap-2 border-blue-500 dark:bg-blue-950/10 text-blue-700 dark:text-blue-300 px-2 py-1 border-l-4"><Icon name="lucide:info" /> Note</span> | For general information or comments that don't fit other categories | +| <span class="flex items-center gap-2 border-green-500 dark:bg-green-950/10 text-green-700 dark:text-green-300 px-2 py-1 border-l-4"><Icon name="lucide:lightbulb" /> Tip</span> | For helpful advice or shortcuts related to the topic at hand | +| <span class="flex items-center gap-2 border-amber-500 dark:bg-amber-950/10 text-amber-700 dark:text-amber-300 px-2 py-1 border-l-4"><Icon name="lucide:alert-triangle" /> Warning</span> | For potential pitfalls or common misconceptions | +| <span class="flex items-center gap-2 border-red-500 dark:bg-red-950/10 text-red-700 dark:text-red-300 px-2 py-1 border-l-4"><Icon name="lucide:shield-alert" /> Danger</span> | For things that could potentially be destructive or harmful | +| <span class="flex items-center gap-2 border-purple-500 dark:bg-purple-950/10 text-purple-700 dark:text-purple-300 px-2 py-1 border-l-4"><Icon name="lucide:message-square-warning" /> Important</span> | For things that are important to the reader's understanding | +</div> + +For the potentially more academic/mathy folk, you can use the following. I've created specific variants that are tailor-made to be used alongside and/or nested into each other: + +<div class="[&_td]:align-middle"> +| Variant | Usage | +| ------- | ----- | +| <span class="flex items-center gap-2 border-purple-500 dark:bg-purple-950/10 text-purple-700 dark:text-purple-300 px-2 py-1 border-l-4"><Icon name="lucide:book-open" /> Definition</span> | For defining terms or concepts | +| <span class="flex items-center gap-2 border-teal-500 dark:bg-teal-950/10 text-teal-700 dark:text-teal-300 px-2 py-1 border-l-4"><Icon name="lucide:check-circle" /> Theorem</span> | For important mathematical or logical statements that have been proven | +| <span class="flex items-center gap-2 border-sky-400 dark:bg-sky-950/10 text-sky-700 dark:text-sky-300 px-2 py-1 border-l-4"><Icon name="lucide:puzzle" /> Lemma</span> | For helper theorems used in proving larger results | +| <span class="flex items-center gap-2 border-gray-500 dark:bg-gray-950/10 text-gray-700 dark:text-gray-300 px-2 py-1 border-l-4"><Icon name="lucide:check-square" /> Proof</span> | For logical arguments that establish the truth of a theorem or lemma | +| <span class="flex items-center gap-2 border-cyan-500 dark:bg-cyan-950/10 text-cyan-700 dark:text-cyan-300 px-2 py-1 border-l-4"><Icon name="lucide:git-branch" /> Corollary</span> | For results that follow directly from theorems | +| <span class="flex items-center gap-2 border-slate-500 dark:bg-slate-950/10 text-slate-700 dark:text-slate-300 px-2 py-1 border-l-4"><Icon name="lucide:file-text" /> Proposition</span> | For important statements that are less significant than theorems | +| <span class="flex items-center gap-2 border-violet-600 dark:bg-violet-950/10 text-violet-700 dark:text-violet-300 px-2 py-1 border-l-4"><Icon name="lucide:anchor" /> Axiom</span> | For fundamental assumptions that are accepted without proof | +| <span class="flex items-center gap-2 border-pink-500 dark:bg-pink-950/10 text-pink-700 dark:text-pink-300 px-2 py-1 border-l-4"><Icon name="lucide:help-circle" /> Conjecture</span> | For unproven statements believed to be true | +| <span class="flex items-center gap-2 border-slate-400 dark:bg-slate-950/10 text-slate-700 dark:text-slate-300 px-2 py-1 border-l-4"><Icon name="lucide:pen-tool" /> Notation</span> | For explaining mathematical notation | +| <span class="flex items-center gap-2 border-gray-400 dark:bg-gray-950/10 text-gray-700 dark:text-gray-300 px-2 py-1 border-l-4"><Icon name="lucide:message-circle" /> Remark</span> | For additional comments or (potentially out-of-scope) observations | +| <span class="flex items-center gap-2 border-yellow-500 dark:bg-yellow-950/10 text-yellow-700 dark:text-yellow-300 px-2 py-1 border-l-4"><Icon name="lucide:lightbulb" /> Intuition</span> | For explaining the intuitive reasoning behind concepts | +| <span class="flex items-center gap-2 border-blue-300 dark:bg-blue-950/10 text-blue-600 dark:text-blue-300 px-2 py-1 border-l-4"><Icon name="lucide:rotate-ccw" /> Recall</span> | For reminding readers of previously covered material | +| <span class="flex items-center gap-2 border-lime-500 dark:bg-lime-950/10 text-lime-700 dark:text-lime-300 px-2 py-1 border-l-4"><Icon name="lucide:help-circle" /> Explanation</span> | For providing deeper insights or clarifying complex topics | +| <span class="flex items-center gap-2 border-emerald-500 dark:bg-emerald-950/10 text-emerald-700 dark:text-emerald-300 px-2 py-1 border-l-4"><Icon name="lucide:code" /> Example</span> | For illustrating concepts with concrete examples or analogies | +| <span class="flex items-center gap-2 border-indigo-500 dark:bg-indigo-950/10 text-indigo-700 dark:text-indigo-300 px-2 py-1 border-l-4"><Icon name="lucide:dumbbell" /> Exercise</span> | For practice problems or take-home challenges for the reader | +| <span class="flex items-center gap-2 border-orange-600 dark:bg-orange-950/10 text-orange-700 dark:text-orange-300 px-2 py-1 border-l-4"><Icon name="lucide:alert-circle" /> Problem</span> | For presenting problems to be solved thoroughly | +| <span class="flex items-center gap-2 border-teal-500 dark:bg-teal-950/10 text-teal-700 dark:text-teal-300 px-2 py-1 border-l-4"><Icon name="lucide:check" /> Answer</span> | For providing simple, short answers to exercises or problems | +| <span class="flex items-center gap-2 border-emerald-600 dark:bg-emerald-950/10 text-emerald-700 dark:text-emerald-300 px-2 py-1 border-l-4"><Icon name="lucide:check-circle-2" /> Solution</span> | For detailed solutions to exercises or problems | +| <span class="flex items-center gap-2 border-sky-500 dark:bg-sky-950/10 text-sky-700 dark:text-sky-300 px-2 py-1 border-l-4"><Icon name="lucide:list" /> Summary</span> | For summarizing key points or concepts | +</div> + +## Generic callouts + +These are what the generic callouts look like (of course, all the text is made up): + +<Callout title="Prerequisites for advanced React development" variant="note"> + This tutorial assumes you're familiar with React hooks and the component lifecycle. If you need a refresher, check out the [official React documentation](https://reactjs.org/docs/hooks-intro.html) before proceeding. +</Callout> + +<Callout title="Productivity enhancement" variant="tip"> + You can quickly format your code by pressing <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>F</kbd> (Windows/Linux) or <kbd>Cmd</kbd> + <kbd>Option</kbd> + <kbd>F</kbd> (Mac). + + Additional shortcuts include: + + | Action | Windows/Linux | Mac | + | ------ | ------------- | --- | + | Search | <kbd>Ctrl</kbd> + <kbd>F</kbd> | <kbd>Cmd</kbd> + <kbd>F</kbd> | + | Replace | <kbd>Ctrl</kbd> + <kbd>H</kbd> | <kbd>Cmd</kbd> + <kbd>H</kbd> | + | Save all | <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>S</kbd> | <kbd>Cmd</kbd> + <kbd>Option</kbd> + <kbd>S</kbd> | +</Callout> + +<Callout title="Cross-browser compatibility issues" variant="warning"> + This API is **not supported** in Internet Explorer and has limited support in older browsers. Make sure to include appropriate polyfills. + + ```js title="polyfill.js" + if (!Object.fromEntries) { + Object.fromEntries = function(entries) { + const obj = {}; + for (const [key, value] of entries) { + obj[key] = value; + } + return obj; + }; + } + ``` + + See the [Browser Compatibility Table](#) for detailed information. +</Callout> + +<Callout title="Critical data loss risk" variant="danger"> + Running this command will **permanently delete** all files in your current directory. Make sure to back up important data before proceeding. + + ```bash title="danger.sh" + # This will delete everything in the current directory + rm -rf ./* + # Safer alternative with confirmation + rm -ri ./* + ``` + + This operation cannot be undone and recovery tools may not be able to restore your data. +</Callout> + +<Callout title="Major API changes in v2.0" variant="important"> + Version 2.0 introduces significant API changes. You'll need to update your existing code to use the new parameter structure. + + 1. The `configure(){:js}` method now returns a Promise + 2. Authentication requires an API key object instead of a string + 3. Event handlers use a new callback pattern + + A migration example looks like the following: + ```diff lang="js" + - app.configure("api-key-string"); + + await app.configure({ key: "api-key-string", version: "2.0" }); + + - app.on('event', callback); + + app.on('event', { handler: callback, options: { once: true } }); + ``` +</Callout> + +## Mathematical callouts + +Like I mentioned before, some of these variants are meant to be nested within each other. Take, for example, the following: + +<Callout title="Continuous function" variant="definition"> + A function $f: X \rightarrow Y$ between topological spaces is continuous if for every open set $V \subseteq Y$, the preimage $f^{-1}(V) \subseteq X$ is open in $X$. + + <Callout title="Equivalent formulations" variant="explanation"> + For metric spaces, continuity can be characterized by: $\forall \varepsilon > 0, \exists \delta > 0$ such that $d_X(x,y) < \delta \implies d_Y(f(x),f(y)) < \varepsilon$. This captures the intuition that points close to each other in $X$ map to points close to each other in $Y$. + </Callout> +</Callout> + +<Callout title="Law of Large Numbers" variant="theorem"> + Let $X_1, X_2, \ldots$ be a sequence of independent and identically distributed random variables with expected value $\mathbb{E}[X_i] = \mu < \infty$. Then for any $\varepsilon > 0$: + $$ + \lim_{n \to \infty} P\left(\left|\frac{1}{n}\sum_{i=1}^{n}X_i - \mu\right| > \varepsilon\right) = 0 + $$ + + <Callout title="Proof" variant="proof"> + We'll prove this using Chebyshev's inequality. Let $S_n = \sum_{i=1}^{n}X_i$ and $\sigma^2 = \text{Var}(X_i)$. By Chebyshev's inequality: + $$ + P\left(\left|\frac{S_n}{n} - \mu\right| \geq \varepsilon\right) \leq \frac{\text{Var}(S_n/n)}{\varepsilon^2} + $$ + + Since the variables are independent, we have: + $$ + \text{Var}(S_n/n) = \frac{\text{Var}(S_n)}{n^2} = \frac{n\sigma^2}{n^2} = \frac{\sigma^2}{n} + $$ + + Substituting this into our inequality: + $$ + P\left(\left|\frac{S_n}{n} - \mu\right| \geq \varepsilon\right) \leq \frac{\sigma^2}{n\varepsilon^2} + $$ + + As $n \to \infty$, the right side approaches 0, which proves the theorem. + </Callout> +</Callout> + +<Callout title="Monotone Convergence Theorem" variant="lemma"> + Let $(f_n)$ be a sequence of non-negative measurable functions such that $f_n(x) \leq f_{n+1}(x)$ for all $n \in \mathbb{N}$ and almost all $x$. Define $f(x) = \lim_{n \to \infty} f_n(x)$. Then: + $$ + \lim_{n \to \infty} \int f_n \, d\mu = \int f \, d\mu + $$ + + <Callout title="Proof" variant="proof"> + Let $g_n = f_n \cdot \chi_E$ where $E = \{x : f(x) < \infty\}$. By Fatou's lemma: + $$ + \int f \, d\mu = \int \lim_{n \to \infty} g_n \, d\mu \leq \liminf_{n \to \infty} \int g_n \, d\mu = \liminf_{n \to \infty} \int f_n \, d\mu + $$ + + For the reverse inequality, note that $f_n \leq f$ for all $n$, so $\int f_n \, d\mu \leq \int f \, d\mu$. Taking the limit: + $$ + \limsup_{n \to \infty} \int f_n \, d\mu \leq \int f \, d\mu + $$ + + Combining these inequalities: + $$ + \int f \, d\mu \leq \liminf_{n \to \infty} \int f_n \, d\mu \leq \limsup_{n \to \infty} \int f_n \, d\mu \leq \int f \, d\mu + $$ + + Therefore, $\lim_{n \to \infty} \int f_n \, d\mu = \int f \, d\mu$. + </Callout> +</Callout> + +I'll add this little subgenre of variant called "example-based" callouts that have more generally a question-answer format. For the "exercise-answer" pairing, the difference is that I'd recommend you default the answer to a closed state to hide the answer from any peeping readers until they've actually done the work themselves. Typically, the difference between an "Answer" and a "Solution" is that the answer basically just gives you the final answer, while the solution will show you the steps it takes to get to the answer: + +<Callout title="Finding the derivative of a product function" variant="exercise"> + Calculate the derivative of $f(x) = x^3 \sin(x)$ using the product rule. + + <Callout variant="answer" defaultOpen={false}> + $$ + \frac{d}{dx}[x^3 \sin(x)] = 3x^2 \sin(x) + x^3 \cos(x) + $$ + </Callout> +</Callout> + +<Callout title="Convergence of arithmetic means" variant="problem"> + Prove that if a sequence $(a_n)$ converges to $L$, then the sequence of arithmetic means $(\frac{a_1 + a_2 + \ldots + a_n}{n})$ also converges to $L$. + + <Callout title="Detailed proof" variant="solution"> + Let $\varepsilon > 0$ be given. Since $(a_n)$ converges to $L$, there exists $N \in \mathbb{N}$ such that $|a_n - L| < \frac{\varepsilon}{2}$ for all $n \geq N$. Let $S_n = \frac{a_1 + a_2 + \ldots + a_n}{n}$ be the sequence of arithmetic means. + + We can split $S_n$ as follows: + $$ + S_n = \frac{a_1 + a_2 + \ldots + a_N + a_{N+1} + \ldots + a_n}{n} + $$ + + For $n > N$, we have: + $$ + \begin{align*} + |S_n - L| &= \left|\frac{a_1 + a_2 + \ldots + a_n}{n} - L\right| \\ + &= \left|\frac{a_1 + a_2 + \ldots + a_n - nL}{n}\right| \\ + &= \left|\frac{(a_1 - L) + (a_2 - L) + \ldots + (a_n - L)}{n}\right| \\ + &\leq \frac{|a_1 - L| + |a_2 - L| + \ldots + |a_N - L| + |a_{N+1} - L| + \ldots + |a_n - L|}{n} + \end{align*} + $$ + + Let $M = \max\{|a_1 - L|, |a_2 - L|, \ldots, |a_N - L|\}$. Then: + $$ + |S_n - L| \leq \frac{NM + (n-N)\frac{\varepsilon}{2}}{n} = \frac{NM}{n} + \frac{n-N}{n} \cdot \frac{\varepsilon}{2} + $$ + + As $n \to \infty$, $\frac{NM}{n} \to 0$ and $\frac{n-N}{n} \to 1$. So for sufficiently large $n$, we have: + $$ + |S_n - L| < \varepsilon + $$ + + Therefore, the sequence of arithmetic means converges to $L$. + </Callout> +</Callout> |
