diff --git a/README.md b/README.md index 13183a257..7f6d19af7 100644 --- a/README.md +++ b/README.md @@ -31,13 +31,23 @@ Follow these steps to get started using these resources: [Arabic](./translations/ar/README.md) | [Bengali](./translations/bn/README.md) | [Bulgarian](./translations/bg/README.md) | [Burmese (Myanmar)](./translations/my/README.md) | [Chinese (Simplified)](./translations/zh-CN/README.md) | [Chinese (Traditional, Hong Kong)](./translations/zh-HK/README.md) | [Chinese (Traditional, Macau)](./translations/zh-MO/README.md) | [Chinese (Traditional, Taiwan)](./translations/zh-TW/README.md) | [Croatian](./translations/hr/README.md) | [Czech](./translations/cs/README.md) | [Danish](./translations/da/README.md) | [Dutch](./translations/nl/README.md) | [Estonian](./translations/et/README.md) | [Finnish](./translations/fi/README.md) | [French](./translations/fr/README.md) | [German](./translations/de/README.md) | [Greek](./translations/el/README.md) | [Hebrew](./translations/he/README.md) | [Hindi](./translations/hi/README.md) | [Hungarian](./translations/hu/README.md) | [Indonesian](./translations/id/README.md) | [Italian](./translations/it/README.md) | [Japanese](./translations/ja/README.md) | [Kannada](./translations/kn/README.md) | [Korean](./translations/ko/README.md) | [Lithuanian](./translations/lt/README.md) | [Malay](./translations/ms/README.md) | [Malayalam](./translations/ml/README.md) | [Marathi](./translations/mr/README.md) | [Nepali](./translations/ne/README.md) | [Nigerian Pidgin](./translations/pcm/README.md) | [Norwegian](./translations/no/README.md) | [Persian (Farsi)](./translations/fa/README.md) | [Polish](./translations/pl/README.md) | [Portuguese (Brazil)](./translations/pt-BR/README.md) | [Portuguese (Portugal)](./translations/pt-PT/README.md) | [Punjabi (Gurmukhi)](./translations/pa/README.md) | [Romanian](./translations/ro/README.md) | [Russian](./translations/ru/README.md) | [Serbian (Cyrillic)](./translations/sr/README.md) | [Slovak](./translations/sk/README.md) | [Slovenian](./translations/sl/README.md) | [Spanish](./translations/es/README.md) | [Swahili](./translations/sw/README.md) | [Swedish](./translations/sv/README.md) | [Tagalog (Filipino)](./translations/tl/README.md) | [Tamil](./translations/ta/README.md) | [Telugu](./translations/te/README.md) | [Thai](./translations/th/README.md) | [Turkish](./translations/tr/README.md) | [Ukrainian](./translations/uk/README.md) | [Urdu](./translations/ur/README.md) | [Vietnamese](./translations/vi/README.md) > **Prefer to Clone Locally?** - +> > This repository includes 50+ language translations which significantly increases the download size. To clone without translations, use sparse checkout: +> +> **Bash / macOS / Linux:** > ```bash > git clone --filter=blob:none --sparse https://github.com/microsoft/Web-Dev-For-Beginners.git > cd Web-Dev-For-Beginners > git sparse-checkout set --no-cone '/*' '!translations' '!translated_images' > ``` +> +> **CMD (Windows):** +> ```cmd +> git clone --filter=blob:none --sparse https://github.com/microsoft/Web-Dev-For-Beginners.git +> cd Web-Dev-For-Beginners +> git sparse-checkout set --no-cone "/*" "!translations" "!translated_images" +> ``` +> > This gives you everything you need to complete the course with a much faster download. diff --git a/translated_images/1.b6da8c1394b07491afeb6b2a8e5aca73ebd3cf478e27bcc9aeabb187e722648e.en.png b/translated_images/1.b6da8c1394b07491afeb6b2a8e5aca73ebd3cf478e27bcc9aeabb187e722648e.en.png deleted file mode 100644 index 4148c1017..000000000 Binary files a/translated_images/1.b6da8c1394b07491afeb6b2a8e5aca73ebd3cf478e27bcc9aeabb187e722648e.en.png and /dev/null differ diff --git a/translated_images/1.cc07a5cbe114ad1d4728c35134584ac1b87db688eff83cf75985cf31fe0ed95c.en.png b/translated_images/1.cc07a5cbe114ad1d4728c35134584ac1b87db688eff83cf75985cf31fe0ed95c.en.png deleted file mode 100644 index e89ba6168..000000000 Binary files a/translated_images/1.cc07a5cbe114ad1d4728c35134584ac1b87db688eff83cf75985cf31fe0ed95c.en.png and /dev/null differ diff --git a/translated_images/2.1dae52ff0804224692cd648afbf2342955d7afe3b0101b617268130dfb427f55.en.png b/translated_images/2.1dae52ff0804224692cd648afbf2342955d7afe3b0101b617268130dfb427f55.en.png deleted file mode 100644 index 78a6fb81c..000000000 Binary files a/translated_images/2.1dae52ff0804224692cd648afbf2342955d7afe3b0101b617268130dfb427f55.en.png and /dev/null differ diff --git a/translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.en.png b/translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.en.png deleted file mode 100644 index 6e5a9ef91..000000000 Binary files a/translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.en.png and /dev/null differ diff --git a/translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.en.png b/translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.en.png deleted file mode 100644 index 474ed4017..000000000 Binary files a/translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.en.png and /dev/null differ diff --git a/translated_images/backgroundColor.e19c3c60768150c8de229c89233ecb5d859aeabef0ada99d2236dd2c44c1510f.en.png b/translated_images/backgroundColor.e19c3c60768150c8de229c89233ecb5d859aeabef0ada99d2236dd2c44c1510f.en.png deleted file mode 100644 index 3bd93a532..000000000 Binary files a/translated_images/backgroundColor.e19c3c60768150c8de229c89233ecb5d859aeabef0ada99d2236dd2c44c1510f.en.png and /dev/null differ diff --git a/translated_images/browser-console.efaf0b51aaaf67782a29e1a0bb32cc063f189b18e894eb5926e02f1abe864ec2.en.png b/translated_images/browser-console.efaf0b51aaaf67782a29e1a0bb32cc063f189b18e894eb5926e02f1abe864ec2.en.png deleted file mode 100644 index ad9341a4b..000000000 Binary files a/translated_images/browser-console.efaf0b51aaaf67782a29e1a0bb32cc063f189b18e894eb5926e02f1abe864ec2.en.png and /dev/null differ diff --git a/translated_images/browser.60317c9be8b7f84adce43e30bff8d47a1ae15793beab762317b2bc6b74337c1a.en.jpg b/translated_images/browser.60317c9be8b7f84adce43e30bff8d47a1ae15793beab762317b2bc6b74337c1a.en.jpg deleted file mode 100644 index 06fa7e91e..000000000 Binary files a/translated_images/browser.60317c9be8b7f84adce43e30bff8d47a1ae15793beab762317b2bc6b74337c1a.en.jpg and /dev/null differ diff --git a/translated_images/canvas.fbd605ff8e5b8aff567d398528ce113db304446b90b9cad55c654de3fdfcda34.en.png b/translated_images/canvas.fbd605ff8e5b8aff567d398528ce113db304446b90b9cad55c654de3fdfcda34.en.png deleted file mode 100644 index b42a0d08a..000000000 Binary files a/translated_images/canvas.fbd605ff8e5b8aff567d398528ce113db304446b90b9cad55c654de3fdfcda34.en.png and /dev/null differ diff --git a/translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.en.png b/translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.en.png deleted file mode 100644 index 0076f9c5d..000000000 Binary files a/translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.en.png and /dev/null differ diff --git a/translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.en.png b/translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.en.png deleted file mode 100644 index 9f3e12884..000000000 Binary files a/translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.en.png and /dev/null differ diff --git a/translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.en.png b/translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.en.png deleted file mode 100644 index ccc65305d..000000000 Binary files a/translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.en.png and /dev/null differ diff --git a/translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.en.png b/translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.en.png deleted file mode 100644 index 42cd07021..000000000 Binary files a/translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.en.png and /dev/null differ diff --git a/translated_images/clone_repo.6a202fb230ab6bdd8e8f536661f12088315044ed26899f00b5815db04bff9217.en.png b/translated_images/clone_repo.6a202fb230ab6bdd8e8f536661f12088315044ed26899f00b5815db04bff9217.en.png deleted file mode 100644 index 3220a0f9f..000000000 Binary files a/translated_images/clone_repo.6a202fb230ab6bdd8e8f536661f12088315044ed26899f00b5815db04bff9217.en.png and /dev/null differ diff --git a/translated_images/codespace.bcecbdf5d2747d3d17da67a78ad911c8853d68102e34748ec372cde1e9236e1d.en.png b/translated_images/codespace.bcecbdf5d2747d3d17da67a78ad911c8853d68102e34748ec372cde1e9236e1d.en.png deleted file mode 100644 index 48934523f..000000000 Binary files a/translated_images/codespace.bcecbdf5d2747d3d17da67a78ad911c8853d68102e34748ec372cde1e9236e1d.en.png and /dev/null differ diff --git a/translated_images/create-a-fork.297ab42b4bd0af9989c1a00dc1ad10805a7e109296a5f47acebacaf5ff098a30.en.png b/translated_images/create-a-fork.297ab42b4bd0af9989c1a00dc1ad10805a7e109296a5f47acebacaf5ff098a30.en.png deleted file mode 100644 index f0a6fa895..000000000 Binary files a/translated_images/create-a-fork.297ab42b4bd0af9989c1a00dc1ad10805a7e109296a5f47acebacaf5ff098a30.en.png and /dev/null differ diff --git a/translated_images/create-new-file-pb.0797800d977ec3ebf484be2545060e443a902973aaa5267219c07fe199b0e2d4.en.png b/translated_images/create-new-file-pb.0797800d977ec3ebf484be2545060e443a902973aaa5267219c07fe199b0e2d4.en.png deleted file mode 100644 index aaa3fe3ce..000000000 Binary files a/translated_images/create-new-file-pb.0797800d977ec3ebf484be2545060e443a902973aaa5267219c07fe199b0e2d4.en.png and /dev/null differ diff --git a/translated_images/create-new-file.2814e609c2af9aeb6c6fd53156c503ac91c3d538f9cac63073b2dd4a7631f183.en.png b/translated_images/create-new-file.2814e609c2af9aeb6c6fd53156c503ac91c3d538f9cac63073b2dd4a7631f183.en.png deleted file mode 100644 index a1fb99b56..000000000 Binary files a/translated_images/create-new-file.2814e609c2af9aeb6c6fd53156c503ac91c3d538f9cac63073b2dd4a7631f183.en.png and /dev/null differ diff --git a/translated_images/createcodespace.0238bbf4d7a8d955fa8fa7f7b6602a3cb6499a24708fbee589f83211c5a613b7.en.png b/translated_images/createcodespace.0238bbf4d7a8d955fa8fa7f7b6602a3cb6499a24708fbee589f83211c5a613b7.en.png deleted file mode 100644 index 99e0f52a2..000000000 Binary files a/translated_images/createcodespace.0238bbf4d7a8d955fa8fa7f7b6602a3cb6499a24708fbee589f83211c5a613b7.en.png and /dev/null differ diff --git a/translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.en.png b/translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.en.png deleted file mode 100644 index 67291b688..000000000 Binary files a/translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.en.png and /dev/null differ diff --git a/translated_images/default-vscode-dev.5d06881d65c1b3234ce50cd9ed3b0028e6031ad5f5b441bcbed96bfa6311f6d0.en.png b/translated_images/default-vscode-dev.5d06881d65c1b3234ce50cd9ed3b0028e6031ad5f5b441bcbed96bfa6311f6d0.en.png deleted file mode 100644 index 2dec44d47..000000000 Binary files a/translated_images/default-vscode-dev.5d06881d65c1b3234ce50cd9ed3b0028e6031ad5f5b441bcbed96bfa6311f6d0.en.png and /dev/null differ diff --git a/translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.en.png b/translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.en.png deleted file mode 100644 index d4bd5400b..000000000 Binary files a/translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.en.png and /dev/null differ diff --git a/translated_images/dom-tree.7daf0e763cbbba9273f9a66fe04c98276d7d23932309b195cb273a9cf1819b42.en.png b/translated_images/dom-tree.7daf0e763cbbba9273f9a66fe04c98276d7d23932309b195cb273a9cf1819b42.en.png deleted file mode 100644 index 6de176274..000000000 Binary files a/translated_images/dom-tree.7daf0e763cbbba9273f9a66fe04c98276d7d23932309b195cb273a9cf1819b42.en.png and /dev/null differ diff --git a/translated_images/earlybrowsers.d984b711cdf3a42ddac919d46c4b5ca7232f68ccfbd81395e04e5a64c0015277.en.jpg b/translated_images/earlybrowsers.d984b711cdf3a42ddac919d46c4b5ca7232f68ccfbd81395e04e5a64c0015277.en.jpg deleted file mode 100644 index 321b64882..000000000 Binary files a/translated_images/earlybrowsers.d984b711cdf3a42ddac919d46c4b5ca7232f68ccfbd81395e04e5a64c0015277.en.jpg and /dev/null differ diff --git a/translated_images/edit-a-file-pb.263555922c14fc523f53f394da84b6e155b1c6d1835dfa572b33ea98a209ef94.en.png b/translated_images/edit-a-file-pb.263555922c14fc523f53f394da84b6e155b1c6d1835dfa572b33ea98a209ef94.en.png deleted file mode 100644 index b324f620d..000000000 Binary files a/translated_images/edit-a-file-pb.263555922c14fc523f53f394da84b6e155b1c6d1835dfa572b33ea98a209ef94.en.png and /dev/null differ diff --git a/translated_images/edit-a-file.52c0ee665ef19f08119d62d63f395dfefddc0a4deb9268d73bfe791f52c5807a.en.png b/translated_images/edit-a-file.52c0ee665ef19f08119d62d63f395dfefddc0a4deb9268d73bfe791f52c5807a.en.png deleted file mode 100644 index 2558533fa..000000000 Binary files a/translated_images/edit-a-file.52c0ee665ef19f08119d62d63f395dfefddc0a4deb9268d73bfe791f52c5807a.en.png and /dev/null differ diff --git a/translated_images/en/.co-op-translator.json b/translated_images/en/.co-op-translator.json new file mode 100644 index 000000000..245e9b0a4 --- /dev/null +++ b/translated_images/en/.co-op-translator.json @@ -0,0 +1,860 @@ +{ + "1.b6da8c1394b07491.webp": { + "original_hash": "6b12479c2e6a54160867fa8945c04082", + "translation_date": "2026-03-06T11:52:51+00:00", + "source_file": "5-browser-extension/1-about-browsers/images/1.png", + "language_code": "en" + }, + "1.cc07a5cbe114ad1d.webp": { + "original_hash": "fc436b6749801dd90d0558ae92d56b60", + "translation_date": "2026-03-06T11:54:08+00:00", + "source_file": "3-terrarium/2-intro-to-css/images/1.png", + "language_code": "en" + }, + "2.1dae52ff08042246.webp": { + "original_hash": "3995628a6a986308859d0cb6eed8d787", + "translation_date": "2026-03-06T11:52:43+00:00", + "source_file": "5-browser-extension/1-about-browsers/images/2.png", + "language_code": "en" + }, + "after-codeswing-extension-pb.0ebddddcf73b5509.webp": { + "original_hash": "861d59ec65a7334c5f3a4c02dfe22ceb", + "translation_date": "2026-03-06T11:51:34+00:00", + "source_file": "8-code-editor/images/after-codeswing-extension-pb.png", + "language_code": "en" + }, + "background.148a8d43afde5730.webp": { + "original_hash": "5a50f015fb466782c69063ffebb256de", + "translation_date": "2026-03-06T11:49:32+00:00", + "source_file": "images/background.png", + "language_code": "en" + }, + "backgroundColor.e19c3c60768150c8.webp": { + "original_hash": "b3e10fe033f615ec9d3580cce61eae09", + "translation_date": "2026-03-06T11:52:21+00:00", + "source_file": "6-space-game/solution/spaceArt/png/Background/backgroundColor.png", + "language_code": "en" + }, + "browser-console.efaf0b51aaaf6778.webp": { + "original_hash": "8d6c5077d1f133d27c65c0014ef503a9", + "translation_date": "2026-03-06T11:53:03+00:00", + "source_file": "7-bank-project/2-forms/images/browser-console.png", + "language_code": "en" + }, + "browser.60317c9be8b7f84a.webp": { + "original_hash": "aa4461fec006d86899864d991b50cc74", + "translation_date": "2026-03-06T11:49:42+00:00", + "source_file": "sketchnotes/browser.jpg", + "language_code": "en" + }, + "canvas.fbd605ff8e5b8aff.webp": { + "original_hash": "29556305738d345dd023554d788d5477", + "translation_date": "2026-03-06T11:49:13+00:00", + "source_file": "teaching-files/canvas.png", + "language_code": "en" + }, + "canvas_grid.5f209da785ded492.webp": { + "original_hash": "8da354720ffbfd778571aa17402de890", + "translation_date": "2026-03-06T11:52:12+00:00", + "source_file": "6-space-game/2-drawing-to-canvas/canvas_grid.png", + "language_code": "en" + }, + "character.5c0dd8e067ffd693.webp": { + "original_hash": "076bbb4d25a17982c81973b8dba9d4fa", + "translation_date": "2026-03-06T11:49:27+00:00", + "source_file": "images/character.png", + "language_code": "en" + }, + "click-register.e89a30bf0d4bc9ca.webp": { + "original_hash": "ef9688313524664fad6ab9b0e080c758", + "translation_date": "2026-03-06T11:52:57+00:00", + "source_file": "7-bank-project/2-forms/images/click-register.png", + "language_code": "en" + }, + "clone_repo.5085c48d666ead57.webp": { + "original_hash": "28c00f3d5861ab95d188b4f6a2d337df", + "translation_date": "2026-03-06T11:54:10+00:00", + "source_file": "1-getting-started-lessons/2-github-basics/images/clone_repo.png", + "language_code": "en" + }, + "clone_repo.6a202fb230ab6bdd.webp": { + "original_hash": "9261d014674312eece91deae958538cf", + "translation_date": "2026-03-06T11:49:29+00:00", + "source_file": "images/clone_repo.png", + "language_code": "en" + }, + "codespace.bcecbdf5d2747d3d.webp": { + "original_hash": "ff86a65511122ddb448e092969566b0a", + "translation_date": "2026-03-06T11:54:12+00:00", + "source_file": "9-chat-project/assets/codespace.png", + "language_code": "en" + }, + "create-a-fork.297ab42b4bd0af99.webp": { + "original_hash": "10712b80e3dcfa7c44fb8820a6ff3ad3", + "translation_date": "2026-03-06T11:51:36+00:00", + "source_file": "8-code-editor/images/create-a-fork.png", + "language_code": "en" + }, + "create-new-file-pb.0797800d977ec3eb.webp": { + "original_hash": "c149c42e04132f2409651425d6924ffa", + "translation_date": "2026-03-06T11:51:07+00:00", + "source_file": "8-code-editor/images/create-new-file-pb.png", + "language_code": "en" + }, + "create-new-file.2814e609c2af9aeb.webp": { + "original_hash": "cf6df76faeac2d92904e5d877b7bdf69", + "translation_date": "2026-03-06T11:51:04+00:00", + "source_file": "8-code-editor/images/create-new-file.png", + "language_code": "en" + }, + "createcodespace.0238bbf4d7a8d955.webp": { + "original_hash": "4f504323085308f4a0e7b5bfb37e16d7", + "translation_date": "2026-03-06T11:49:25+00:00", + "source_file": "images/createcodespace.png", + "language_code": "en" + }, + "data-flow.fa2354e0908fecc8.webp": { + "original_hash": "c9b82b42fa1973b3b7bfad9c7128c24c", + "translation_date": "2026-03-06T11:53:09+00:00", + "source_file": "7-bank-project/4-state-management/images/data-flow.png", + "language_code": "en" + }, + "default-vscode-dev.5d06881d65c1b323.webp": { + "original_hash": "146fecc3a9da37cb1d5c9d628cd94996", + "translation_date": "2026-03-06T11:51:53+00:00", + "source_file": "8-code-editor/images/default-vscode-dev.png", + "language_code": "en" + }, + "dialog.93bba104afeb79f1.webp": { + "original_hash": "c56b5ad7eb8c4df4b3ed8a99bf67e6e2", + "translation_date": "2026-03-06T11:53:09+00:00", + "source_file": "7-bank-project/4-state-management/images/dialog.png", + "language_code": "en" + }, + "dom-tree.7daf0e763cbbba92.webp": { + "original_hash": "579f4ae298ff15a357def7f442671847", + "translation_date": "2026-03-06T11:53:15+00:00", + "source_file": "3-terrarium/3-intro-to-DOM-and-closures/images/dom-tree.png", + "language_code": "en" + }, + "earlybrowsers.d984b711cdf3a42d.webp": { + "original_hash": "810a4d2348668e25289029c5cfcb67bd", + "translation_date": "2026-03-06T11:52:40+00:00", + "source_file": "5-browser-extension/1-about-browsers/images/earlybrowsers.jpg", + "language_code": "en" + }, + "edit-a-file-pb.263555922c14fc52.webp": { + "original_hash": "5c52723d35259eadd110d0c720a87b04", + "translation_date": "2026-03-06T11:51:49+00:00", + "source_file": "8-code-editor/images/edit-a-file-pb.png", + "language_code": "en" + }, + "edit-a-file.52c0ee665ef19f08.webp": { + "original_hash": "c28903236d60be6bba3f3848ea368c63", + "translation_date": "2026-03-06T11:52:11+00:00", + "source_file": "8-code-editor/images/edit-a-file.png", + "language_code": "en" + }, + "enemyShip.035a46787bff658c.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:17+00:00", + "source_file": "6-space-game/5-keeping-score/solution/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.1a1354d7988de290.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:16+00:00", + "source_file": "6-space-game/6-end-condition/solution/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.22cbee6ea27a5809.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:14+00:00", + "source_file": "6-space-game/2-drawing-to-canvas/your-work/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.321ecb1b4eb21f2c.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:16+00:00", + "source_file": "6-space-game/5-keeping-score/your-work/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.4fbf2889e6129db4.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:15+00:00", + "source_file": "6-space-game/6-end-condition/your-work/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.5df2a822c16650c2.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:14+00:00", + "source_file": "6-space-game/2-drawing-to-canvas/solution/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.62983ed4bfb2220f.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:23+00:00", + "source_file": "6-space-game/3-moving-elements-around/solution/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.add7036e1c3c3014.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:14+00:00", + "source_file": "6-space-game/4-collision-detection/solution/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.b39a140287683bf7.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:23+00:00", + "source_file": "6-space-game/3-moving-elements-around/your-work/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.b9626ed228a17a32.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:13+00:00", + "source_file": "6-space-game/4-collision-detection/your-work/assets/enemyShip.png", + "language_code": "en" + }, + "enemyShip.deb0477a7312f54d.webp": { + "original_hash": "2a41854e0eaa974e8619298f3b333e11", + "translation_date": "2026-03-06T11:52:19+00:00", + "source_file": "6-space-game/solution/spaceArt/png/enemyShip.png", + "language_code": "en" + }, + "enemyUFO.bf8585e4e8dcdb68.webp": { + "original_hash": "18198bef76e4882928e4092344d0fb98", + "translation_date": "2026-03-06T11:52:20+00:00", + "source_file": "6-space-game/solution/spaceArt/png/enemyUFO.png", + "language_code": "en" + }, + "extension-details.9f8f1fd4e9eb2de5.webp": { + "original_hash": "f57d2e246e6ba8a58463d7573640d714", + "translation_date": "2026-03-06T11:52:09+00:00", + "source_file": "8-code-editor/images/extension-details.png", + "language_code": "en" + }, + "extension-screenshot.0e7f5bfa110e92e3.webp": { + "original_hash": "4fdd1d3fdbc9ac2c2932f83847a5e4b8", + "translation_date": "2026-03-06T11:49:23+00:00", + "source_file": "5-browser-extension/extension-screenshot.png", + "language_code": "en" + }, + "extension-settings.21c752ae4f4cdb78.webp": { + "original_hash": "fd7ebcb5d84c78047026ab3337908306", + "translation_date": "2026-03-06T11:51:13+00:00", + "source_file": "8-code-editor/images/extension-settings.png", + "language_code": "en" + }, + "extensions.eca0e0c7f59a10b5.webp": { + "original_hash": "a6c9c8f51d3edd917262e53664f08441", + "translation_date": "2026-03-06T11:51:38+00:00", + "source_file": "8-code-editor/images/extensions.png", + "language_code": "en" + }, + "favicon.37b561214b36d454.webp": { + "original_hash": "228faa6584f8ba1f7e9a75e3200112e9", + "translation_date": "2026-03-06T11:49:25+00:00", + "source_file": "images/favicon.png", + "language_code": "en" + }, + "form-post.61de4ca1b964d91a.webp": { + "original_hash": "7e95c76a8ea2e82bceea70aae89f2360", + "translation_date": "2026-03-06T11:52:59+00:00", + "source_file": "7-bank-project/2-forms/images/form-post.png", + "language_code": "en" + }, + "history.7fdabbafa521e064.webp": { + "original_hash": "445d71bea6a747dfe547df7eea846439", + "translation_date": "2026-03-06T11:52:52+00:00", + "source_file": "7-bank-project/1-template-route/history.png", + "language_code": "en" + }, + "install-on-edge.78634f02842c4828.webp": { + "original_hash": "6224aad8f1cd252da83c2808ff5c7a4e", + "translation_date": "2026-03-06T11:49:17+00:00", + "source_file": "5-browser-extension/install-on-edge.png", + "language_code": "en" + }, + "install-on-edge.d68781acaf0b3d3d.webp": { + "original_hash": "6224aad8f1cd252da83c2808ff5c7a4e", + "translation_date": "2026-03-06T11:52:48+00:00", + "source_file": "5-browser-extension/1-about-browsers/images/install-on-edge.png", + "language_code": "en" + }, + "laserGreen.89904f0f49945560.webp": { + "original_hash": "ddf7102c86fc3ec46037714c60091851", + "translation_date": "2026-03-06T11:52:19+00:00", + "source_file": "6-space-game/solution/spaceArt/png/laserGreen.png", + "language_code": "en" + }, + "laserGreenShot.e4fbfc4714c08a5b.webp": { + "original_hash": "cb6ed500c16736a41998e4cd0c467df7", + "translation_date": "2026-03-06T11:52:19+00:00", + "source_file": "6-space-game/solution/spaceArt/png/laserGreenShot.png", + "language_code": "en" + }, + "laserRed.2040e11f55c0a40a.webp": { + "original_hash": "6f0626e9839beb9d9a82ff40699aabfd", + "translation_date": "2026-03-06T11:52:15+00:00", + "source_file": "6-space-game/6-end-condition/solution/assets/laserRed.png", + "language_code": "en" + }, + "laserRed.381bc5555491ce67.webp": { + "original_hash": "6f0626e9839beb9d9a82ff40699aabfd", + "translation_date": "2026-03-06T11:52:23+00:00", + "source_file": "6-space-game/3-moving-elements-around/your-work/assets/laserRed.png", + "language_code": "en" + }, + "laserRed.69730edd76f0b3bd.webp": { + "original_hash": "6f0626e9839beb9d9a82ff40699aabfd", + "translation_date": "2026-03-06T11:52:15+00:00", + "source_file": "6-space-game/6-end-condition/your-work/assets/laserRed.png", + "language_code": "en" + }, + "laserRed.b583dc1728eb8581.webp": { + "original_hash": "6f0626e9839beb9d9a82ff40699aabfd", + "translation_date": "2026-03-06T11:52:17+00:00", + "source_file": "6-space-game/5-keeping-score/solution/assets/laserRed.png", + "language_code": "en" + }, + "laserRed.cae9ab24ea9b18fd.webp": { + "original_hash": "6f0626e9839beb9d9a82ff40699aabfd", + "translation_date": "2026-03-06T11:52:13+00:00", + "source_file": "6-space-game/4-collision-detection/solution/assets/laserRed.png", + "language_code": "en" + }, + "laserRed.d81ce4986f87c251.webp": { + "original_hash": "6f0626e9839beb9d9a82ff40699aabfd", + "translation_date": "2026-03-06T11:52:18+00:00", + "source_file": "6-space-game/solution/spaceArt/png/laserRed.png", + "language_code": "en" + }, + "laserRed.e58ef8db2585dfbe.webp": { + "original_hash": "6f0626e9839beb9d9a82ff40699aabfd", + "translation_date": "2026-03-06T11:52:16+00:00", + "source_file": "6-space-game/5-keeping-score/your-work/assets/laserRed.png", + "language_code": "en" + }, + "laserRed.e66e29ace6666064.webp": { + "original_hash": "6f0626e9839beb9d9a82ff40699aabfd", + "translation_date": "2026-03-06T11:52:23+00:00", + "source_file": "6-space-game/3-moving-elements-around/solution/assets/laserRed.png", + "language_code": "en" + }, + "laserRed.e86e8fb629c6026e.webp": { + "original_hash": "6f0626e9839beb9d9a82ff40699aabfd", + "translation_date": "2026-03-06T11:52:13+00:00", + "source_file": "6-space-game/4-collision-detection/your-work/assets/laserRed.png", + "language_code": "en" + }, + "laserRedShot.c39d066745996a71.webp": { + "original_hash": "1f1048184aab9d405e9f7d067a57af01", + "translation_date": "2026-03-06T11:52:19+00:00", + "source_file": "6-space-game/solution/spaceArt/png/laserRedShot.png", + "language_code": "en" + }, + "life.27144b6d4bfdea76.webp": { + "original_hash": "9a5d93e699071693b15b7b157f760a90", + "translation_date": "2026-03-06T11:52:19+00:00", + "source_file": "6-space-game/solution/spaceArt/png/life.png", + "language_code": "en" + }, + "life.2a159298dd98f4ef.webp": { + "original_hash": "9a5d93e699071693b15b7b157f760a90", + "translation_date": "2026-03-06T11:52:16+00:00", + "source_file": "6-space-game/5-keeping-score/your-work/assets/life.png", + "language_code": "en" + }, + "life.466df3b1692a244a.webp": { + "original_hash": "9a5d93e699071693b15b7b157f760a90", + "translation_date": "2026-03-06T11:52:13+00:00", + "source_file": "6-space-game/4-collision-detection/your-work/assets/life.png", + "language_code": "en" + }, + "life.65a2aaceca875284.webp": { + "original_hash": "9a5d93e699071693b15b7b157f760a90", + "translation_date": "2026-03-06T11:52:14+00:00", + "source_file": "6-space-game/4-collision-detection/solution/assets/life.png", + "language_code": "en" + }, + "life.6fb9f50d53ee0413.webp": { + "original_hash": "9a5d93e699071693b15b7b157f760a90", + "translation_date": "2026-03-06T11:52:17+00:00", + "source_file": "6-space-game/5-keeping-score/solution/assets/life.png", + "language_code": "en" + }, + "life.78b6e96a3003767e.webp": { + "original_hash": "9a5d93e699071693b15b7b157f760a90", + "translation_date": "2026-03-06T11:52:15+00:00", + "source_file": "6-space-game/6-end-condition/your-work/assets/life.png", + "language_code": "en" + }, + "life.86d843ce9c23289c.webp": { + "original_hash": "9a5d93e699071693b15b7b157f760a90", + "translation_date": "2026-03-06T11:52:16+00:00", + "source_file": "6-space-game/6-end-condition/solution/assets/life.png", + "language_code": "en" + }, + "localstorage.472f8147b6a3f8d1.webp": { + "original_hash": "7706ccb87a13a08250f315f03140bc61", + "translation_date": "2026-03-06T11:52:26+00:00", + "source_file": "5-browser-extension/2-forms-browsers-local-storage/images/localstorage.png", + "language_code": "en" + }, + "log.804026979f3707e0.webp": { + "original_hash": "4c5e39f339781db01641b77b6b2d6026", + "translation_date": "2026-03-06T11:52:37+00:00", + "source_file": "5-browser-extension/3-background-tasks-and-performance/images/log.png", + "language_code": "en" + }, + "login-error.416fe019b36a6327.webp": { + "original_hash": "ea96ed372d7a4c37ee2df3f0352f79d1", + "translation_date": "2026-03-06T11:53:04+00:00", + "source_file": "7-bank-project/3-data/images/login-error.png", + "language_code": "en" + }, + "meteorBig.1e452b3ad7af50ad.webp": { + "original_hash": "07f37816512f563dd68780fdee2e30a6", + "translation_date": "2026-03-06T11:52:18+00:00", + "source_file": "6-space-game/solution/spaceArt/png/meteorBig.png", + "language_code": "en" + }, + "meteorSmall.0d729bc71c12d41f.webp": { + "original_hash": "ebabf6690cc614f9e33f019c356166fa", + "translation_date": "2026-03-06T11:52:18+00:00", + "source_file": "6-space-game/solution/spaceArt/png/meteorSmall.png", + "language_code": "en" + }, + "moodle.94eb93d714a50cb2.webp": { + "original_hash": "0d04a6ef1ac524b452d5a0aae3f45bee", + "translation_date": "2026-03-06T11:49:05+00:00", + "source_file": "teaching-files/moodle.png", + "language_code": "en" + }, + "mpa.7f7375a1a2d4aa77.webp": { + "original_hash": "021255b74f0b79b0c286c163c210ef3d", + "translation_date": "2026-03-06T11:53:05+00:00", + "source_file": "7-bank-project/3-data/images/mpa.png", + "language_code": "en" + }, + "nebula.55c2933d36d035d3.webp": { + "original_hash": "e0fa4f86653c6fe97bc77271c46241c2", + "translation_date": "2026-03-06T11:52:22+00:00", + "source_file": "6-space-game/solution/spaceArt/png/Background/nebula.png", + "language_code": "en" + }, + "new-file-github.com.c886796d800e8056.webp": { + "original_hash": "2e0ddd0dad4734e3968b70907df9c052", + "translation_date": "2026-03-06T11:51:58+00:00", + "source_file": "8-code-editor/images/new-file-github.com.png", + "language_code": "en" + }, + "open-palette-menu.46dda01084738da8.webp": { + "original_hash": "1860e80bf0534b9d54ef0fcb7e1a9f9e", + "translation_date": "2026-03-06T11:51:51+00:00", + "source_file": "8-code-editor/images/open-palette-menu.png", + "language_code": "en" + }, + "open-remote-repository.bd9c2598b8949e7f.webp": { + "original_hash": "777c01a9242da7d5d0e1b037df9c86f9", + "translation_date": "2026-03-06T11:51:36+00:00", + "source_file": "8-code-editor/images/open-remote-repository.png", + "language_code": "en" + }, + "palette-menu.4946174e07f42622.webp": { + "original_hash": "7387b91076790084ec8828866e88c6ce", + "translation_date": "2026-03-06T11:51:50+00:00", + "source_file": "8-code-editor/images/palette-menu.png", + "language_code": "en" + }, + "partI-solution.36c53b48c9ffae2a.webp": { + "original_hash": "fbbd263368f61f8ed3a86c4571e6810b", + "translation_date": "2026-03-06T11:52:12+00:00", + "source_file": "6-space-game/2-drawing-to-canvas/partI-solution.png", + "language_code": "en" + }, + "plant1.a876180d8659acb9.webp": { + "original_hash": "e08f9b0f46f6d9d7c9949d4c3e590694", + "translation_date": "2026-03-06T11:53:34+00:00", + "source_file": "3-terrarium/solution/images/plant1.png", + "language_code": "en" + }, + "plant10.2f2c47804ae52dd3.webp": { + "original_hash": "dba97454882c2796c52a33c403db61f7", + "translation_date": "2026-03-06T11:53:49+00:00", + "source_file": "3-terrarium/solution/images/plant10.png", + "language_code": "en" + }, + "plant11.0ce0081b0ef17aa1.webp": { + "original_hash": "68346dbd1ae03331b0a87025c3e8e9e2", + "translation_date": "2026-03-06T11:53:45+00:00", + "source_file": "3-terrarium/solution/images/plant11.png", + "language_code": "en" + }, + "plant12.6b934c4312a00228.webp": { + "original_hash": "dafacde8e7a0b56c4baaabe88b4f90e2", + "translation_date": "2026-03-06T11:54:06+00:00", + "source_file": "3-terrarium/solution/images/plant12.png", + "language_code": "en" + }, + "plant13.37d6ab2e2481421f.webp": { + "original_hash": "5cac561d7596ee631c4d02436d8f6998", + "translation_date": "2026-03-06T11:53:53+00:00", + "source_file": "3-terrarium/solution/images/plant13.png", + "language_code": "en" + }, + "plant14.908791477a46eb7f.webp": { + "original_hash": "349b8e5a33d1221bef4a4ac3bb439bb9", + "translation_date": "2026-03-06T11:53:38+00:00", + "source_file": "3-terrarium/solution/images/plant14.png", + "language_code": "en" + }, + "plant2.9e45efea224115b0.webp": { + "original_hash": "24beefd3dcca66085b44d3ae5d9758e1", + "translation_date": "2026-03-06T11:54:04+00:00", + "source_file": "3-terrarium/solution/images/plant2.png", + "language_code": "en" + }, + "plant3.06efdd0fa0c4b115.webp": { + "original_hash": "7e40e6f14cf52f7d75ed42320817b044", + "translation_date": "2026-03-06T11:53:59+00:00", + "source_file": "3-terrarium/solution/images/plant3.png", + "language_code": "en" + }, + "plant4.3b78072b427727c6.webp": { + "original_hash": "c523205855d0691a9a0161c6abca983c", + "translation_date": "2026-03-06T11:53:56+00:00", + "source_file": "3-terrarium/solution/images/plant4.png", + "language_code": "en" + }, + "plant5.8ec58b18ac336fa8.webp": { + "original_hash": "bcf5f2eacd7da3fe6b07c857d7f5a2ce", + "translation_date": "2026-03-06T11:54:01+00:00", + "source_file": "3-terrarium/solution/images/plant5.png", + "language_code": "en" + }, + "plant6.ca4ff8372e6676b1.webp": { + "original_hash": "6932fdb455fcae5b324b129367d2f56a", + "translation_date": "2026-03-06T11:53:41+00:00", + "source_file": "3-terrarium/solution/images/plant6.png", + "language_code": "en" + }, + "plant7.194d5a42fcf5a88c.webp": { + "original_hash": "b7a1e35f9946cb04440ce620c34f201d", + "translation_date": "2026-03-06T11:53:21+00:00", + "source_file": "3-terrarium/solution/images/plant7.png", + "language_code": "en" + }, + "plant8.7b247809ab0eb492.webp": { + "original_hash": "3eb38c747aaf33ce7aa70b58a31b62a8", + "translation_date": "2026-03-06T11:53:32+00:00", + "source_file": "3-terrarium/solution/images/plant8.png", + "language_code": "en" + }, + "plant9.8fe614c01ded1b1e.webp": { + "original_hash": "a9655c162938a27c63d48ac675061e2b", + "translation_date": "2026-03-06T11:53:25+00:00", + "source_file": "3-terrarium/solution/images/plant9.png", + "language_code": "en" + }, + "player.137ee0e47f895ffc.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:16+00:00", + "source_file": "6-space-game/6-end-condition/solution/assets/player.png", + "language_code": "en" + }, + "player.2887422f6982c3cd.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:16+00:00", + "source_file": "6-space-game/5-keeping-score/your-work/assets/player.png", + "language_code": "en" + }, + "player.391fed427ede24f5.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:17+00:00", + "source_file": "6-space-game/5-keeping-score/solution/assets/player.png", + "language_code": "en" + }, + "player.3c4f50182552a73a.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:23+00:00", + "source_file": "6-space-game/3-moving-elements-around/your-work/assets/player.png", + "language_code": "en" + }, + "player.47bc9de0714c723d.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:14+00:00", + "source_file": "6-space-game/2-drawing-to-canvas/your-work/assets/player.png", + "language_code": "en" + }, + "player.57b3107c03012695.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:19+00:00", + "source_file": "6-space-game/solution/spaceArt/png/player.png", + "language_code": "en" + }, + "player.606f85953e5e564e.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:15+00:00", + "source_file": "6-space-game/6-end-condition/your-work/assets/player.png", + "language_code": "en" + }, + "player.680ea4c619b54fe1.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:13+00:00", + "source_file": "6-space-game/4-collision-detection/your-work/assets/player.png", + "language_code": "en" + }, + "player.bfe14f110bddf56d.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:23+00:00", + "source_file": "6-space-game/3-moving-elements-around/solution/assets/player.png", + "language_code": "en" + }, + "player.c99c25d54a615ca0.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:14+00:00", + "source_file": "6-space-game/4-collision-detection/solution/assets/player.png", + "language_code": "en" + }, + "player.dd24c1afa8c71e9b.webp": { + "original_hash": "952e66c2dd458cfd6e82052f7123a97b", + "translation_date": "2026-03-06T11:52:15+00:00", + "source_file": "6-space-game/2-drawing-to-canvas/solution/assets/player.png", + "language_code": "en" + }, + "playerDamaged.181703f652fd5176.webp": { + "original_hash": "9d71aebe7303edd536064fb0f5e2ae82", + "translation_date": "2026-03-06T11:52:20+00:00", + "source_file": "6-space-game/solution/spaceArt/png/playerDamaged.png", + "language_code": "en" + }, + "playerLeft.0f928412e66ba5d9.webp": { + "original_hash": "40a42047b8ee49c6dd87c981e98d4d2e", + "translation_date": "2026-03-06T11:52:21+00:00", + "source_file": "6-space-game/solution/spaceArt/png/playerLeft.png", + "language_code": "en" + }, + "playerRight.e4825f489e29f737.webp": { + "original_hash": "1c7b03f73e1d6ed74955357680cb05cb", + "translation_date": "2026-03-06T11:52:21+00:00", + "source_file": "6-space-game/solution/spaceArt/png/playerRight.png", + "language_code": "en" + }, + "playground-choice.1d23ba7d407f4758.webp": { + "original_hash": "1c2e88cad7aad10922b4de1e87f1a47f", + "translation_date": "2026-03-06T11:54:20+00:00", + "source_file": "9-chat-project/assets/playground-choice.png", + "language_code": "en" + }, + "playground.d2b927122224ff8f.webp": { + "original_hash": "4152bb8cd5f23e73d58b3beb52919477", + "translation_date": "2026-03-06T11:54:19+00:00", + "source_file": "9-chat-project/assets/playground.png", + "language_code": "en" + }, + "preview.9215f0a010074476.webp": { + "original_hash": "6eaab6a69de1fa433e822578652c7287", + "translation_date": "2026-03-06T11:52:18+00:00", + "source_file": "6-space-game/solution/spaceArt/preview.jpg", + "language_code": "en" + }, + "profiler.5a4a62479c5df01c.webp": { + "original_hash": "40b8a4d9f47e2f3e18aa2e814a15356c", + "translation_date": "2026-03-06T11:52:35+00:00", + "source_file": "5-browser-extension/3-background-tasks-and-performance/images/profiler.png", + "language_code": "en" + }, + "project-on-vscode.dev.e79815a9a95ee7fe.webp": { + "original_hash": "35de4bc32ea66a11f919671558e07d52", + "translation_date": "2026-03-06T11:51:54+00:00", + "source_file": "8-code-editor/images/project-on-vscode.dev.png", + "language_code": "en" + }, + "result.96ef01f607bf856a.webp": { + "original_hash": "e83c44a0fcaa7720ce32eb71d53d5250", + "translation_date": "2026-03-06T11:53:01+00:00", + "source_file": "7-bank-project/2-forms/images/result.png", + "language_code": "en" + }, + "screen1.baccbba0f1f93364.webp": { + "original_hash": "92c8fa2dbe566c4e19c98a9e7de6faa6", + "translation_date": "2026-03-06T11:52:54+00:00", + "source_file": "7-bank-project/images/screen1.png", + "language_code": "en" + }, + "screen2.123c82a831a1d14a.webp": { + "original_hash": "43b7f2857d5f758394e443df8fbc31cf", + "translation_date": "2026-03-06T11:52:56+00:00", + "source_file": "7-bank-project/images/screen2.png", + "language_code": "en" + }, + "screenshot.0a1ee0d123df681b.webp": { + "original_hash": "f909b463a14ff6542a816470f68bfac3", + "translation_date": "2026-03-06T11:54:26+00:00", + "source_file": "9-chat-project/assets/screenshot.png", + "language_code": "en" + }, + "screenshot.e7a5ad659e364568.webp": { + "original_hash": "c562c1fdc9d73658456e02b873e4dff9", + "translation_date": "2026-03-06T11:49:34+00:00", + "source_file": "images/screenshot.png", + "language_code": "en" + }, + "screenshot_gray.0c796099a1f9f25e.webp": { + "original_hash": "324b7bff7867c38e100d0acad18ed53d", + "translation_date": "2026-03-06T11:53:11+00:00", + "source_file": "3-terrarium/images/screenshot_gray.png", + "language_code": "en" + }, + "shield.1b9412b7ca6610ab.webp": { + "original_hash": "a672dc1a5f905918272bb58f1e236340", + "translation_date": "2026-03-06T11:52:20+00:00", + "source_file": "6-space-game/solution/spaceArt/png/shield.png", + "language_code": "en" + }, + "snapshot.97750180ebcad737.webp": { + "original_hash": "9db2fa7afcc1d258ec1a130cef145f94", + "translation_date": "2026-03-06T11:52:27+00:00", + "source_file": "5-browser-extension/3-background-tasks-and-performance/images/snapshot.png", + "language_code": "en" + }, + "spa.268ec73b41f992c2.webp": { + "original_hash": "3d3d7273070c2ddab04458fbb084ad4a", + "translation_date": "2026-03-06T11:53:06+00:00", + "source_file": "7-bank-project/3-data/images/spa.png", + "language_code": "en" + }, + "speedLine.5bcabb93f48b5ae1.webp": { + "original_hash": "ef791dbe8ea2e21cf697831e203803d5", + "translation_date": "2026-03-06T11:52:22+00:00", + "source_file": "6-space-game/solution/spaceArt/png/Background/speedLine.png", + "language_code": "en" + }, + "spritesheet.bec82852290b14ee.webp": { + "original_hash": "d593b0f366e9efd2f2b3ef18e7eb2d0c", + "translation_date": "2026-03-06T11:52:13+00:00", + "source_file": "6-space-game/solution/spritesheet.png", + "language_code": "en" + }, + "starBackground.a897b8acb1b0587d.webp": { + "original_hash": "cca00ba0b9e73859ab5bb928d5ca2fa2", + "translation_date": "2026-03-06T11:52:22+00:00", + "source_file": "6-space-game/solution/spaceArt/png/Background/starBackground.png", + "language_code": "en" + }, + "starBig.72e9c6d0d18f363d.webp": { + "original_hash": "4e8f1abc8b48d75990117ea8b6207842", + "translation_date": "2026-03-06T11:52:21+00:00", + "source_file": "6-space-game/solution/spaceArt/png/Background/starBig.png", + "language_code": "en" + }, + "starSmall.ed78b961dbcd0898.webp": { + "original_hash": "609bf88a971475818f95816b8cf71508", + "translation_date": "2026-03-06T11:52:22+00:00", + "source_file": "6-space-game/solution/spaceArt/png/Background/starSmall.png", + "language_code": "en" + }, + "template.67ad477109d29a2b.webp": { + "original_hash": "a184e4c012fd4fca9ab3c552df87bd0c", + "translation_date": "2026-03-06T11:54:21+00:00", + "source_file": "9-chat-project/assets/template.png", + "language_code": "en" + }, + "terrarium-final.0920f16e87c13a84.webp": { + "original_hash": "324b7bff7867c38e100d0acad18ed53d", + "translation_date": "2026-03-06T11:53:17+00:00", + "source_file": "3-terrarium/3-intro-to-DOM-and-closures/images/terrarium-final.png", + "language_code": "en" + }, + "terrarium-final.2f07047ffc597d0a.webp": { + "original_hash": "c669f9222e16690bb2015ce86bb4739c", + "translation_date": "2026-03-06T11:54:07+00:00", + "source_file": "3-terrarium/2-intro-to-css/images/terrarium-final.png", + "language_code": "en" + }, + "validation-error.8bd23e98d416c22f.webp": { + "original_hash": "d614ce6b24e2583901da9038297fe327", + "translation_date": "2026-03-06T11:53:00+00:00", + "source_file": "7-bank-project/2-forms/images/validation-error.png", + "language_code": "en" + }, + "vs-code-index.e2986cf919471eb9.webp": { + "original_hash": "ed8437cb2629b95551fff5e5d72ef4f5", + "translation_date": "2026-03-06T11:53:12+00:00", + "source_file": "3-terrarium/1-intro-to-html/images/vs-code-index.png", + "language_code": "en" + }, + "webdev101-a11y.8ef3025c858d897a.webp": { + "original_hash": "3f5220c5d502a906028b8a85245cc6da", + "translation_date": "2026-03-06T11:50:41+00:00", + "source_file": "sketchnotes/webdev101-a11y.png", + "language_code": "en" + }, + "webdev101-css.3f7af5991bf53a20.webp": { + "original_hash": "9de1dc14864697c82395b02f31a72aec", + "translation_date": "2026-03-06T11:50:18+00:00", + "source_file": "sketchnotes/webdev101-css.png", + "language_code": "en" + }, + "webdev101-github.8846d7971abef6f9.webp": { + "original_hash": "412ec8fc404fead25f314e2fdb564548", + "translation_date": "2026-03-06T11:50:09+00:00", + "source_file": "sketchnotes/webdev101-github.png", + "language_code": "en" + }, + "webdev101-html.4389c2067af68e98.webp": { + "original_hash": "23bf24ecb0e72f0c6c835824dec5ee54", + "translation_date": "2026-03-06T11:49:50+00:00", + "source_file": "sketchnotes/webdev101-html.png", + "language_code": "en" + }, + "webdev101-js-arrays.439d7528b8a29455.webp": { + "original_hash": "564c9e2d7f8e5a3b7e23570df300c732", + "translation_date": "2026-03-06T11:51:02+00:00", + "source_file": "sketchnotes/webdev101-js-arrays.png", + "language_code": "en" + }, + "webdev101-js-datatypes.4cc470179730702c.webp": { + "original_hash": "20fda1612cc0e8d20e6be01ffc28e5f7", + "translation_date": "2026-03-06T11:50:48+00:00", + "source_file": "sketchnotes/webdev101-js-datatypes.png", + "language_code": "en" + }, + "webdev101-js-decisions.69e1b20f272dd1f0.webp": { + "original_hash": "5e49a0b9b4149f782a4378354ba7fd56", + "translation_date": "2026-03-06T11:50:33+00:00", + "source_file": "sketchnotes/webdev101-js-decisions.png", + "language_code": "en" + }, + "webdev101-js-functions.be049c4726e94f8b.webp": { + "original_hash": "ec4279b1b2191fa07a83e78a97e81f29", + "translation_date": "2026-03-06T11:50:26+00:00", + "source_file": "sketchnotes/webdev101-js-functions.png", + "language_code": "en" + }, + "webdev101-js.10280393044d7eaa.webp": { + "original_hash": "fe1f154de74b31fdeb9a6df40e7ad5e1", + "translation_date": "2026-03-06T11:50:56+00:00", + "source_file": "sketchnotes/webdev101-js.png", + "language_code": "en" + }, + "webdev101-programming.d6e3f98e61ac4bff.webp": { + "original_hash": "adf4dac4d350592773dbdba8ebaaa262", + "translation_date": "2026-03-06T11:50:02+00:00", + "source_file": "sketchnotes/webdev101-programming.png", + "language_code": "en" + }, + "working-tree-pb.6cd43e5076f23ba3.webp": { + "original_hash": "f6b14887694745dd143a09bd60b74185", + "translation_date": "2026-03-06T11:52:04+00:00", + "source_file": "8-code-editor/images/working-tree-pb.png", + "language_code": "en" + }, + "working-tree.c58eec08e6335c79.webp": { + "original_hash": "bf2608b4302123a00a8e7b1b6a430b4a", + "translation_date": "2026-03-06T11:52:01+00:00", + "source_file": "8-code-editor/images/working-tree.png", + "language_code": "en" + } +} \ No newline at end of file diff --git a/translated_images/en/1.b6da8c1394b07491.webp b/translated_images/en/1.b6da8c1394b07491.webp new file mode 100644 index 000000000..f951b91e3 Binary files /dev/null and b/translated_images/en/1.b6da8c1394b07491.webp differ diff --git a/translated_images/en/1.cc07a5cbe114ad1d.webp b/translated_images/en/1.cc07a5cbe114ad1d.webp new file mode 100644 index 000000000..33cc711b8 Binary files /dev/null and b/translated_images/en/1.cc07a5cbe114ad1d.webp differ diff --git a/translated_images/en/2.1dae52ff08042246.webp b/translated_images/en/2.1dae52ff08042246.webp new file mode 100644 index 000000000..a36fc5a40 Binary files /dev/null and b/translated_images/en/2.1dae52ff08042246.webp differ diff --git a/translated_images/en/after-codeswing-extension-pb.0ebddddcf73b5509.webp b/translated_images/en/after-codeswing-extension-pb.0ebddddcf73b5509.webp new file mode 100644 index 000000000..d40b409f5 Binary files /dev/null and b/translated_images/en/after-codeswing-extension-pb.0ebddddcf73b5509.webp differ diff --git a/translated_images/en/background.148a8d43afde5730.webp b/translated_images/en/background.148a8d43afde5730.webp new file mode 100644 index 000000000..f735f5cd3 Binary files /dev/null and b/translated_images/en/background.148a8d43afde5730.webp differ diff --git a/translated_images/en/backgroundColor.e19c3c60768150c8.webp b/translated_images/en/backgroundColor.e19c3c60768150c8.webp new file mode 100644 index 000000000..415592530 Binary files /dev/null and b/translated_images/en/backgroundColor.e19c3c60768150c8.webp differ diff --git a/translated_images/en/browser-console.efaf0b51aaaf6778.webp b/translated_images/en/browser-console.efaf0b51aaaf6778.webp new file mode 100644 index 000000000..a40a81488 Binary files /dev/null and b/translated_images/en/browser-console.efaf0b51aaaf6778.webp differ diff --git a/translated_images/en/browser.60317c9be8b7f84a.webp b/translated_images/en/browser.60317c9be8b7f84a.webp new file mode 100644 index 000000000..dd13229c0 Binary files /dev/null and b/translated_images/en/browser.60317c9be8b7f84a.webp differ diff --git a/translated_images/en/canvas.fbd605ff8e5b8aff.webp b/translated_images/en/canvas.fbd605ff8e5b8aff.webp new file mode 100644 index 000000000..e3d6318ff Binary files /dev/null and b/translated_images/en/canvas.fbd605ff8e5b8aff.webp differ diff --git a/translated_images/en/canvas_grid.5f209da785ded492.webp b/translated_images/en/canvas_grid.5f209da785ded492.webp new file mode 100644 index 000000000..2d0256c2f Binary files /dev/null and b/translated_images/en/canvas_grid.5f209da785ded492.webp differ diff --git a/translated_images/en/character.5c0dd8e067ffd693.webp b/translated_images/en/character.5c0dd8e067ffd693.webp new file mode 100644 index 000000000..6a0167cb3 Binary files /dev/null and b/translated_images/en/character.5c0dd8e067ffd693.webp differ diff --git a/translated_images/en/click-register.e89a30bf0d4bc9ca.webp b/translated_images/en/click-register.e89a30bf0d4bc9ca.webp new file mode 100644 index 000000000..f054292ed Binary files /dev/null and b/translated_images/en/click-register.e89a30bf0d4bc9ca.webp differ diff --git a/translated_images/en/clone_repo.5085c48d666ead57.webp b/translated_images/en/clone_repo.5085c48d666ead57.webp new file mode 100644 index 000000000..c384d7ea7 Binary files /dev/null and b/translated_images/en/clone_repo.5085c48d666ead57.webp differ diff --git a/translated_images/en/clone_repo.6a202fb230ab6bdd.webp b/translated_images/en/clone_repo.6a202fb230ab6bdd.webp new file mode 100644 index 000000000..1f0f6ea3a Binary files /dev/null and b/translated_images/en/clone_repo.6a202fb230ab6bdd.webp differ diff --git a/translated_images/en/codespace.bcecbdf5d2747d3d.webp b/translated_images/en/codespace.bcecbdf5d2747d3d.webp new file mode 100644 index 000000000..95ee30832 Binary files /dev/null and b/translated_images/en/codespace.bcecbdf5d2747d3d.webp differ diff --git a/translated_images/en/create-a-fork.297ab42b4bd0af99.webp b/translated_images/en/create-a-fork.297ab42b4bd0af99.webp new file mode 100644 index 000000000..3e6b0419b Binary files /dev/null and b/translated_images/en/create-a-fork.297ab42b4bd0af99.webp differ diff --git a/translated_images/en/create-new-file-pb.0797800d977ec3eb.webp b/translated_images/en/create-new-file-pb.0797800d977ec3eb.webp new file mode 100644 index 000000000..902427c30 Binary files /dev/null and b/translated_images/en/create-new-file-pb.0797800d977ec3eb.webp differ diff --git a/translated_images/en/create-new-file.2814e609c2af9aeb.webp b/translated_images/en/create-new-file.2814e609c2af9aeb.webp new file mode 100644 index 000000000..2bbfdce93 Binary files /dev/null and b/translated_images/en/create-new-file.2814e609c2af9aeb.webp differ diff --git a/translated_images/en/createcodespace.0238bbf4d7a8d955.webp b/translated_images/en/createcodespace.0238bbf4d7a8d955.webp new file mode 100644 index 000000000..9ae4deb49 Binary files /dev/null and b/translated_images/en/createcodespace.0238bbf4d7a8d955.webp differ diff --git a/translated_images/en/data-flow.fa2354e0908fecc8.webp b/translated_images/en/data-flow.fa2354e0908fecc8.webp new file mode 100644 index 000000000..f361d3b04 Binary files /dev/null and b/translated_images/en/data-flow.fa2354e0908fecc8.webp differ diff --git a/translated_images/en/default-vscode-dev.5d06881d65c1b323.webp b/translated_images/en/default-vscode-dev.5d06881d65c1b323.webp new file mode 100644 index 000000000..8e884d0e8 Binary files /dev/null and b/translated_images/en/default-vscode-dev.5d06881d65c1b323.webp differ diff --git a/translated_images/en/dialog.93bba104afeb79f1.webp b/translated_images/en/dialog.93bba104afeb79f1.webp new file mode 100644 index 000000000..20f1cab8f Binary files /dev/null and b/translated_images/en/dialog.93bba104afeb79f1.webp differ diff --git a/translated_images/en/dom-tree.7daf0e763cbbba92.webp b/translated_images/en/dom-tree.7daf0e763cbbba92.webp new file mode 100644 index 000000000..295ff0ed4 Binary files /dev/null and b/translated_images/en/dom-tree.7daf0e763cbbba92.webp differ diff --git a/translated_images/en/earlybrowsers.d984b711cdf3a42d.webp b/translated_images/en/earlybrowsers.d984b711cdf3a42d.webp new file mode 100644 index 000000000..f63eaeaa3 Binary files /dev/null and b/translated_images/en/earlybrowsers.d984b711cdf3a42d.webp differ diff --git a/translated_images/en/edit-a-file-pb.263555922c14fc52.webp b/translated_images/en/edit-a-file-pb.263555922c14fc52.webp new file mode 100644 index 000000000..85cdc715b Binary files /dev/null and b/translated_images/en/edit-a-file-pb.263555922c14fc52.webp differ diff --git a/translated_images/en/edit-a-file.52c0ee665ef19f08.webp b/translated_images/en/edit-a-file.52c0ee665ef19f08.webp new file mode 100644 index 000000000..7c03d44a1 Binary files /dev/null and b/translated_images/en/edit-a-file.52c0ee665ef19f08.webp differ diff --git a/translated_images/en/enemyShip.035a46787bff658c.webp b/translated_images/en/enemyShip.035a46787bff658c.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.035a46787bff658c.webp differ diff --git a/translated_images/en/enemyShip.1a1354d7988de290.webp b/translated_images/en/enemyShip.1a1354d7988de290.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.1a1354d7988de290.webp differ diff --git a/translated_images/en/enemyShip.22cbee6ea27a5809.webp b/translated_images/en/enemyShip.22cbee6ea27a5809.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.22cbee6ea27a5809.webp differ diff --git a/translated_images/en/enemyShip.321ecb1b4eb21f2c.webp b/translated_images/en/enemyShip.321ecb1b4eb21f2c.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.321ecb1b4eb21f2c.webp differ diff --git a/translated_images/en/enemyShip.4fbf2889e6129db4.webp b/translated_images/en/enemyShip.4fbf2889e6129db4.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.4fbf2889e6129db4.webp differ diff --git a/translated_images/en/enemyShip.5df2a822c16650c2.webp b/translated_images/en/enemyShip.5df2a822c16650c2.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.5df2a822c16650c2.webp differ diff --git a/translated_images/en/enemyShip.62983ed4bfb2220f.webp b/translated_images/en/enemyShip.62983ed4bfb2220f.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.62983ed4bfb2220f.webp differ diff --git a/translated_images/en/enemyShip.add7036e1c3c3014.webp b/translated_images/en/enemyShip.add7036e1c3c3014.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.add7036e1c3c3014.webp differ diff --git a/translated_images/en/enemyShip.b39a140287683bf7.webp b/translated_images/en/enemyShip.b39a140287683bf7.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.b39a140287683bf7.webp differ diff --git a/translated_images/en/enemyShip.b9626ed228a17a32.webp b/translated_images/en/enemyShip.b9626ed228a17a32.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.b9626ed228a17a32.webp differ diff --git a/translated_images/en/enemyShip.deb0477a7312f54d.webp b/translated_images/en/enemyShip.deb0477a7312f54d.webp new file mode 100644 index 000000000..a668c6e24 Binary files /dev/null and b/translated_images/en/enemyShip.deb0477a7312f54d.webp differ diff --git a/translated_images/en/enemyUFO.bf8585e4e8dcdb68.webp b/translated_images/en/enemyUFO.bf8585e4e8dcdb68.webp new file mode 100644 index 000000000..4f52507d2 Binary files /dev/null and b/translated_images/en/enemyUFO.bf8585e4e8dcdb68.webp differ diff --git a/translated_images/en/extension-details.9f8f1fd4e9eb2de5.webp b/translated_images/en/extension-details.9f8f1fd4e9eb2de5.webp new file mode 100644 index 000000000..2bb955796 Binary files /dev/null and b/translated_images/en/extension-details.9f8f1fd4e9eb2de5.webp differ diff --git a/translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp b/translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp new file mode 100644 index 000000000..fe31cfec7 Binary files /dev/null and b/translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp differ diff --git a/translated_images/en/extension-settings.21c752ae4f4cdb78.webp b/translated_images/en/extension-settings.21c752ae4f4cdb78.webp new file mode 100644 index 000000000..34f6b2188 Binary files /dev/null and b/translated_images/en/extension-settings.21c752ae4f4cdb78.webp differ diff --git a/translated_images/en/extensions.eca0e0c7f59a10b5.webp b/translated_images/en/extensions.eca0e0c7f59a10b5.webp new file mode 100644 index 000000000..8a01bafba Binary files /dev/null and b/translated_images/en/extensions.eca0e0c7f59a10b5.webp differ diff --git a/translated_images/en/favicon.37b561214b36d454.webp b/translated_images/en/favicon.37b561214b36d454.webp new file mode 100644 index 000000000..48a53960d Binary files /dev/null and b/translated_images/en/favicon.37b561214b36d454.webp differ diff --git a/translated_images/en/form-post.61de4ca1b964d91a.webp b/translated_images/en/form-post.61de4ca1b964d91a.webp new file mode 100644 index 000000000..edd0691f7 Binary files /dev/null and b/translated_images/en/form-post.61de4ca1b964d91a.webp differ diff --git a/translated_images/en/history.7fdabbafa521e064.webp b/translated_images/en/history.7fdabbafa521e064.webp new file mode 100644 index 000000000..162af5d6f Binary files /dev/null and b/translated_images/en/history.7fdabbafa521e064.webp differ diff --git a/translated_images/en/install-on-edge.78634f02842c4828.webp b/translated_images/en/install-on-edge.78634f02842c4828.webp new file mode 100644 index 000000000..d00046ed7 Binary files /dev/null and b/translated_images/en/install-on-edge.78634f02842c4828.webp differ diff --git a/translated_images/en/install-on-edge.d68781acaf0b3d3d.webp b/translated_images/en/install-on-edge.d68781acaf0b3d3d.webp new file mode 100644 index 000000000..d00046ed7 Binary files /dev/null and b/translated_images/en/install-on-edge.d68781acaf0b3d3d.webp differ diff --git a/translated_images/en/laserGreen.89904f0f49945560.webp b/translated_images/en/laserGreen.89904f0f49945560.webp new file mode 100644 index 000000000..bfe37aafc Binary files /dev/null and b/translated_images/en/laserGreen.89904f0f49945560.webp differ diff --git a/translated_images/en/laserGreenShot.e4fbfc4714c08a5b.webp b/translated_images/en/laserGreenShot.e4fbfc4714c08a5b.webp new file mode 100644 index 000000000..dd3e87139 Binary files /dev/null and b/translated_images/en/laserGreenShot.e4fbfc4714c08a5b.webp differ diff --git a/translated_images/en/laserRed.2040e11f55c0a40a.webp b/translated_images/en/laserRed.2040e11f55c0a40a.webp new file mode 100644 index 000000000..27c042acb Binary files /dev/null and b/translated_images/en/laserRed.2040e11f55c0a40a.webp differ diff --git a/translated_images/en/laserRed.381bc5555491ce67.webp b/translated_images/en/laserRed.381bc5555491ce67.webp new file mode 100644 index 000000000..27c042acb Binary files /dev/null and b/translated_images/en/laserRed.381bc5555491ce67.webp differ diff --git a/translated_images/en/laserRed.69730edd76f0b3bd.webp b/translated_images/en/laserRed.69730edd76f0b3bd.webp new file mode 100644 index 000000000..27c042acb Binary files /dev/null and b/translated_images/en/laserRed.69730edd76f0b3bd.webp differ diff --git a/translated_images/en/laserRed.b583dc1728eb8581.webp b/translated_images/en/laserRed.b583dc1728eb8581.webp new file mode 100644 index 000000000..27c042acb Binary files /dev/null and b/translated_images/en/laserRed.b583dc1728eb8581.webp differ diff --git a/translated_images/en/laserRed.cae9ab24ea9b18fd.webp b/translated_images/en/laserRed.cae9ab24ea9b18fd.webp new file mode 100644 index 000000000..27c042acb Binary files /dev/null and b/translated_images/en/laserRed.cae9ab24ea9b18fd.webp differ diff --git a/translated_images/en/laserRed.d81ce4986f87c251.webp b/translated_images/en/laserRed.d81ce4986f87c251.webp new file mode 100644 index 000000000..27c042acb Binary files /dev/null and b/translated_images/en/laserRed.d81ce4986f87c251.webp differ diff --git a/translated_images/en/laserRed.e58ef8db2585dfbe.webp b/translated_images/en/laserRed.e58ef8db2585dfbe.webp new file mode 100644 index 000000000..27c042acb Binary files /dev/null and b/translated_images/en/laserRed.e58ef8db2585dfbe.webp differ diff --git a/translated_images/en/laserRed.e66e29ace6666064.webp b/translated_images/en/laserRed.e66e29ace6666064.webp new file mode 100644 index 000000000..27c042acb Binary files /dev/null and b/translated_images/en/laserRed.e66e29ace6666064.webp differ diff --git a/translated_images/en/laserRed.e86e8fb629c6026e.webp b/translated_images/en/laserRed.e86e8fb629c6026e.webp new file mode 100644 index 000000000..27c042acb Binary files /dev/null and b/translated_images/en/laserRed.e86e8fb629c6026e.webp differ diff --git a/translated_images/en/laserRedShot.c39d066745996a71.webp b/translated_images/en/laserRedShot.c39d066745996a71.webp new file mode 100644 index 000000000..99fcece7a Binary files /dev/null and b/translated_images/en/laserRedShot.c39d066745996a71.webp differ diff --git a/translated_images/en/life.27144b6d4bfdea76.webp b/translated_images/en/life.27144b6d4bfdea76.webp new file mode 100644 index 000000000..442ec0a5b Binary files /dev/null and b/translated_images/en/life.27144b6d4bfdea76.webp differ diff --git a/translated_images/en/life.2a159298dd98f4ef.webp b/translated_images/en/life.2a159298dd98f4ef.webp new file mode 100644 index 000000000..442ec0a5b Binary files /dev/null and b/translated_images/en/life.2a159298dd98f4ef.webp differ diff --git a/translated_images/en/life.466df3b1692a244a.webp b/translated_images/en/life.466df3b1692a244a.webp new file mode 100644 index 000000000..442ec0a5b Binary files /dev/null and b/translated_images/en/life.466df3b1692a244a.webp differ diff --git a/translated_images/en/life.65a2aaceca875284.webp b/translated_images/en/life.65a2aaceca875284.webp new file mode 100644 index 000000000..442ec0a5b Binary files /dev/null and b/translated_images/en/life.65a2aaceca875284.webp differ diff --git a/translated_images/en/life.6fb9f50d53ee0413.webp b/translated_images/en/life.6fb9f50d53ee0413.webp new file mode 100644 index 000000000..442ec0a5b Binary files /dev/null and b/translated_images/en/life.6fb9f50d53ee0413.webp differ diff --git a/translated_images/en/life.78b6e96a3003767e.webp b/translated_images/en/life.78b6e96a3003767e.webp new file mode 100644 index 000000000..442ec0a5b Binary files /dev/null and b/translated_images/en/life.78b6e96a3003767e.webp differ diff --git a/translated_images/en/life.86d843ce9c23289c.webp b/translated_images/en/life.86d843ce9c23289c.webp new file mode 100644 index 000000000..442ec0a5b Binary files /dev/null and b/translated_images/en/life.86d843ce9c23289c.webp differ diff --git a/translated_images/en/localstorage.472f8147b6a3f8d1.webp b/translated_images/en/localstorage.472f8147b6a3f8d1.webp new file mode 100644 index 000000000..a7e41f9d0 Binary files /dev/null and b/translated_images/en/localstorage.472f8147b6a3f8d1.webp differ diff --git a/translated_images/en/log.804026979f3707e0.webp b/translated_images/en/log.804026979f3707e0.webp new file mode 100644 index 000000000..f8c31cd10 Binary files /dev/null and b/translated_images/en/log.804026979f3707e0.webp differ diff --git a/translated_images/en/login-error.416fe019b36a6327.webp b/translated_images/en/login-error.416fe019b36a6327.webp new file mode 100644 index 000000000..4b4e36656 Binary files /dev/null and b/translated_images/en/login-error.416fe019b36a6327.webp differ diff --git a/translated_images/en/meteorBig.1e452b3ad7af50ad.webp b/translated_images/en/meteorBig.1e452b3ad7af50ad.webp new file mode 100644 index 000000000..39fba1031 Binary files /dev/null and b/translated_images/en/meteorBig.1e452b3ad7af50ad.webp differ diff --git a/translated_images/en/meteorSmall.0d729bc71c12d41f.webp b/translated_images/en/meteorSmall.0d729bc71c12d41f.webp new file mode 100644 index 000000000..631797205 Binary files /dev/null and b/translated_images/en/meteorSmall.0d729bc71c12d41f.webp differ diff --git a/translated_images/en/moodle.94eb93d714a50cb2.webp b/translated_images/en/moodle.94eb93d714a50cb2.webp new file mode 100644 index 000000000..90a52755e Binary files /dev/null and b/translated_images/en/moodle.94eb93d714a50cb2.webp differ diff --git a/translated_images/en/mpa.7f7375a1a2d4aa77.webp b/translated_images/en/mpa.7f7375a1a2d4aa77.webp new file mode 100644 index 000000000..98d533643 Binary files /dev/null and b/translated_images/en/mpa.7f7375a1a2d4aa77.webp differ diff --git a/translated_images/en/nebula.55c2933d36d035d3.webp b/translated_images/en/nebula.55c2933d36d035d3.webp new file mode 100644 index 000000000..a294cbf33 Binary files /dev/null and b/translated_images/en/nebula.55c2933d36d035d3.webp differ diff --git a/translated_images/en/new-file-github.com.c886796d800e8056.webp b/translated_images/en/new-file-github.com.c886796d800e8056.webp new file mode 100644 index 000000000..838642e1c Binary files /dev/null and b/translated_images/en/new-file-github.com.c886796d800e8056.webp differ diff --git a/translated_images/en/open-palette-menu.46dda01084738da8.webp b/translated_images/en/open-palette-menu.46dda01084738da8.webp new file mode 100644 index 000000000..66cde7f5a Binary files /dev/null and b/translated_images/en/open-palette-menu.46dda01084738da8.webp differ diff --git a/translated_images/en/open-remote-repository.bd9c2598b8949e7f.webp b/translated_images/en/open-remote-repository.bd9c2598b8949e7f.webp new file mode 100644 index 000000000..7e4c3555d Binary files /dev/null and b/translated_images/en/open-remote-repository.bd9c2598b8949e7f.webp differ diff --git a/translated_images/en/palette-menu.4946174e07f42622.webp b/translated_images/en/palette-menu.4946174e07f42622.webp new file mode 100644 index 000000000..a257874a1 Binary files /dev/null and b/translated_images/en/palette-menu.4946174e07f42622.webp differ diff --git a/translated_images/en/partI-solution.36c53b48c9ffae2a.webp b/translated_images/en/partI-solution.36c53b48c9ffae2a.webp new file mode 100644 index 000000000..e7df45a1e Binary files /dev/null and b/translated_images/en/partI-solution.36c53b48c9ffae2a.webp differ diff --git a/translated_images/en/plant1.a876180d8659acb9.webp b/translated_images/en/plant1.a876180d8659acb9.webp new file mode 100644 index 000000000..0afdb8492 Binary files /dev/null and b/translated_images/en/plant1.a876180d8659acb9.webp differ diff --git a/translated_images/en/plant10.2f2c47804ae52dd3.webp b/translated_images/en/plant10.2f2c47804ae52dd3.webp new file mode 100644 index 000000000..a972d3197 Binary files /dev/null and b/translated_images/en/plant10.2f2c47804ae52dd3.webp differ diff --git a/translated_images/en/plant11.0ce0081b0ef17aa1.webp b/translated_images/en/plant11.0ce0081b0ef17aa1.webp new file mode 100644 index 000000000..83718f403 Binary files /dev/null and b/translated_images/en/plant11.0ce0081b0ef17aa1.webp differ diff --git a/translated_images/en/plant12.6b934c4312a00228.webp b/translated_images/en/plant12.6b934c4312a00228.webp new file mode 100644 index 000000000..abfcadc6c Binary files /dev/null and b/translated_images/en/plant12.6b934c4312a00228.webp differ diff --git a/translated_images/en/plant13.37d6ab2e2481421f.webp b/translated_images/en/plant13.37d6ab2e2481421f.webp new file mode 100644 index 000000000..77816483d Binary files /dev/null and b/translated_images/en/plant13.37d6ab2e2481421f.webp differ diff --git a/translated_images/en/plant14.908791477a46eb7f.webp b/translated_images/en/plant14.908791477a46eb7f.webp new file mode 100644 index 000000000..9b2eea637 Binary files /dev/null and b/translated_images/en/plant14.908791477a46eb7f.webp differ diff --git a/translated_images/en/plant2.9e45efea224115b0.webp b/translated_images/en/plant2.9e45efea224115b0.webp new file mode 100644 index 000000000..e6b517d90 Binary files /dev/null and b/translated_images/en/plant2.9e45efea224115b0.webp differ diff --git a/translated_images/en/plant3.06efdd0fa0c4b115.webp b/translated_images/en/plant3.06efdd0fa0c4b115.webp new file mode 100644 index 000000000..fa73f15cf Binary files /dev/null and b/translated_images/en/plant3.06efdd0fa0c4b115.webp differ diff --git a/translated_images/en/plant4.3b78072b427727c6.webp b/translated_images/en/plant4.3b78072b427727c6.webp new file mode 100644 index 000000000..be231012e Binary files /dev/null and b/translated_images/en/plant4.3b78072b427727c6.webp differ diff --git a/translated_images/en/plant5.8ec58b18ac336fa8.webp b/translated_images/en/plant5.8ec58b18ac336fa8.webp new file mode 100644 index 000000000..4e295e185 Binary files /dev/null and b/translated_images/en/plant5.8ec58b18ac336fa8.webp differ diff --git a/translated_images/en/plant6.ca4ff8372e6676b1.webp b/translated_images/en/plant6.ca4ff8372e6676b1.webp new file mode 100644 index 000000000..46a89a545 Binary files /dev/null and b/translated_images/en/plant6.ca4ff8372e6676b1.webp differ diff --git a/translated_images/en/plant7.194d5a42fcf5a88c.webp b/translated_images/en/plant7.194d5a42fcf5a88c.webp new file mode 100644 index 000000000..420dca0b9 Binary files /dev/null and b/translated_images/en/plant7.194d5a42fcf5a88c.webp differ diff --git a/translated_images/en/plant8.7b247809ab0eb492.webp b/translated_images/en/plant8.7b247809ab0eb492.webp new file mode 100644 index 000000000..9b4c15c2f Binary files /dev/null and b/translated_images/en/plant8.7b247809ab0eb492.webp differ diff --git a/translated_images/en/plant9.8fe614c01ded1b1e.webp b/translated_images/en/plant9.8fe614c01ded1b1e.webp new file mode 100644 index 000000000..893f89540 Binary files /dev/null and b/translated_images/en/plant9.8fe614c01ded1b1e.webp differ diff --git a/translated_images/en/player.137ee0e47f895ffc.webp b/translated_images/en/player.137ee0e47f895ffc.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.137ee0e47f895ffc.webp differ diff --git a/translated_images/en/player.2887422f6982c3cd.webp b/translated_images/en/player.2887422f6982c3cd.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.2887422f6982c3cd.webp differ diff --git a/translated_images/en/player.391fed427ede24f5.webp b/translated_images/en/player.391fed427ede24f5.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.391fed427ede24f5.webp differ diff --git a/translated_images/en/player.3c4f50182552a73a.webp b/translated_images/en/player.3c4f50182552a73a.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.3c4f50182552a73a.webp differ diff --git a/translated_images/en/player.47bc9de0714c723d.webp b/translated_images/en/player.47bc9de0714c723d.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.47bc9de0714c723d.webp differ diff --git a/translated_images/en/player.57b3107c03012695.webp b/translated_images/en/player.57b3107c03012695.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.57b3107c03012695.webp differ diff --git a/translated_images/en/player.606f85953e5e564e.webp b/translated_images/en/player.606f85953e5e564e.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.606f85953e5e564e.webp differ diff --git a/translated_images/en/player.680ea4c619b54fe1.webp b/translated_images/en/player.680ea4c619b54fe1.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.680ea4c619b54fe1.webp differ diff --git a/translated_images/en/player.bfe14f110bddf56d.webp b/translated_images/en/player.bfe14f110bddf56d.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.bfe14f110bddf56d.webp differ diff --git a/translated_images/en/player.c99c25d54a615ca0.webp b/translated_images/en/player.c99c25d54a615ca0.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.c99c25d54a615ca0.webp differ diff --git a/translated_images/en/player.dd24c1afa8c71e9b.webp b/translated_images/en/player.dd24c1afa8c71e9b.webp new file mode 100644 index 000000000..879c28a80 Binary files /dev/null and b/translated_images/en/player.dd24c1afa8c71e9b.webp differ diff --git a/translated_images/en/playerDamaged.181703f652fd5176.webp b/translated_images/en/playerDamaged.181703f652fd5176.webp new file mode 100644 index 000000000..00d3377d9 Binary files /dev/null and b/translated_images/en/playerDamaged.181703f652fd5176.webp differ diff --git a/translated_images/en/playerLeft.0f928412e66ba5d9.webp b/translated_images/en/playerLeft.0f928412e66ba5d9.webp new file mode 100644 index 000000000..0856babce Binary files /dev/null and b/translated_images/en/playerLeft.0f928412e66ba5d9.webp differ diff --git a/translated_images/en/playerRight.e4825f489e29f737.webp b/translated_images/en/playerRight.e4825f489e29f737.webp new file mode 100644 index 000000000..8d6696a22 Binary files /dev/null and b/translated_images/en/playerRight.e4825f489e29f737.webp differ diff --git a/translated_images/en/playground-choice.1d23ba7d407f4758.webp b/translated_images/en/playground-choice.1d23ba7d407f4758.webp new file mode 100644 index 000000000..bdb9df17c Binary files /dev/null and b/translated_images/en/playground-choice.1d23ba7d407f4758.webp differ diff --git a/translated_images/en/playground.d2b927122224ff8f.webp b/translated_images/en/playground.d2b927122224ff8f.webp new file mode 100644 index 000000000..dbd7f55c9 Binary files /dev/null and b/translated_images/en/playground.d2b927122224ff8f.webp differ diff --git a/translated_images/en/preview.9215f0a010074476.webp b/translated_images/en/preview.9215f0a010074476.webp new file mode 100644 index 000000000..84346fe7c Binary files /dev/null and b/translated_images/en/preview.9215f0a010074476.webp differ diff --git a/translated_images/en/profiler.5a4a62479c5df01c.webp b/translated_images/en/profiler.5a4a62479c5df01c.webp new file mode 100644 index 000000000..0cfd23b63 Binary files /dev/null and b/translated_images/en/profiler.5a4a62479c5df01c.webp differ diff --git a/translated_images/en/project-on-vscode.dev.e79815a9a95ee7fe.webp b/translated_images/en/project-on-vscode.dev.e79815a9a95ee7fe.webp new file mode 100644 index 000000000..afbcd98d1 Binary files /dev/null and b/translated_images/en/project-on-vscode.dev.e79815a9a95ee7fe.webp differ diff --git a/translated_images/en/result.96ef01f607bf856a.webp b/translated_images/en/result.96ef01f607bf856a.webp new file mode 100644 index 000000000..51ef20f14 Binary files /dev/null and b/translated_images/en/result.96ef01f607bf856a.webp differ diff --git a/translated_images/en/screen1.baccbba0f1f93364.webp b/translated_images/en/screen1.baccbba0f1f93364.webp new file mode 100644 index 000000000..07dc0f16a Binary files /dev/null and b/translated_images/en/screen1.baccbba0f1f93364.webp differ diff --git a/translated_images/en/screen2.123c82a831a1d14a.webp b/translated_images/en/screen2.123c82a831a1d14a.webp new file mode 100644 index 000000000..9e6d9a002 Binary files /dev/null and b/translated_images/en/screen2.123c82a831a1d14a.webp differ diff --git a/translated_images/en/screenshot.0a1ee0d123df681b.webp b/translated_images/en/screenshot.0a1ee0d123df681b.webp new file mode 100644 index 000000000..5eee42b6e Binary files /dev/null and b/translated_images/en/screenshot.0a1ee0d123df681b.webp differ diff --git a/translated_images/en/screenshot.e7a5ad659e364568.webp b/translated_images/en/screenshot.e7a5ad659e364568.webp new file mode 100644 index 000000000..b2ddd9c88 Binary files /dev/null and b/translated_images/en/screenshot.e7a5ad659e364568.webp differ diff --git a/translated_images/en/screenshot_gray.0c796099a1f9f25e.webp b/translated_images/en/screenshot_gray.0c796099a1f9f25e.webp new file mode 100644 index 000000000..5fc633e5c Binary files /dev/null and b/translated_images/en/screenshot_gray.0c796099a1f9f25e.webp differ diff --git a/translated_images/en/shield.1b9412b7ca6610ab.webp b/translated_images/en/shield.1b9412b7ca6610ab.webp new file mode 100644 index 000000000..a2e065ca1 Binary files /dev/null and b/translated_images/en/shield.1b9412b7ca6610ab.webp differ diff --git a/translated_images/en/snapshot.97750180ebcad737.webp b/translated_images/en/snapshot.97750180ebcad737.webp new file mode 100644 index 000000000..0babbb24c Binary files /dev/null and b/translated_images/en/snapshot.97750180ebcad737.webp differ diff --git a/translated_images/en/spa.268ec73b41f992c2.webp b/translated_images/en/spa.268ec73b41f992c2.webp new file mode 100644 index 000000000..2bd4c1405 Binary files /dev/null and b/translated_images/en/spa.268ec73b41f992c2.webp differ diff --git a/translated_images/en/speedLine.5bcabb93f48b5ae1.webp b/translated_images/en/speedLine.5bcabb93f48b5ae1.webp new file mode 100644 index 000000000..57b77b342 Binary files /dev/null and b/translated_images/en/speedLine.5bcabb93f48b5ae1.webp differ diff --git a/translated_images/en/spritesheet.bec82852290b14ee.webp b/translated_images/en/spritesheet.bec82852290b14ee.webp new file mode 100644 index 000000000..02853f8a0 Binary files /dev/null and b/translated_images/en/spritesheet.bec82852290b14ee.webp differ diff --git a/translated_images/en/starBackground.a897b8acb1b0587d.webp b/translated_images/en/starBackground.a897b8acb1b0587d.webp new file mode 100644 index 000000000..66280c96a Binary files /dev/null and b/translated_images/en/starBackground.a897b8acb1b0587d.webp differ diff --git a/translated_images/en/starBig.72e9c6d0d18f363d.webp b/translated_images/en/starBig.72e9c6d0d18f363d.webp new file mode 100644 index 000000000..917791333 Binary files /dev/null and b/translated_images/en/starBig.72e9c6d0d18f363d.webp differ diff --git a/translated_images/en/starSmall.ed78b961dbcd0898.webp b/translated_images/en/starSmall.ed78b961dbcd0898.webp new file mode 100644 index 000000000..bf86a6e91 Binary files /dev/null and b/translated_images/en/starSmall.ed78b961dbcd0898.webp differ diff --git a/translated_images/en/template.67ad477109d29a2b.webp b/translated_images/en/template.67ad477109d29a2b.webp new file mode 100644 index 000000000..919a3d51a Binary files /dev/null and b/translated_images/en/template.67ad477109d29a2b.webp differ diff --git a/translated_images/en/terrarium-final.0920f16e87c13a84.webp b/translated_images/en/terrarium-final.0920f16e87c13a84.webp new file mode 100644 index 000000000..5fc633e5c Binary files /dev/null and b/translated_images/en/terrarium-final.0920f16e87c13a84.webp differ diff --git a/translated_images/en/terrarium-final.2f07047ffc597d0a.webp b/translated_images/en/terrarium-final.2f07047ffc597d0a.webp new file mode 100644 index 000000000..98ea433bf Binary files /dev/null and b/translated_images/en/terrarium-final.2f07047ffc597d0a.webp differ diff --git a/translated_images/en/validation-error.8bd23e98d416c22f.webp b/translated_images/en/validation-error.8bd23e98d416c22f.webp new file mode 100644 index 000000000..6436f89c4 Binary files /dev/null and b/translated_images/en/validation-error.8bd23e98d416c22f.webp differ diff --git a/translated_images/en/vs-code-index.e2986cf919471eb9.webp b/translated_images/en/vs-code-index.e2986cf919471eb9.webp new file mode 100644 index 000000000..47d52d488 Binary files /dev/null and b/translated_images/en/vs-code-index.e2986cf919471eb9.webp differ diff --git a/translated_images/en/webdev101-a11y.8ef3025c858d897a.webp b/translated_images/en/webdev101-a11y.8ef3025c858d897a.webp new file mode 100644 index 000000000..7089cea71 Binary files /dev/null and b/translated_images/en/webdev101-a11y.8ef3025c858d897a.webp differ diff --git a/translated_images/en/webdev101-css.3f7af5991bf53a20.webp b/translated_images/en/webdev101-css.3f7af5991bf53a20.webp new file mode 100644 index 000000000..325aa3a8a Binary files /dev/null and b/translated_images/en/webdev101-css.3f7af5991bf53a20.webp differ diff --git a/translated_images/en/webdev101-github.8846d7971abef6f9.webp b/translated_images/en/webdev101-github.8846d7971abef6f9.webp new file mode 100644 index 000000000..1a24746fa Binary files /dev/null and b/translated_images/en/webdev101-github.8846d7971abef6f9.webp differ diff --git a/translated_images/en/webdev101-html.4389c2067af68e98.webp b/translated_images/en/webdev101-html.4389c2067af68e98.webp new file mode 100644 index 000000000..b52c12fcb Binary files /dev/null and b/translated_images/en/webdev101-html.4389c2067af68e98.webp differ diff --git a/translated_images/en/webdev101-js-arrays.439d7528b8a29455.webp b/translated_images/en/webdev101-js-arrays.439d7528b8a29455.webp new file mode 100644 index 000000000..981bfc47c Binary files /dev/null and b/translated_images/en/webdev101-js-arrays.439d7528b8a29455.webp differ diff --git a/translated_images/en/webdev101-js-datatypes.4cc470179730702c.webp b/translated_images/en/webdev101-js-datatypes.4cc470179730702c.webp new file mode 100644 index 000000000..75bca7c93 Binary files /dev/null and b/translated_images/en/webdev101-js-datatypes.4cc470179730702c.webp differ diff --git a/translated_images/en/webdev101-js-decisions.69e1b20f272dd1f0.webp b/translated_images/en/webdev101-js-decisions.69e1b20f272dd1f0.webp new file mode 100644 index 000000000..3f99231cf Binary files /dev/null and b/translated_images/en/webdev101-js-decisions.69e1b20f272dd1f0.webp differ diff --git a/translated_images/en/webdev101-js-functions.be049c4726e94f8b.webp b/translated_images/en/webdev101-js-functions.be049c4726e94f8b.webp new file mode 100644 index 000000000..f5fef90c1 Binary files /dev/null and b/translated_images/en/webdev101-js-functions.be049c4726e94f8b.webp differ diff --git a/translated_images/en/webdev101-js.10280393044d7eaa.webp b/translated_images/en/webdev101-js.10280393044d7eaa.webp new file mode 100644 index 000000000..a11f4f882 Binary files /dev/null and b/translated_images/en/webdev101-js.10280393044d7eaa.webp differ diff --git a/translated_images/en/webdev101-programming.d6e3f98e61ac4bff.webp b/translated_images/en/webdev101-programming.d6e3f98e61ac4bff.webp new file mode 100644 index 000000000..127becaa2 Binary files /dev/null and b/translated_images/en/webdev101-programming.d6e3f98e61ac4bff.webp differ diff --git a/translated_images/en/working-tree-pb.6cd43e5076f23ba3.webp b/translated_images/en/working-tree-pb.6cd43e5076f23ba3.webp new file mode 100644 index 000000000..5c0775fa7 Binary files /dev/null and b/translated_images/en/working-tree-pb.6cd43e5076f23ba3.webp differ diff --git a/translated_images/en/working-tree.c58eec08e6335c79.webp b/translated_images/en/working-tree.c58eec08e6335c79.webp new file mode 100644 index 000000000..4dc43168b Binary files /dev/null and b/translated_images/en/working-tree.c58eec08e6335c79.webp differ diff --git a/translated_images/enemyShip.035a46787bff658cd126f2e02f640e60fc84536ee2d009a1a5792f3e0423c148.en.png b/translated_images/enemyShip.035a46787bff658cd126f2e02f640e60fc84536ee2d009a1a5792f3e0423c148.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.035a46787bff658cd126f2e02f640e60fc84536ee2d009a1a5792f3e0423c148.en.png and /dev/null differ diff --git a/translated_images/enemyShip.1a1354d7988de290ea352832e06745922d463e9a4a7cca3b8f89477e934b16b2.en.png b/translated_images/enemyShip.1a1354d7988de290ea352832e06745922d463e9a4a7cca3b8f89477e934b16b2.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.1a1354d7988de290ea352832e06745922d463e9a4a7cca3b8f89477e934b16b2.en.png and /dev/null differ diff --git a/translated_images/enemyShip.22cbee6ea27a5809ef09dddc81a4f77714de1a4c8fe2b29ee5d13651f8d60fe0.en.png b/translated_images/enemyShip.22cbee6ea27a5809ef09dddc81a4f77714de1a4c8fe2b29ee5d13651f8d60fe0.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.22cbee6ea27a5809ef09dddc81a4f77714de1a4c8fe2b29ee5d13651f8d60fe0.en.png and /dev/null differ diff --git a/translated_images/enemyShip.321ecb1b4eb21f2c5b74a5118216ac3cbdf4cda52de32993a6c157547e7539bd.en.png b/translated_images/enemyShip.321ecb1b4eb21f2c5b74a5118216ac3cbdf4cda52de32993a6c157547e7539bd.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.321ecb1b4eb21f2c5b74a5118216ac3cbdf4cda52de32993a6c157547e7539bd.en.png and /dev/null differ diff --git a/translated_images/enemyShip.4fbf2889e6129db41989c4c74999ae81dd8d4dd994f1df01f720e923a5749a36.en.png b/translated_images/enemyShip.4fbf2889e6129db41989c4c74999ae81dd8d4dd994f1df01f720e923a5749a36.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.4fbf2889e6129db41989c4c74999ae81dd8d4dd994f1df01f720e923a5749a36.en.png and /dev/null differ diff --git a/translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.en.png b/translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.en.png and /dev/null differ diff --git a/translated_images/enemyShip.62983ed4bfb2220fe28986c8c8c5e6f1528caf879a4290bddbf3550469374c5d.en.png b/translated_images/enemyShip.62983ed4bfb2220fe28986c8c8c5e6f1528caf879a4290bddbf3550469374c5d.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.62983ed4bfb2220fe28986c8c8c5e6f1528caf879a4290bddbf3550469374c5d.en.png and /dev/null differ diff --git a/translated_images/enemyShip.add7036e1c3c30144d4500534897f937d962ffb178f6d7dbb536c2b19f05d3b7.en.png b/translated_images/enemyShip.add7036e1c3c30144d4500534897f937d962ffb178f6d7dbb536c2b19f05d3b7.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.add7036e1c3c30144d4500534897f937d962ffb178f6d7dbb536c2b19f05d3b7.en.png and /dev/null differ diff --git a/translated_images/enemyShip.b39a140287683bf7a409e00e19b41f29793c9dea0220e5d9fb174978fec357a2.en.png b/translated_images/enemyShip.b39a140287683bf7a409e00e19b41f29793c9dea0220e5d9fb174978fec357a2.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.b39a140287683bf7a409e00e19b41f29793c9dea0220e5d9fb174978fec357a2.en.png and /dev/null differ diff --git a/translated_images/enemyShip.b9626ed228a17a323a180f11f359f96848de1c9ee48d76702b49cd1cc3ef3821.en.png b/translated_images/enemyShip.b9626ed228a17a323a180f11f359f96848de1c9ee48d76702b49cd1cc3ef3821.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.b9626ed228a17a323a180f11f359f96848de1c9ee48d76702b49cd1cc3ef3821.en.png and /dev/null differ diff --git a/translated_images/enemyShip.deb0477a7312f54d5e9b3f707b02af3cfa2cafa04e1e9a3dd5818e6ab0244b2c.en.png b/translated_images/enemyShip.deb0477a7312f54d5e9b3f707b02af3cfa2cafa04e1e9a3dd5818e6ab0244b2c.en.png deleted file mode 100644 index 511221671..000000000 Binary files a/translated_images/enemyShip.deb0477a7312f54d5e9b3f707b02af3cfa2cafa04e1e9a3dd5818e6ab0244b2c.en.png and /dev/null differ diff --git a/translated_images/enemyUFO.bf8585e4e8dcdb68e03f67a534d870334c5db3557ad4f960027eac7782cf7ceb.en.png b/translated_images/enemyUFO.bf8585e4e8dcdb68e03f67a534d870334c5db3557ad4f960027eac7782cf7ceb.en.png deleted file mode 100644 index 0431526ad..000000000 Binary files a/translated_images/enemyUFO.bf8585e4e8dcdb68e03f67a534d870334c5db3557ad4f960027eac7782cf7ceb.en.png and /dev/null differ diff --git a/translated_images/extension-details.9f8f1fd4e9eb2de5069ae413119eb8ee43172776383ebe2f7cf640e11df2e106.en.png b/translated_images/extension-details.9f8f1fd4e9eb2de5069ae413119eb8ee43172776383ebe2f7cf640e11df2e106.en.png deleted file mode 100644 index e8763a282..000000000 Binary files a/translated_images/extension-details.9f8f1fd4e9eb2de5069ae413119eb8ee43172776383ebe2f7cf640e11df2e106.en.png and /dev/null differ diff --git a/translated_images/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.en.png b/translated_images/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.en.png deleted file mode 100644 index 00d0890db..000000000 Binary files a/translated_images/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.en.png and /dev/null differ diff --git a/translated_images/extension-settings.21c752ae4f4cdb78a867f140ccd0680e04619d0c44bb4afb26373e54b829d934.en.png b/translated_images/extension-settings.21c752ae4f4cdb78a867f140ccd0680e04619d0c44bb4afb26373e54b829d934.en.png deleted file mode 100644 index 0b90bfbe1..000000000 Binary files a/translated_images/extension-settings.21c752ae4f4cdb78a867f140ccd0680e04619d0c44bb4afb26373e54b829d934.en.png and /dev/null differ diff --git a/translated_images/extensions.eca0e0c7f59a10b5c88be7fe24b3e32cca6b6058b35a49026c3a9d80b1813b7c.en.png b/translated_images/extensions.eca0e0c7f59a10b5c88be7fe24b3e32cca6b6058b35a49026c3a9d80b1813b7c.en.png deleted file mode 100644 index ecc6a080d..000000000 Binary files a/translated_images/extensions.eca0e0c7f59a10b5c88be7fe24b3e32cca6b6058b35a49026c3a9d80b1813b7c.en.png and /dev/null differ diff --git a/translated_images/favicon.37b561214b36d454f9fd1f725d77f310fe256eb88f2a0ae08b9cb18aeb30650c.en.png b/translated_images/favicon.37b561214b36d454f9fd1f725d77f310fe256eb88f2a0ae08b9cb18aeb30650c.en.png deleted file mode 100644 index 26e0ae439..000000000 Binary files a/translated_images/favicon.37b561214b36d454f9fd1f725d77f310fe256eb88f2a0ae08b9cb18aeb30650c.en.png and /dev/null differ diff --git a/translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.en.png b/translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.en.png deleted file mode 100644 index 5ddd08a26..000000000 Binary files a/translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.en.png and /dev/null differ diff --git a/translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.en.png b/translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.en.png deleted file mode 100644 index b66a67183..000000000 Binary files a/translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.en.png and /dev/null differ diff --git a/translated_images/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.en.png b/translated_images/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.en.png deleted file mode 100644 index bcd6d49dd..000000000 Binary files a/translated_images/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.en.png and /dev/null differ diff --git a/translated_images/install-on-edge.d68781acaf0b3d3dada8b7507cde7a64bf74b7040d9818baaa9070668e819f90.en.png b/translated_images/install-on-edge.d68781acaf0b3d3dada8b7507cde7a64bf74b7040d9818baaa9070668e819f90.en.png deleted file mode 100644 index bcd6d49dd..000000000 Binary files a/translated_images/install-on-edge.d68781acaf0b3d3dada8b7507cde7a64bf74b7040d9818baaa9070668e819f90.en.png and /dev/null differ diff --git a/translated_images/laserGreen.89904f0f499455604f204b641dfe992cb6f688d5b1c82a2227d1674af84c0b20.en.png b/translated_images/laserGreen.89904f0f499455604f204b641dfe992cb6f688d5b1c82a2227d1674af84c0b20.en.png deleted file mode 100644 index cfd373b41..000000000 Binary files a/translated_images/laserGreen.89904f0f499455604f204b641dfe992cb6f688d5b1c82a2227d1674af84c0b20.en.png and /dev/null differ diff --git a/translated_images/laserGreenShot.e4fbfc4714c08a5b1a3e94429dde0e5ad4f010c25f0d0b6c321aea62014ed203.en.png b/translated_images/laserGreenShot.e4fbfc4714c08a5b1a3e94429dde0e5ad4f010c25f0d0b6c321aea62014ed203.en.png deleted file mode 100644 index 816fdf33c..000000000 Binary files a/translated_images/laserGreenShot.e4fbfc4714c08a5b1a3e94429dde0e5ad4f010c25f0d0b6c321aea62014ed203.en.png and /dev/null differ diff --git a/translated_images/laserRed.2040e11f55c0a40a9800af7a11247676b4969e6c87e697f29589f605a0192b05.en.png b/translated_images/laserRed.2040e11f55c0a40a9800af7a11247676b4969e6c87e697f29589f605a0192b05.en.png deleted file mode 100644 index 9b6c5f9b8..000000000 Binary files a/translated_images/laserRed.2040e11f55c0a40a9800af7a11247676b4969e6c87e697f29589f605a0192b05.en.png and /dev/null differ diff --git a/translated_images/laserRed.381bc5555491ce677eedc34e728c7c4f5676ce6c74db68d8a4d82fde952cb8fb.en.png b/translated_images/laserRed.381bc5555491ce677eedc34e728c7c4f5676ce6c74db68d8a4d82fde952cb8fb.en.png deleted file mode 100644 index 9b6c5f9b8..000000000 Binary files a/translated_images/laserRed.381bc5555491ce677eedc34e728c7c4f5676ce6c74db68d8a4d82fde952cb8fb.en.png and /dev/null differ diff --git a/translated_images/laserRed.69730edd76f0b3bd5a45ae075c3dd1a064017020ddff4b4c3f007c21d9a62ebc.en.png b/translated_images/laserRed.69730edd76f0b3bd5a45ae075c3dd1a064017020ddff4b4c3f007c21d9a62ebc.en.png deleted file mode 100644 index 9b6c5f9b8..000000000 Binary files a/translated_images/laserRed.69730edd76f0b3bd5a45ae075c3dd1a064017020ddff4b4c3f007c21d9a62ebc.en.png and /dev/null differ diff --git a/translated_images/laserRed.b583dc1728eb8581da951a0ec74c42cf06cf6903e9b939c71baaf04ef1a60f90.en.png b/translated_images/laserRed.b583dc1728eb8581da951a0ec74c42cf06cf6903e9b939c71baaf04ef1a60f90.en.png deleted file mode 100644 index 9b6c5f9b8..000000000 Binary files a/translated_images/laserRed.b583dc1728eb8581da951a0ec74c42cf06cf6903e9b939c71baaf04ef1a60f90.en.png and /dev/null differ diff --git a/translated_images/laserRed.cae9ab24ea9b18fd5fde4b22153f4d71291a363bd611de8108bc6a40cecefe24.en.png b/translated_images/laserRed.cae9ab24ea9b18fd5fde4b22153f4d71291a363bd611de8108bc6a40cecefe24.en.png deleted file mode 100644 index 9b6c5f9b8..000000000 Binary files a/translated_images/laserRed.cae9ab24ea9b18fd5fde4b22153f4d71291a363bd611de8108bc6a40cecefe24.en.png and /dev/null differ diff --git a/translated_images/laserRed.d81ce4986f87c251d4fd93a2fcfb8215c90684ad71d59de7bb0c2561a8e76d56.en.png b/translated_images/laserRed.d81ce4986f87c251d4fd93a2fcfb8215c90684ad71d59de7bb0c2561a8e76d56.en.png deleted file mode 100644 index 9b6c5f9b8..000000000 Binary files a/translated_images/laserRed.d81ce4986f87c251d4fd93a2fcfb8215c90684ad71d59de7bb0c2561a8e76d56.en.png and /dev/null differ diff --git a/translated_images/laserRed.e58ef8db2585dfbe451c9f46f4190d75f555479ddc24e2b75be28fe3a2894f24.en.png b/translated_images/laserRed.e58ef8db2585dfbe451c9f46f4190d75f555479ddc24e2b75be28fe3a2894f24.en.png deleted file mode 100644 index 9b6c5f9b8..000000000 Binary files a/translated_images/laserRed.e58ef8db2585dfbe451c9f46f4190d75f555479ddc24e2b75be28fe3a2894f24.en.png and /dev/null differ diff --git a/translated_images/laserRed.e66e29ace6666064cf451ce990d73b779028e21542cded84ecad88577353aad1.en.png b/translated_images/laserRed.e66e29ace6666064cf451ce990d73b779028e21542cded84ecad88577353aad1.en.png deleted file mode 100644 index 9b6c5f9b8..000000000 Binary files a/translated_images/laserRed.e66e29ace6666064cf451ce990d73b779028e21542cded84ecad88577353aad1.en.png and /dev/null differ diff --git a/translated_images/laserRed.e86e8fb629c6026e20cc7e8507f8a1f2fc82cc355117c721eb08ac67c40d3e6a.en.png b/translated_images/laserRed.e86e8fb629c6026e20cc7e8507f8a1f2fc82cc355117c721eb08ac67c40d3e6a.en.png deleted file mode 100644 index 9b6c5f9b8..000000000 Binary files a/translated_images/laserRed.e86e8fb629c6026e20cc7e8507f8a1f2fc82cc355117c721eb08ac67c40d3e6a.en.png and /dev/null differ diff --git a/translated_images/laserRedShot.c39d066745996a71e5ffb0eeec4eff60fede6dc7fb65bdf8ef8b64193fda04c9.en.png b/translated_images/laserRedShot.c39d066745996a71e5ffb0eeec4eff60fede6dc7fb65bdf8ef8b64193fda04c9.en.png deleted file mode 100644 index 28ecda5ba..000000000 Binary files a/translated_images/laserRedShot.c39d066745996a71e5ffb0eeec4eff60fede6dc7fb65bdf8ef8b64193fda04c9.en.png and /dev/null differ diff --git a/translated_images/life.27144b6d4bfdea76e9613184ff89c93d44888d2c9068a8599553a4306cd539ea.en.png b/translated_images/life.27144b6d4bfdea76e9613184ff89c93d44888d2c9068a8599553a4306cd539ea.en.png deleted file mode 100644 index 3487f796a..000000000 Binary files a/translated_images/life.27144b6d4bfdea76e9613184ff89c93d44888d2c9068a8599553a4306cd539ea.en.png and /dev/null differ diff --git a/translated_images/life.2a159298dd98f4efde6d8b2792eaff08d6944f39e57dbfa65b0b3d7f27addf7e.en.png b/translated_images/life.2a159298dd98f4efde6d8b2792eaff08d6944f39e57dbfa65b0b3d7f27addf7e.en.png deleted file mode 100644 index 3487f796a..000000000 Binary files a/translated_images/life.2a159298dd98f4efde6d8b2792eaff08d6944f39e57dbfa65b0b3d7f27addf7e.en.png and /dev/null differ diff --git a/translated_images/life.466df3b1692a244ad9189538ae5184e6bb43165d7c3172f66b5a60790a1541cc.en.png b/translated_images/life.466df3b1692a244ad9189538ae5184e6bb43165d7c3172f66b5a60790a1541cc.en.png deleted file mode 100644 index 3487f796a..000000000 Binary files a/translated_images/life.466df3b1692a244ad9189538ae5184e6bb43165d7c3172f66b5a60790a1541cc.en.png and /dev/null differ diff --git a/translated_images/life.65a2aaceca87528424e6e93a36e953b58d4facfefbfd42dc4d6ad2db43076018.en.png b/translated_images/life.65a2aaceca87528424e6e93a36e953b58d4facfefbfd42dc4d6ad2db43076018.en.png deleted file mode 100644 index 3487f796a..000000000 Binary files a/translated_images/life.65a2aaceca87528424e6e93a36e953b58d4facfefbfd42dc4d6ad2db43076018.en.png and /dev/null differ diff --git a/translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.en.png b/translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.en.png deleted file mode 100644 index 3487f796a..000000000 Binary files a/translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.en.png and /dev/null differ diff --git a/translated_images/life.78b6e96a3003767e113e7d6fbb5d57fc59245a92579256c08af23c93f2e2b0a3.en.png b/translated_images/life.78b6e96a3003767e113e7d6fbb5d57fc59245a92579256c08af23c93f2e2b0a3.en.png deleted file mode 100644 index 3487f796a..000000000 Binary files a/translated_images/life.78b6e96a3003767e113e7d6fbb5d57fc59245a92579256c08af23c93f2e2b0a3.en.png and /dev/null differ diff --git a/translated_images/life.86d843ce9c23289c0094eff7154a7b6d3cada290b7db733424ee1c68864143c5.en.png b/translated_images/life.86d843ce9c23289c0094eff7154a7b6d3cada290b7db733424ee1c68864143c5.en.png deleted file mode 100644 index 3487f796a..000000000 Binary files a/translated_images/life.86d843ce9c23289c0094eff7154a7b6d3cada290b7db733424ee1c68864143c5.en.png and /dev/null differ diff --git a/translated_images/localstorage.472f8147b6a3f8d141d9551c95a2da610ac9a3c6a73d4a1c224081c98bae09d9.en.png b/translated_images/localstorage.472f8147b6a3f8d141d9551c95a2da610ac9a3c6a73d4a1c224081c98bae09d9.en.png deleted file mode 100644 index 251fcfcee..000000000 Binary files a/translated_images/localstorage.472f8147b6a3f8d141d9551c95a2da610ac9a3c6a73d4a1c224081c98bae09d9.en.png and /dev/null differ diff --git a/translated_images/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.en.png b/translated_images/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.en.png deleted file mode 100644 index 10c7c0d0d..000000000 Binary files a/translated_images/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.en.png and /dev/null differ diff --git a/translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.en.png b/translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.en.png deleted file mode 100644 index 53147dc21..000000000 Binary files a/translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.en.png and /dev/null differ diff --git a/translated_images/meteorBig.1e452b3ad7af50adaafcbe25c82b2758be31cdff66d6b417b79f5453bf9ad3e0.en.png b/translated_images/meteorBig.1e452b3ad7af50adaafcbe25c82b2758be31cdff66d6b417b79f5453bf9ad3e0.en.png deleted file mode 100644 index b3cd54079..000000000 Binary files a/translated_images/meteorBig.1e452b3ad7af50adaafcbe25c82b2758be31cdff66d6b417b79f5453bf9ad3e0.en.png and /dev/null differ diff --git a/translated_images/meteorSmall.0d729bc71c12d41f26f077dfbecaccb9016e21e11dac7966e4f2de825e5de3b6.en.png b/translated_images/meteorSmall.0d729bc71c12d41f26f077dfbecaccb9016e21e11dac7966e4f2de825e5de3b6.en.png deleted file mode 100644 index a61e0e285..000000000 Binary files a/translated_images/meteorSmall.0d729bc71c12d41f26f077dfbecaccb9016e21e11dac7966e4f2de825e5de3b6.en.png and /dev/null differ diff --git a/translated_images/moodle.94eb93d714a50cb2c97435b408017dee224348b61bc86203ffd43a4f4e57b95f.en.png b/translated_images/moodle.94eb93d714a50cb2c97435b408017dee224348b61bc86203ffd43a4f4e57b95f.en.png deleted file mode 100644 index 65b0a4fd6..000000000 Binary files a/translated_images/moodle.94eb93d714a50cb2c97435b408017dee224348b61bc86203ffd43a4f4e57b95f.en.png and /dev/null differ diff --git a/translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.en.png b/translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.en.png deleted file mode 100644 index a1eff225e..000000000 Binary files a/translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.en.png and /dev/null differ diff --git a/translated_images/nebula.55c2933d36d035d359ef8d8422e7a7f260b3f6d15c026a18472bf8e71185d59c.en.png b/translated_images/nebula.55c2933d36d035d359ef8d8422e7a7f260b3f6d15c026a18472bf8e71185d59c.en.png deleted file mode 100644 index 755230882..000000000 Binary files a/translated_images/nebula.55c2933d36d035d359ef8d8422e7a7f260b3f6d15c026a18472bf8e71185d59c.en.png and /dev/null differ diff --git a/translated_images/new-file-github.com.c886796d800e8056561829a181be1382c5303da9d902d8b2dd82b68a4806e21f.en.png b/translated_images/new-file-github.com.c886796d800e8056561829a181be1382c5303da9d902d8b2dd82b68a4806e21f.en.png deleted file mode 100644 index 6032b4abf..000000000 Binary files a/translated_images/new-file-github.com.c886796d800e8056561829a181be1382c5303da9d902d8b2dd82b68a4806e21f.en.png and /dev/null differ diff --git a/translated_images/open-palette-menu.46dda01084738da84fc55100956fcc915f33e9de8c19813148ac3b1803871cff.en.png b/translated_images/open-palette-menu.46dda01084738da84fc55100956fcc915f33e9de8c19813148ac3b1803871cff.en.png deleted file mode 100644 index 4d8582431..000000000 Binary files a/translated_images/open-palette-menu.46dda01084738da84fc55100956fcc915f33e9de8c19813148ac3b1803871cff.en.png and /dev/null differ diff --git a/translated_images/open-remote-repository.bd9c2598b8949e7fc283cdfc8f4050c6205a7c7c6d3f78c4b135115d037d6fa2.en.png b/translated_images/open-remote-repository.bd9c2598b8949e7fc283cdfc8f4050c6205a7c7c6d3f78c4b135115d037d6fa2.en.png deleted file mode 100644 index 9dc30ee1c..000000000 Binary files a/translated_images/open-remote-repository.bd9c2598b8949e7fc283cdfc8f4050c6205a7c7c6d3f78c4b135115d037d6fa2.en.png and /dev/null differ diff --git a/translated_images/palette-menu.4946174e07f426226afcdad707d19b8d5150e41591c751c45b5dee213affef91.en.png b/translated_images/palette-menu.4946174e07f426226afcdad707d19b8d5150e41591c751c45b5dee213affef91.en.png deleted file mode 100644 index 1c1b335c9..000000000 Binary files a/translated_images/palette-menu.4946174e07f426226afcdad707d19b8d5150e41591c751c45b5dee213affef91.en.png and /dev/null differ diff --git a/translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.en.png b/translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.en.png deleted file mode 100644 index 88783500d..000000000 Binary files a/translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.en.png and /dev/null differ diff --git a/translated_images/plant1.a876180d8659acb9a51f95b2466b207b95dec201fafa23efcd4137fb62d0acb1.en.png b/translated_images/plant1.a876180d8659acb9a51f95b2466b207b95dec201fafa23efcd4137fb62d0acb1.en.png deleted file mode 100644 index 0632233d0..000000000 Binary files a/translated_images/plant1.a876180d8659acb9a51f95b2466b207b95dec201fafa23efcd4137fb62d0acb1.en.png and /dev/null differ diff --git a/translated_images/plant10.2f2c47804ae52dd3550b3f97782a76629d5819bba30e8a8b79933a9ccde606d4.en.png b/translated_images/plant10.2f2c47804ae52dd3550b3f97782a76629d5819bba30e8a8b79933a9ccde606d4.en.png deleted file mode 100644 index 209ee5d22..000000000 Binary files a/translated_images/plant10.2f2c47804ae52dd3550b3f97782a76629d5819bba30e8a8b79933a9ccde606d4.en.png and /dev/null differ diff --git a/translated_images/plant11.0ce0081b0ef17aa1793cc5fe6d7de6f8cf7f8cfb24933c3c457386194fc10e77.en.png b/translated_images/plant11.0ce0081b0ef17aa1793cc5fe6d7de6f8cf7f8cfb24933c3c457386194fc10e77.en.png deleted file mode 100644 index 201bec9e6..000000000 Binary files a/translated_images/plant11.0ce0081b0ef17aa1793cc5fe6d7de6f8cf7f8cfb24933c3c457386194fc10e77.en.png and /dev/null differ diff --git a/translated_images/plant12.6b934c4312a00228719509ac56cd568ec45672bfdcc732bac7f42391035d606c.en.png b/translated_images/plant12.6b934c4312a00228719509ac56cd568ec45672bfdcc732bac7f42391035d606c.en.png deleted file mode 100644 index 593e15732..000000000 Binary files a/translated_images/plant12.6b934c4312a00228719509ac56cd568ec45672bfdcc732bac7f42391035d606c.en.png and /dev/null differ diff --git a/translated_images/plant13.37d6ab2e2481421f0611f07685309cc07fe42d63e6abbaa963f972dbff7d176d.en.png b/translated_images/plant13.37d6ab2e2481421f0611f07685309cc07fe42d63e6abbaa963f972dbff7d176d.en.png deleted file mode 100644 index 0f69b814b..000000000 Binary files a/translated_images/plant13.37d6ab2e2481421f0611f07685309cc07fe42d63e6abbaa963f972dbff7d176d.en.png and /dev/null differ diff --git a/translated_images/plant14.908791477a46eb7f40a85155f53861fa5734be5075443b5c19f78e758f64d286.en.png b/translated_images/plant14.908791477a46eb7f40a85155f53861fa5734be5075443b5c19f78e758f64d286.en.png deleted file mode 100644 index 221277ef2..000000000 Binary files a/translated_images/plant14.908791477a46eb7f40a85155f53861fa5734be5075443b5c19f78e758f64d286.en.png and /dev/null differ diff --git a/translated_images/plant2.9e45efea224115b077fade85ce6871246bf85de20f419c57faed6b78e9ac7fcd.en.png b/translated_images/plant2.9e45efea224115b077fade85ce6871246bf85de20f419c57faed6b78e9ac7fcd.en.png deleted file mode 100644 index 331ca68d1..000000000 Binary files a/translated_images/plant2.9e45efea224115b077fade85ce6871246bf85de20f419c57faed6b78e9ac7fcd.en.png and /dev/null differ diff --git a/translated_images/plant3.06efdd0fa0c4b1152034312e11765b1a8fad48ebc00b72a3e7df657f66f45449.en.png b/translated_images/plant3.06efdd0fa0c4b1152034312e11765b1a8fad48ebc00b72a3e7df657f66f45449.en.png deleted file mode 100644 index d94bd097e..000000000 Binary files a/translated_images/plant3.06efdd0fa0c4b1152034312e11765b1a8fad48ebc00b72a3e7df657f66f45449.en.png and /dev/null differ diff --git a/translated_images/plant4.3b78072b427727c6e6eb08eefc8451b248577412dd025002cefb707238e8bf46.en.png b/translated_images/plant4.3b78072b427727c6e6eb08eefc8451b248577412dd025002cefb707238e8bf46.en.png deleted file mode 100644 index c60f756c7..000000000 Binary files a/translated_images/plant4.3b78072b427727c6e6eb08eefc8451b248577412dd025002cefb707238e8bf46.en.png and /dev/null differ diff --git a/translated_images/plant5.8ec58b18ac336fa8ec87ce1d5b433ee58c4918e67fdf0315d5407d80cbd97569.en.png b/translated_images/plant5.8ec58b18ac336fa8ec87ce1d5b433ee58c4918e67fdf0315d5407d80cbd97569.en.png deleted file mode 100644 index f2fe32fb9..000000000 Binary files a/translated_images/plant5.8ec58b18ac336fa8ec87ce1d5b433ee58c4918e67fdf0315d5407d80cbd97569.en.png and /dev/null differ diff --git a/translated_images/plant6.ca4ff8372e6676b1ffed650fba21cb2af52c70df969a8203e57fb5bedd81e9f0.en.png b/translated_images/plant6.ca4ff8372e6676b1ffed650fba21cb2af52c70df969a8203e57fb5bedd81e9f0.en.png deleted file mode 100644 index 82e0db0d9..000000000 Binary files a/translated_images/plant6.ca4ff8372e6676b1ffed650fba21cb2af52c70df969a8203e57fb5bedd81e9f0.en.png and /dev/null differ diff --git a/translated_images/plant7.194d5a42fcf5a88c5dd4960c68e6f78707acdb4e21bf533a6a65f8d002ab660b.en.png b/translated_images/plant7.194d5a42fcf5a88c5dd4960c68e6f78707acdb4e21bf533a6a65f8d002ab660b.en.png deleted file mode 100644 index 07cb7054d..000000000 Binary files a/translated_images/plant7.194d5a42fcf5a88c5dd4960c68e6f78707acdb4e21bf533a6a65f8d002ab660b.en.png and /dev/null differ diff --git a/translated_images/plant8.7b247809ab0eb492105cac4f42b79ac771ce56e401fdf3df170b3b6ef03c5642.en.png b/translated_images/plant8.7b247809ab0eb492105cac4f42b79ac771ce56e401fdf3df170b3b6ef03c5642.en.png deleted file mode 100644 index a0d261a90..000000000 Binary files a/translated_images/plant8.7b247809ab0eb492105cac4f42b79ac771ce56e401fdf3df170b3b6ef03c5642.en.png and /dev/null differ diff --git a/translated_images/plant9.8fe614c01ded1b1ec05d1b4d6d527047b1ece5edba299c1c516aaf4b05eb19ed.en.png b/translated_images/plant9.8fe614c01ded1b1ec05d1b4d6d527047b1ece5edba299c1c516aaf4b05eb19ed.en.png deleted file mode 100644 index bc09a0506..000000000 Binary files a/translated_images/plant9.8fe614c01ded1b1ec05d1b4d6d527047b1ece5edba299c1c516aaf4b05eb19ed.en.png and /dev/null differ diff --git a/translated_images/player.137ee0e47f895ffcdb50ba1b316936715ec8decfd6cee3258332a6c60e5d0d04.en.png b/translated_images/player.137ee0e47f895ffcdb50ba1b316936715ec8decfd6cee3258332a6c60e5d0d04.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.137ee0e47f895ffcdb50ba1b316936715ec8decfd6cee3258332a6c60e5d0d04.en.png and /dev/null differ diff --git a/translated_images/player.2887422f6982c3cd284b2bafd7551ff073a7b7b8a66edd2f0c2c722f94acfd5c.en.png b/translated_images/player.2887422f6982c3cd284b2bafd7551ff073a7b7b8a66edd2f0c2c722f94acfd5c.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.2887422f6982c3cd284b2bafd7551ff073a7b7b8a66edd2f0c2c722f94acfd5c.en.png and /dev/null differ diff --git a/translated_images/player.391fed427ede24f513d4b559cff8ff60f00818b31c81268b783a7f89054fda90.en.png b/translated_images/player.391fed427ede24f513d4b559cff8ff60f00818b31c81268b783a7f89054fda90.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.391fed427ede24f513d4b559cff8ff60f00818b31c81268b783a7f89054fda90.en.png and /dev/null differ diff --git a/translated_images/player.3c4f50182552a73a2b22542c75209c57231da2f51d88d571f198382e2fb3b45b.en.png b/translated_images/player.3c4f50182552a73a2b22542c75209c57231da2f51d88d571f198382e2fb3b45b.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.3c4f50182552a73a2b22542c75209c57231da2f51d88d571f198382e2fb3b45b.en.png and /dev/null differ diff --git a/translated_images/player.47bc9de0714c723dfe0705c328fb8769de71c87b99d340921c2247674d9d631a.en.png b/translated_images/player.47bc9de0714c723dfe0705c328fb8769de71c87b99d340921c2247674d9d631a.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.47bc9de0714c723dfe0705c328fb8769de71c87b99d340921c2247674d9d631a.en.png and /dev/null differ diff --git a/translated_images/player.57b3107c03012695cedb271fdda06900e2d0d9580ae5fab5c563fdb029ba8584.en.png b/translated_images/player.57b3107c03012695cedb271fdda06900e2d0d9580ae5fab5c563fdb029ba8584.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.57b3107c03012695cedb271fdda06900e2d0d9580ae5fab5c563fdb029ba8584.en.png and /dev/null differ diff --git a/translated_images/player.606f85953e5e564e7711d22697724750fdcc661d5f7c5295e2da7e46905fd322.en.png b/translated_images/player.606f85953e5e564e7711d22697724750fdcc661d5f7c5295e2da7e46905fd322.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.606f85953e5e564e7711d22697724750fdcc661d5f7c5295e2da7e46905fd322.en.png and /dev/null differ diff --git a/translated_images/player.680ea4c619b54fe160261abdfe2e68139dedacb8d884b6cb405b9a6ab162940d.en.png b/translated_images/player.680ea4c619b54fe160261abdfe2e68139dedacb8d884b6cb405b9a6ab162940d.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.680ea4c619b54fe160261abdfe2e68139dedacb8d884b6cb405b9a6ab162940d.en.png and /dev/null differ diff --git a/translated_images/player.bfe14f110bddf56d10a1989066d170af2ce6b1412626c37a7e184963e54c7ef4.en.png b/translated_images/player.bfe14f110bddf56d10a1989066d170af2ce6b1412626c37a7e184963e54c7ef4.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.bfe14f110bddf56d10a1989066d170af2ce6b1412626c37a7e184963e54c7ef4.en.png and /dev/null differ diff --git a/translated_images/player.c99c25d54a615ca088fc55515a6ee76c766fba0e31b167816062f3ab3d22fbcd.en.png b/translated_images/player.c99c25d54a615ca088fc55515a6ee76c766fba0e31b167816062f3ab3d22fbcd.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.c99c25d54a615ca088fc55515a6ee76c766fba0e31b167816062f3ab3d22fbcd.en.png and /dev/null differ diff --git a/translated_images/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.en.png b/translated_images/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.en.png deleted file mode 100644 index 13fc0247c..000000000 Binary files a/translated_images/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.en.png and /dev/null differ diff --git a/translated_images/playerDamaged.181703f652fd5176d25dbc286cdab2b79c9d7470dfd95af344dbb024780b6176.en.png b/translated_images/playerDamaged.181703f652fd5176d25dbc286cdab2b79c9d7470dfd95af344dbb024780b6176.en.png deleted file mode 100644 index 91d73b263..000000000 Binary files a/translated_images/playerDamaged.181703f652fd5176d25dbc286cdab2b79c9d7470dfd95af344dbb024780b6176.en.png and /dev/null differ diff --git a/translated_images/playerLeft.0f928412e66ba5d9455ccc99ef113088d2510843b23f8dbcd3106425b221979f.en.png b/translated_images/playerLeft.0f928412e66ba5d9455ccc99ef113088d2510843b23f8dbcd3106425b221979f.en.png deleted file mode 100644 index 941cd3ace..000000000 Binary files a/translated_images/playerLeft.0f928412e66ba5d9455ccc99ef113088d2510843b23f8dbcd3106425b221979f.en.png and /dev/null differ diff --git a/translated_images/playerRight.e4825f489e29f73719f8e3197ba0e5742e2ffbc178641009b57fe254c6abdc38.en.png b/translated_images/playerRight.e4825f489e29f73719f8e3197ba0e5742e2ffbc178641009b57fe254c6abdc38.en.png deleted file mode 100644 index 4e69314c4..000000000 Binary files a/translated_images/playerRight.e4825f489e29f73719f8e3197ba0e5742e2ffbc178641009b57fe254c6abdc38.en.png and /dev/null differ diff --git a/translated_images/playground-choice.1d23ba7d407f47584c9f446c77f0bcf70cae794cc9c8d7849a3cca4a3693e6c4.en.png b/translated_images/playground-choice.1d23ba7d407f47584c9f446c77f0bcf70cae794cc9c8d7849a3cca4a3693e6c4.en.png deleted file mode 100644 index 0cfc445d7..000000000 Binary files a/translated_images/playground-choice.1d23ba7d407f47584c9f446c77f0bcf70cae794cc9c8d7849a3cca4a3693e6c4.en.png and /dev/null differ diff --git a/translated_images/playground.d2b927122224ff8ff4028fc842176e353c339147d8925455f36c92fb1655c477.en.png b/translated_images/playground.d2b927122224ff8ff4028fc842176e353c339147d8925455f36c92fb1655c477.en.png deleted file mode 100644 index 0ae823503..000000000 Binary files a/translated_images/playground.d2b927122224ff8ff4028fc842176e353c339147d8925455f36c92fb1655c477.en.png and /dev/null differ diff --git a/translated_images/preview.9215f0a010074476f8ab66e6becf3c1b594a30cca0a28b88fb4f3f4821594dc0.en.jpg b/translated_images/preview.9215f0a010074476f8ab66e6becf3c1b594a30cca0a28b88fb4f3f4821594dc0.en.jpg deleted file mode 100644 index b776392d7..000000000 Binary files a/translated_images/preview.9215f0a010074476f8ab66e6becf3c1b594a30cca0a28b88fb4f3f4821594dc0.en.jpg and /dev/null differ diff --git a/translated_images/profiler.5a4a62479c5df01cfec9aab74173dba13f91d2c968e1a1ae434c26165792df15.en.png b/translated_images/profiler.5a4a62479c5df01cfec9aab74173dba13f91d2c968e1a1ae434c26165792df15.en.png deleted file mode 100644 index c1c079cfb..000000000 Binary files a/translated_images/profiler.5a4a62479c5df01cfec9aab74173dba13f91d2c968e1a1ae434c26165792df15.en.png and /dev/null differ diff --git a/translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.en.png b/translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.en.png deleted file mode 100644 index 98f02933a..000000000 Binary files a/translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.en.png and /dev/null differ diff --git a/translated_images/result.96ef01f607bf856aa9789078633e94a4f7664d912f235efce2657299becca483.en.png b/translated_images/result.96ef01f607bf856aa9789078633e94a4f7664d912f235efce2657299becca483.en.png deleted file mode 100644 index 755bf0f58..000000000 Binary files a/translated_images/result.96ef01f607bf856aa9789078633e94a4f7664d912f235efce2657299becca483.en.png and /dev/null differ diff --git a/translated_images/screen1.baccbba0f1f93364672eb250d2fbd21574bb1caf79a2155022dc098a741cbdfe.en.png b/translated_images/screen1.baccbba0f1f93364672eb250d2fbd21574bb1caf79a2155022dc098a741cbdfe.en.png deleted file mode 100644 index 9f669d468..000000000 Binary files a/translated_images/screen1.baccbba0f1f93364672eb250d2fbd21574bb1caf79a2155022dc098a741cbdfe.en.png and /dev/null differ diff --git a/translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.en.png b/translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.en.png deleted file mode 100644 index 91c965e9b..000000000 Binary files a/translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.en.png and /dev/null differ diff --git a/translated_images/screenshot.0a1ee0d123df681b4501eb53ffb267519fcc20aa653eabecef1e7561ddfb1cab.en.png b/translated_images/screenshot.0a1ee0d123df681b4501eb53ffb267519fcc20aa653eabecef1e7561ddfb1cab.en.png deleted file mode 100644 index 518fbb44f..000000000 Binary files a/translated_images/screenshot.0a1ee0d123df681b4501eb53ffb267519fcc20aa653eabecef1e7561ddfb1cab.en.png and /dev/null differ diff --git a/translated_images/screenshot.e7a5ad659e3645682a7d44bd944af8147012dc403b4965712a052214b42e77c1.en.png b/translated_images/screenshot.e7a5ad659e3645682a7d44bd944af8147012dc403b4965712a052214b42e77c1.en.png deleted file mode 100644 index e56466c7e..000000000 Binary files a/translated_images/screenshot.e7a5ad659e3645682a7d44bd944af8147012dc403b4965712a052214b42e77c1.en.png and /dev/null differ diff --git a/translated_images/screenshot_gray.0c796099a1f9f25e40aa55ead81f268434c00af30d7092490759945eda63067d.en.png b/translated_images/screenshot_gray.0c796099a1f9f25e40aa55ead81f268434c00af30d7092490759945eda63067d.en.png deleted file mode 100644 index c46266c6b..000000000 Binary files a/translated_images/screenshot_gray.0c796099a1f9f25e40aa55ead81f268434c00af30d7092490759945eda63067d.en.png and /dev/null differ diff --git a/translated_images/shield.1b9412b7ca6610ab21f8836483f4e1ec7835b7fe61617f2cead3ff3317ddd56f.en.png b/translated_images/shield.1b9412b7ca6610ab21f8836483f4e1ec7835b7fe61617f2cead3ff3317ddd56f.en.png deleted file mode 100644 index b962a2f13..000000000 Binary files a/translated_images/shield.1b9412b7ca6610ab21f8836483f4e1ec7835b7fe61617f2cead3ff3317ddd56f.en.png and /dev/null differ diff --git a/translated_images/snapshot.97750180ebcad73794a3594b36925eb5c8dbaac9e03fec7f9b974188c9ac63c7.en.png b/translated_images/snapshot.97750180ebcad73794a3594b36925eb5c8dbaac9e03fec7f9b974188c9ac63c7.en.png deleted file mode 100644 index 7101e10cd..000000000 Binary files a/translated_images/snapshot.97750180ebcad73794a3594b36925eb5c8dbaac9e03fec7f9b974188c9ac63c7.en.png and /dev/null differ diff --git a/translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.en.png b/translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.en.png deleted file mode 100644 index 80f8578e5..000000000 Binary files a/translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.en.png and /dev/null differ diff --git a/translated_images/speedLine.5bcabb93f48b5ae1fe081a6b8832ed314636560b7bb228889bfbeb75a0322490.en.png b/translated_images/speedLine.5bcabb93f48b5ae1fe081a6b8832ed314636560b7bb228889bfbeb75a0322490.en.png deleted file mode 100644 index 03018e7f2..000000000 Binary files a/translated_images/speedLine.5bcabb93f48b5ae1fe081a6b8832ed314636560b7bb228889bfbeb75a0322490.en.png and /dev/null differ diff --git a/translated_images/spritesheet.bec82852290b14ee8f814b4173f8d823658151a2402c2be8f15b17159290d1ab.en.png b/translated_images/spritesheet.bec82852290b14ee8f814b4173f8d823658151a2402c2be8f15b17159290d1ab.en.png deleted file mode 100644 index c7f6f709d..000000000 Binary files a/translated_images/spritesheet.bec82852290b14ee8f814b4173f8d823658151a2402c2be8f15b17159290d1ab.en.png and /dev/null differ diff --git a/translated_images/starBackground.a897b8acb1b0587dbb2cdbf8beeaa388269510bb3ac3b4165f0141dc893045a2.en.png b/translated_images/starBackground.a897b8acb1b0587dbb2cdbf8beeaa388269510bb3ac3b4165f0141dc893045a2.en.png deleted file mode 100644 index 7344ae888..000000000 Binary files a/translated_images/starBackground.a897b8acb1b0587dbb2cdbf8beeaa388269510bb3ac3b4165f0141dc893045a2.en.png and /dev/null differ diff --git a/translated_images/starBig.72e9c6d0d18f363d485fd26a32c346d269d465f6a87bc0ca5e94ecd34fcd7362.en.png b/translated_images/starBig.72e9c6d0d18f363d485fd26a32c346d269d465f6a87bc0ca5e94ecd34fcd7362.en.png deleted file mode 100644 index e38c77b7c..000000000 Binary files a/translated_images/starBig.72e9c6d0d18f363d485fd26a32c346d269d465f6a87bc0ca5e94ecd34fcd7362.en.png and /dev/null differ diff --git a/translated_images/starSmall.ed78b961dbcd0898e8b9b721cbaaa8d54a0a1165a52a13f19650064add273eec.en.png b/translated_images/starSmall.ed78b961dbcd0898e8b9b721cbaaa8d54a0a1165a52a13f19650064add273eec.en.png deleted file mode 100644 index 56bcfd58c..000000000 Binary files a/translated_images/starSmall.ed78b961dbcd0898e8b9b721cbaaa8d54a0a1165a52a13f19650064add273eec.en.png and /dev/null differ diff --git a/translated_images/template.67ad477109d29a2b04599a83c964c87fcde041256d4f04d3589cbb00c696f76c.en.png b/translated_images/template.67ad477109d29a2b04599a83c964c87fcde041256d4f04d3589cbb00c696f76c.en.png deleted file mode 100644 index 3b2a2c44b..000000000 Binary files a/translated_images/template.67ad477109d29a2b04599a83c964c87fcde041256d4f04d3589cbb00c696f76c.en.png and /dev/null differ diff --git a/translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.en.png b/translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.en.png deleted file mode 100644 index c46266c6b..000000000 Binary files a/translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.en.png and /dev/null differ diff --git a/translated_images/terrarium-final.2f07047ffc597d0a06b06cab28a77801a10dd12fdb6c7fc630e9c40665491c53.en.png b/translated_images/terrarium-final.2f07047ffc597d0a06b06cab28a77801a10dd12fdb6c7fc630e9c40665491c53.en.png deleted file mode 100644 index 50f5d0af5..000000000 Binary files a/translated_images/terrarium-final.2f07047ffc597d0a06b06cab28a77801a10dd12fdb6c7fc630e9c40665491c53.en.png and /dev/null differ diff --git a/translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.en.png b/translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.en.png deleted file mode 100644 index ca7fed243..000000000 Binary files a/translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.en.png and /dev/null differ diff --git a/translated_images/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.en.png b/translated_images/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.en.png deleted file mode 100644 index 0b483b87e..000000000 Binary files a/translated_images/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.en.png and /dev/null differ diff --git a/translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.en.png b/translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.en.png deleted file mode 100644 index b2b0220d5..000000000 Binary files a/translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.en.png and /dev/null differ diff --git a/translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.en.png b/translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.en.png deleted file mode 100644 index 098efdf50..000000000 Binary files a/translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.en.png and /dev/null differ diff --git a/translated_images/webdev101-github.8846d7971abef6f947909b4f9d343e2a23778aa716ca6b9d71df7174ee5009ac.en.png b/translated_images/webdev101-github.8846d7971abef6f947909b4f9d343e2a23778aa716ca6b9d71df7174ee5009ac.en.png deleted file mode 100644 index 29388480a..000000000 Binary files a/translated_images/webdev101-github.8846d7971abef6f947909b4f9d343e2a23778aa716ca6b9d71df7174ee5009ac.en.png and /dev/null differ diff --git a/translated_images/webdev101-html.4389c2067af68e98280c1bde52b6c6269f399eaae3659b7c846018d8a7b0bbd9.en.png b/translated_images/webdev101-html.4389c2067af68e98280c1bde52b6c6269f399eaae3659b7c846018d8a7b0bbd9.en.png deleted file mode 100644 index f6cf31b49..000000000 Binary files a/translated_images/webdev101-html.4389c2067af68e98280c1bde52b6c6269f399eaae3659b7c846018d8a7b0bbd9.en.png and /dev/null differ diff --git a/translated_images/webdev101-js-arrays.439d7528b8a294558d0e4302e448d193f8ad7495cc407539cc81f1afe904b470.en.png b/translated_images/webdev101-js-arrays.439d7528b8a294558d0e4302e448d193f8ad7495cc407539cc81f1afe904b470.en.png deleted file mode 100644 index 37c841353..000000000 Binary files a/translated_images/webdev101-js-arrays.439d7528b8a294558d0e4302e448d193f8ad7495cc407539cc81f1afe904b470.en.png and /dev/null differ diff --git a/translated_images/webdev101-js-datatypes.4cc470179730702c756480d3ffa46507f746e5975ebf80f99fdaaf1cff09a7f4.en.png b/translated_images/webdev101-js-datatypes.4cc470179730702c756480d3ffa46507f746e5975ebf80f99fdaaf1cff09a7f4.en.png deleted file mode 100644 index a7c724e8a..000000000 Binary files a/translated_images/webdev101-js-datatypes.4cc470179730702c756480d3ffa46507f746e5975ebf80f99fdaaf1cff09a7f4.en.png and /dev/null differ diff --git a/translated_images/webdev101-js-decisions.69e1b20f272dd1f0b1cb2f8adaff3ed2a77c4f91db96d8a0594132a353fa189a.en.png b/translated_images/webdev101-js-decisions.69e1b20f272dd1f0b1cb2f8adaff3ed2a77c4f91db96d8a0594132a353fa189a.en.png deleted file mode 100644 index 7f6ffbf6e..000000000 Binary files a/translated_images/webdev101-js-decisions.69e1b20f272dd1f0b1cb2f8adaff3ed2a77c4f91db96d8a0594132a353fa189a.en.png and /dev/null differ diff --git a/translated_images/webdev101-js-functions.be049c4726e94f8b7605c36330ac42eeb5cd8ed02bcdd60fdac778174d6cb865.en.png b/translated_images/webdev101-js-functions.be049c4726e94f8b7605c36330ac42eeb5cd8ed02bcdd60fdac778174d6cb865.en.png deleted file mode 100644 index cfce51a5c..000000000 Binary files a/translated_images/webdev101-js-functions.be049c4726e94f8b7605c36330ac42eeb5cd8ed02bcdd60fdac778174d6cb865.en.png and /dev/null differ diff --git a/translated_images/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.en.png b/translated_images/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.en.png deleted file mode 100644 index 259f524b2..000000000 Binary files a/translated_images/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.en.png and /dev/null differ diff --git a/translated_images/webdev101-programming.d6e3f98e61ac4bff0b27dcbf1c3f16c8ed46984866f2d29988929678b0058fde.en.png b/translated_images/webdev101-programming.d6e3f98e61ac4bff0b27dcbf1c3f16c8ed46984866f2d29988929678b0058fde.en.png deleted file mode 100644 index cb4b05596..000000000 Binary files a/translated_images/webdev101-programming.d6e3f98e61ac4bff0b27dcbf1c3f16c8ed46984866f2d29988929678b0058fde.en.png and /dev/null differ diff --git a/translated_images/working-tree-pb.6cd43e5076f23ba3d017f7662394bd87f975e194a068556905e4cc99da9cbfdc.en.png b/translated_images/working-tree-pb.6cd43e5076f23ba3d017f7662394bd87f975e194a068556905e4cc99da9cbfdc.en.png deleted file mode 100644 index e5bfe5642..000000000 Binary files a/translated_images/working-tree-pb.6cd43e5076f23ba3d017f7662394bd87f975e194a068556905e4cc99da9cbfdc.en.png and /dev/null differ diff --git a/translated_images/working-tree.c58eec08e6335c79cc708c0c220c0b7fea61514bd3c7fb7471905a864aceac7c.en.png b/translated_images/working-tree.c58eec08e6335c79cc708c0c220c0b7fea61514bd3c7fb7471905a864aceac7c.en.png deleted file mode 100644 index 129c89ced..000000000 Binary files a/translated_images/working-tree.c58eec08e6335c79cc708c0c220c0b7fea61514bd3c7fb7471905a864aceac7c.en.png and /dev/null differ diff --git a/translations/en/.co-op-translator.json b/translations/en/.co-op-translator.json new file mode 100644 index 000000000..51d15da1c --- /dev/null +++ b/translations/en/.co-op-translator.json @@ -0,0 +1,584 @@ +{ + "1-getting-started-lessons/1-intro-to-programming-languages/README.md": { + "original_hash": "bec5e35642176d9e483552bfc82996d8", + "translation_date": "2026-03-06T11:35:13+00:00", + "source_file": "1-getting-started-lessons/1-intro-to-programming-languages/README.md", + "language_code": "en" + }, + "1-getting-started-lessons/1-intro-to-programming-languages/assignment.md": { + "original_hash": "17b8ec8e85d99e27dcb3f73842e583be", + "translation_date": "2026-03-06T11:35:29+00:00", + "source_file": "1-getting-started-lessons/1-intro-to-programming-languages/assignment.md", + "language_code": "en" + }, + "1-getting-started-lessons/2-github-basics/README.md": { + "original_hash": "5c383cc2cc23bb164b06417d1c107a44", + "translation_date": "2026-03-06T11:37:58+00:00", + "source_file": "1-getting-started-lessons/2-github-basics/README.md", + "language_code": "en" + }, + "1-getting-started-lessons/3-accessibility/README.md": { + "original_hash": "7f2c48e04754724123ea100a822765e5", + "translation_date": "2026-03-06T11:31:39+00:00", + "source_file": "1-getting-started-lessons/3-accessibility/README.md", + "language_code": "en" + }, + "1-getting-started-lessons/3-accessibility/assignment.md": { + "original_hash": "e6d0f456dfc22afb41bbdefeb5ec179d", + "translation_date": "2026-03-06T11:32:26+00:00", + "source_file": "1-getting-started-lessons/3-accessibility/assignment.md", + "language_code": "en" + }, + "1-getting-started-lessons/README.md": { + "original_hash": "770d9f83dddc841c19f210dee5fe0712", + "translation_date": "2025-10-03T13:25:08+00:00", + "source_file": "1-getting-started-lessons/README.md", + "language_code": "en" + }, + "10-ai-framework-project/README.md": { + "original_hash": "3925b6a1c31c60755eaae4d578232c25", + "translation_date": "2026-03-06T10:39:12+00:00", + "source_file": "10-ai-framework-project/README.md", + "language_code": "en" + }, + "2-js-basics/1-data-types/README.md": { + "original_hash": "672b0bb6e8b431075f3bdb7130590d2d", + "translation_date": "2026-03-06T10:48:37+00:00", + "source_file": "2-js-basics/1-data-types/README.md", + "language_code": "en" + }, + "2-js-basics/1-data-types/assignment.md": { + "original_hash": "6fd645e97c48cd5eb5a3d290815ec8b5", + "translation_date": "2026-03-06T10:48:45+00:00", + "source_file": "2-js-basics/1-data-types/assignment.md", + "language_code": "en" + }, + "2-js-basics/2-functions-methods/README.md": { + "original_hash": "71f7d7dafa1c7194d79ddac87f669ff9", + "translation_date": "2026-03-06T10:46:37+00:00", + "source_file": "2-js-basics/2-functions-methods/README.md", + "language_code": "en" + }, + "2-js-basics/2-functions-methods/assignment.md": { + "original_hash": "8328f58f4593b4671656ff8f4b2edbd9", + "translation_date": "2026-03-06T10:46:50+00:00", + "source_file": "2-js-basics/2-functions-methods/assignment.md", + "language_code": "en" + }, + "2-js-basics/3-making-decisions/README.md": { + "original_hash": "c688385d15dd3645e924ea0ffee8967f", + "translation_date": "2026-03-06T10:50:36+00:00", + "source_file": "2-js-basics/3-making-decisions/README.md", + "language_code": "en" + }, + "2-js-basics/3-making-decisions/assignment.md": { + "original_hash": "ffe366b2d1f037b99fbadbe1dc81083d", + "translation_date": "2026-03-06T10:50:56+00:00", + "source_file": "2-js-basics/3-making-decisions/assignment.md", + "language_code": "en" + }, + "2-js-basics/4-arrays-loops/README.md": { + "original_hash": "1710a50a519a6e4a1b40a5638783018d", + "translation_date": "2026-03-06T10:52:54+00:00", + "source_file": "2-js-basics/4-arrays-loops/README.md", + "language_code": "en" + }, + "2-js-basics/4-arrays-loops/assignment.md": { + "original_hash": "8abcada0534e0fb3a7556ea3c5a2a8a4", + "translation_date": "2026-03-06T10:53:08+00:00", + "source_file": "2-js-basics/4-arrays-loops/assignment.md", + "language_code": "en" + }, + "2-js-basics/README.md": { + "original_hash": "cc9e70a2f096c67389c8acff1521fc27", + "translation_date": "2025-08-28T11:39:19+00:00", + "source_file": "2-js-basics/README.md", + "language_code": "en" + }, + "3-terrarium/1-intro-to-html/README.md": { + "original_hash": "3fcfa99c4897e051b558b5eaf1e8cc74", + "translation_date": "2026-03-06T11:24:57+00:00", + "source_file": "3-terrarium/1-intro-to-html/README.md", + "language_code": "en" + }, + "3-terrarium/1-intro-to-html/assignment.md": { + "original_hash": "650e63282e1dfa032890fcf5c1c4119d", + "translation_date": "2026-03-06T11:25:17+00:00", + "source_file": "3-terrarium/1-intro-to-html/assignment.md", + "language_code": "en" + }, + "3-terrarium/2-intro-to-css/README.md": { + "original_hash": "e39f3a4e3bcccf94639e3af1248f8a4d", + "translation_date": "2026-03-06T11:28:35+00:00", + "source_file": "3-terrarium/2-intro-to-css/README.md", + "language_code": "en" + }, + "3-terrarium/2-intro-to-css/assignment.md": { + "original_hash": "bee6762d4092a13fc7c338814963f980", + "translation_date": "2026-03-06T11:28:50+00:00", + "source_file": "3-terrarium/2-intro-to-css/assignment.md", + "language_code": "en" + }, + "3-terrarium/3-intro-to-DOM-and-closures/README.md": { + "original_hash": "973e48ad87d67bf5bb819746c9f8e302", + "translation_date": "2026-03-06T11:27:00+00:00", + "source_file": "3-terrarium/3-intro-to-DOM-and-closures/README.md", + "language_code": "en" + }, + "3-terrarium/3-intro-to-DOM-and-closures/assignment.md": { + "original_hash": "947ca5ce7c94aee9c7de7034e762bc17", + "translation_date": "2026-03-06T11:27:21+00:00", + "source_file": "3-terrarium/3-intro-to-DOM-and-closures/assignment.md", + "language_code": "en" + }, + "3-terrarium/README.md": { + "original_hash": "bc5c5550f79d10add90ce419ee34abb3", + "translation_date": "2026-03-06T10:40:00+00:00", + "source_file": "3-terrarium/README.md", + "language_code": "en" + }, + "3-terrarium/solution/README.md": { + "original_hash": "6329fbe8bd936068debd78cca6f09c0a", + "translation_date": "2025-08-28T11:50:16+00:00", + "source_file": "3-terrarium/solution/README.md", + "language_code": "en" + }, + "4-typing-game/README.md": { + "original_hash": "efa2ab875b8bb5a7883816506da6b6d2", + "translation_date": "2026-03-06T10:39:54+00:00", + "source_file": "4-typing-game/README.md", + "language_code": "en" + }, + "4-typing-game/solution/README.md": { + "original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c", + "translation_date": "2025-08-28T11:58:40+00:00", + "source_file": "4-typing-game/solution/README.md", + "language_code": "en" + }, + "4-typing-game/typing-game/README.md": { + "original_hash": "da8bc72041a2bb3826a54654ee1a8844", + "translation_date": "2026-03-06T11:23:27+00:00", + "source_file": "4-typing-game/typing-game/README.md", + "language_code": "en" + }, + "4-typing-game/typing-game/assignment.md": { + "original_hash": "3eac59d70e2532a677a2ce6bf765485a", + "translation_date": "2026-03-06T11:23:39+00:00", + "source_file": "4-typing-game/typing-game/assignment.md", + "language_code": "en" + }, + "5-browser-extension/1-about-browsers/README.md": { + "original_hash": "00aa85715e1efd4930c17a23e3012e69", + "translation_date": "2026-03-06T11:11:23+00:00", + "source_file": "5-browser-extension/1-about-browsers/README.md", + "language_code": "en" + }, + "5-browser-extension/1-about-browsers/assignment.md": { + "original_hash": "b6897c02603d0045dd6d8256e8714baa", + "translation_date": "2026-03-06T11:11:39+00:00", + "source_file": "5-browser-extension/1-about-browsers/assignment.md", + "language_code": "en" + }, + "5-browser-extension/2-forms-browsers-local-storage/README.md": { + "original_hash": "2b6203a48c48d8234e0948353b47d84e", + "translation_date": "2026-03-06T11:07:39+00:00", + "source_file": "5-browser-extension/2-forms-browsers-local-storage/README.md", + "language_code": "en" + }, + "5-browser-extension/2-forms-browsers-local-storage/assignment.md": { + "original_hash": "25b8d28b8531352d4eb67291fd7824c4", + "translation_date": "2026-03-06T11:07:57+00:00", + "source_file": "5-browser-extension/2-forms-browsers-local-storage/assignment.md", + "language_code": "en" + }, + "5-browser-extension/3-background-tasks-and-performance/README.md": { + "original_hash": "b275fed2c6fc90d2b9b6661a3225faa2", + "translation_date": "2026-03-06T11:09:37+00:00", + "source_file": "5-browser-extension/3-background-tasks-and-performance/README.md", + "language_code": "en" + }, + "5-browser-extension/3-background-tasks-and-performance/assignment.md": { + "original_hash": "a203e560e58ccc6ba68bffc40c7c8676", + "translation_date": "2026-03-06T11:09:58+00:00", + "source_file": "5-browser-extension/3-background-tasks-and-performance/assignment.md", + "language_code": "en" + }, + "5-browser-extension/README.md": { + "original_hash": "b121a279a6ab39878491f3e572673515", + "translation_date": "2025-08-28T11:22:58+00:00", + "source_file": "5-browser-extension/README.md", + "language_code": "en" + }, + "5-browser-extension/solution/README.md": { + "original_hash": "fab4e6b4f0efcd587a9029d82991f597", + "translation_date": "2025-08-28T11:27:00+00:00", + "source_file": "5-browser-extension/solution/README.md", + "language_code": "en" + }, + "5-browser-extension/solution/translation/README.es.md": { + "original_hash": "cbaf73f94a9ab4c680a10ef871e92948", + "translation_date": "2025-08-28T11:28:22+00:00", + "source_file": "5-browser-extension/solution/translation/README.es.md", + "language_code": "en" + }, + "5-browser-extension/solution/translation/README.fr.md": { + "original_hash": "9361268ca430b2579375009e1eceb5e5", + "translation_date": "2025-08-28T11:29:07+00:00", + "source_file": "5-browser-extension/solution/translation/README.fr.md", + "language_code": "en" + }, + "5-browser-extension/solution/translation/README.hi.md": { + "original_hash": "dd58ae1b7707034f055718c1b68bc8de", + "translation_date": "2025-08-28T11:27:20+00:00", + "source_file": "5-browser-extension/solution/translation/README.hi.md", + "language_code": "en" + }, + "5-browser-extension/solution/translation/README.it.md": { + "original_hash": "9a6b22a2eff0f499b66236be973b24ad", + "translation_date": "2025-08-28T11:27:41+00:00", + "source_file": "5-browser-extension/solution/translation/README.it.md", + "language_code": "en" + }, + "5-browser-extension/solution/translation/README.ja.md": { + "original_hash": "3f5e6821e0febccfc5d05e7c944d9e3d", + "translation_date": "2025-08-28T11:28:01+00:00", + "source_file": "5-browser-extension/solution/translation/README.ja.md", + "language_code": "en" + }, + "5-browser-extension/solution/translation/README.ms.md": { + "original_hash": "21b364c158c8e4f698de65eeac16c9fe", + "translation_date": "2025-08-28T11:28:46+00:00", + "source_file": "5-browser-extension/solution/translation/README.ms.md", + "language_code": "en" + }, + "5-browser-extension/start/README.md": { + "original_hash": "26fd39046d264ba185dcb086d3a8cf3e", + "translation_date": "2025-08-28T11:26:41+00:00", + "source_file": "5-browser-extension/start/README.md", + "language_code": "en" + }, + "6-space-game/1-introduction/README.md": { + "original_hash": "a6332a7bb4d0be3bfd24199c83993777", + "translation_date": "2026-03-06T11:03:38+00:00", + "source_file": "6-space-game/1-introduction/README.md", + "language_code": "en" + }, + "6-space-game/1-introduction/assignment.md": { + "original_hash": "c8fc39a014d08247c082878122e2ba73", + "translation_date": "2026-03-06T11:03:54+00:00", + "source_file": "6-space-game/1-introduction/assignment.md", + "language_code": "en" + }, + "6-space-game/2-drawing-to-canvas/README.md": { + "original_hash": "7994743c5b21fdcceb36307916ef249a", + "translation_date": "2026-03-06T10:58:48+00:00", + "source_file": "6-space-game/2-drawing-to-canvas/README.md", + "language_code": "en" + }, + "6-space-game/2-drawing-to-canvas/assignment.md": { + "original_hash": "87cd43afe5b69dbbffb5c4b209ea6791", + "translation_date": "2026-03-06T10:58:59+00:00", + "source_file": "6-space-game/2-drawing-to-canvas/assignment.md", + "language_code": "en" + }, + "6-space-game/3-moving-elements-around/README.md": { + "original_hash": "8c55a2bd4bc0ebe4c88198fd563a9e09", + "translation_date": "2026-03-06T11:05:43+00:00", + "source_file": "6-space-game/3-moving-elements-around/README.md", + "language_code": "en" + }, + "6-space-game/3-moving-elements-around/assignment.md": { + "original_hash": "c162b3b3a1cafc1483c8015e9b266f0d", + "translation_date": "2026-03-06T11:05:53+00:00", + "source_file": "6-space-game/3-moving-elements-around/assignment.md", + "language_code": "en" + }, + "6-space-game/4-collision-detection/README.md": { + "original_hash": "039b4d8ce65f5edd82cf48d9c3e6728c", + "translation_date": "2026-03-06T10:57:05+00:00", + "source_file": "6-space-game/4-collision-detection/README.md", + "language_code": "en" + }, + "6-space-game/4-collision-detection/assignment.md": { + "original_hash": "124efddbb65166cddb38075ad6dae324", + "translation_date": "2026-03-06T10:57:16+00:00", + "source_file": "6-space-game/4-collision-detection/assignment.md", + "language_code": "en" + }, + "6-space-game/4-collision-detection/solution/README.md": { + "original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c", + "translation_date": "2025-08-28T11:35:46+00:00", + "source_file": "6-space-game/4-collision-detection/solution/README.md", + "language_code": "en" + }, + "6-space-game/4-collision-detection/your-work/README.md": { + "original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c", + "translation_date": "2025-08-28T11:35:55+00:00", + "source_file": "6-space-game/4-collision-detection/your-work/README.md", + "language_code": "en" + }, + "6-space-game/5-keeping-score/README.md": { + "original_hash": "2ed9145a16cf576faa2a973dff84d099", + "translation_date": "2026-03-06T11:01:59+00:00", + "source_file": "6-space-game/5-keeping-score/README.md", + "language_code": "en" + }, + "6-space-game/5-keeping-score/assignment.md": { + "original_hash": "81f292dbda01685b91735e0398dc0504", + "translation_date": "2025-08-28T11:34:09+00:00", + "source_file": "6-space-game/5-keeping-score/assignment.md", + "language_code": "en" + }, + "6-space-game/5-keeping-score/solution/README.md": { + "original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c", + "translation_date": "2025-08-28T11:34:21+00:00", + "source_file": "6-space-game/5-keeping-score/solution/README.md", + "language_code": "en" + }, + "6-space-game/5-keeping-score/your-work/README.md": { + "original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c", + "translation_date": "2025-08-28T11:34:30+00:00", + "source_file": "6-space-game/5-keeping-score/your-work/README.md", + "language_code": "en" + }, + "6-space-game/6-end-condition/README.md": { + "original_hash": "a4b78043f4d64bf3ee24e0689b8b391d", + "translation_date": "2026-03-06T11:00:22+00:00", + "source_file": "6-space-game/6-end-condition/README.md", + "language_code": "en" + }, + "6-space-game/6-end-condition/assignment.md": { + "original_hash": "232d592791465c1678cab3a2bb6cd3e8", + "translation_date": "2026-03-06T11:00:50+00:00", + "source_file": "6-space-game/6-end-condition/assignment.md", + "language_code": "en" + }, + "6-space-game/6-end-condition/solution/README.md": { + "original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c", + "translation_date": "2025-08-28T11:38:05+00:00", + "source_file": "6-space-game/6-end-condition/solution/README.md", + "language_code": "en" + }, + "6-space-game/6-end-condition/your-work/README.md": { + "original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c", + "translation_date": "2025-08-28T11:38:14+00:00", + "source_file": "6-space-game/6-end-condition/your-work/README.md", + "language_code": "en" + }, + "6-space-game/README.md": { + "original_hash": "c40a698395ee5102715f7880bba3f2e7", + "translation_date": "2025-08-28T11:31:47+00:00", + "source_file": "6-space-game/README.md", + "language_code": "en" + }, + "6-space-game/solution/README.md": { + "original_hash": "068cbb9b3c10a96d503f6cdd6c9ace8c", + "translation_date": "2025-08-28T11:34:38+00:00", + "source_file": "6-space-game/solution/README.md", + "language_code": "en" + }, + "7-bank-project/1-template-route/README.md": { + "original_hash": "351678bece18f07d9daa987a881fb062", + "translation_date": "2026-03-06T11:16:13+00:00", + "source_file": "7-bank-project/1-template-route/README.md", + "language_code": "en" + }, + "7-bank-project/1-template-route/assignment.md": { + "original_hash": "df0dcecddcd28ea8cbf6ede0ad57d673", + "translation_date": "2026-03-06T11:16:24+00:00", + "source_file": "7-bank-project/1-template-route/assignment.md", + "language_code": "en" + }, + "7-bank-project/2-forms/README.md": { + "original_hash": "7cbdbd132d39a2bb493e85bc2a9387cc", + "translation_date": "2026-03-06T11:13:46+00:00", + "source_file": "7-bank-project/2-forms/README.md", + "language_code": "en" + }, + "7-bank-project/2-forms/assignment.md": { + "original_hash": "efb01fcafd2ef40c593a6e662fc938a8", + "translation_date": "2026-03-06T11:14:07+00:00", + "source_file": "7-bank-project/2-forms/assignment.md", + "language_code": "en" + }, + "7-bank-project/3-data/README.md": { + "original_hash": "86ee5069f27ea3151389d8687c95fac9", + "translation_date": "2026-03-06T11:18:59+00:00", + "source_file": "7-bank-project/3-data/README.md", + "language_code": "en" + }, + "7-bank-project/3-data/assignment.md": { + "original_hash": "d0a02cb117e91a5b5f24178080068a3d", + "translation_date": "2026-03-06T11:19:20+00:00", + "source_file": "7-bank-project/3-data/assignment.md", + "language_code": "en" + }, + "7-bank-project/4-state-management/README.md": { + "original_hash": "b807b09df716dc48a2b750835bf8e933", + "translation_date": "2026-03-06T11:21:23+00:00", + "source_file": "7-bank-project/4-state-management/README.md", + "language_code": "en" + }, + "7-bank-project/4-state-management/assignment.md": { + "original_hash": "50a7783473b39a2e0f133e271a102231", + "translation_date": "2026-03-06T11:21:50+00:00", + "source_file": "7-bank-project/4-state-management/assignment.md", + "language_code": "en" + }, + "7-bank-project/README.md": { + "original_hash": "830359535306594b448db6575ce5cdee", + "translation_date": "2025-08-28T11:13:52+00:00", + "source_file": "7-bank-project/README.md", + "language_code": "en" + }, + "7-bank-project/api/README.md": { + "original_hash": "9884f8c8a61cf56214450f8b16a094ce", + "translation_date": "2025-08-28T11:16:11+00:00", + "source_file": "7-bank-project/api/README.md", + "language_code": "en" + }, + "7-bank-project/solution/README.md": { + "original_hash": "461aa4fc74c6b1789c3a13b5d82c0cd9", + "translation_date": "2025-08-28T11:16:34+00:00", + "source_file": "7-bank-project/solution/README.md", + "language_code": "en" + }, + "8-code-editor/1-using-a-code-editor/README.md": { + "original_hash": "a9a3bcc037a447e2d8994d99e871cd9f", + "translation_date": "2026-03-06T10:54:48+00:00", + "source_file": "8-code-editor/1-using-a-code-editor/README.md", + "language_code": "en" + }, + "8-code-editor/1-using-a-code-editor/assignment.md": { + "original_hash": "effe56ba51c38d7bdfad1ea38288666b", + "translation_date": "2026-03-06T10:55:36+00:00", + "source_file": "8-code-editor/1-using-a-code-editor/assignment.md", + "language_code": "en" + }, + "9-chat-project/README.md": { + "original_hash": "2066c17078e9d18b5e309f31d8e8bc24", + "translation_date": "2026-03-06T10:44:47+00:00", + "source_file": "9-chat-project/README.md", + "language_code": "en" + }, + "9-chat-project/solution/README.md": { + "original_hash": "cb549dcad8eea3221cb89793aeaa3bb3", + "translation_date": "2025-09-01T15:17:50+00:00", + "source_file": "9-chat-project/solution/README.md", + "language_code": "en" + }, + "9-chat-project/solution/backend/README.md": { + "original_hash": "bcd2c2bbaae71151b1ed1b9170aa78af", + "translation_date": "2025-09-01T15:41:51+00:00", + "source_file": "9-chat-project/solution/backend/README.md", + "language_code": "en" + }, + "9-chat-project/solution/backend/python/README.md": { + "original_hash": "0aaa930f076f2d83cc872ad157f8ffd3", + "translation_date": "2026-03-06T11:38:06+00:00", + "source_file": "9-chat-project/solution/backend/python/README.md", + "language_code": "en" + }, + "9-chat-project/solution/frontend/README.md": { + "original_hash": "7746a470be8fc7f736eb1b43ebb710ee", + "translation_date": "2025-09-01T15:50:34+00:00", + "source_file": "9-chat-project/solution/frontend/README.md", + "language_code": "en" + }, + "AGENTS.md": { + "original_hash": "a362efd06d64d4134a0cfe8515a86d34", + "translation_date": "2025-10-03T11:11:50+00:00", + "source_file": "AGENTS.md", + "language_code": "en" + }, + "CODE_OF_CONDUCT.md": { + "original_hash": "b0a9b4cccd918195f58224d5793da1a6", + "translation_date": "2025-08-28T11:13:41+00:00", + "source_file": "CODE_OF_CONDUCT.md", + "language_code": "en" + }, + "CONTRIBUTING.md": { + "original_hash": "777400e9f0336c7ee2f9a1200a88478f", + "translation_date": "2025-08-28T11:12:28+00:00", + "source_file": "CONTRIBUTING.md", + "language_code": "en" + }, + "Git-Basics/README.md": { + "original_hash": "5cf5e1ed51455fefed4895fcc4d6ba2a", + "translation_date": "2025-10-03T15:43:56+00:00", + "source_file": "Git-Basics/README.md", + "language_code": "en" + }, + "README.md": { + "original_hash": "a2c9eed480687319517c08a6319e5536", + "translation_date": "2026-03-06T10:36:58+00:00", + "source_file": "README.md", + "language_code": "en" + }, + "Roadmap.md": { + "original_hash": "28bf6185fd7f27b62ddc210514366192", + "translation_date": "2026-03-06T11:54:38+00:00", + "source_file": "Roadmap.md", + "language_code": "en" + }, + "SECURITY.md": { + "original_hash": "4ecc3bf2e27983d4c780be6f26ee6228", + "translation_date": "2025-08-28T11:12:43+00:00", + "source_file": "SECURITY.md", + "language_code": "en" + }, + "SUPPORT.md": { + "original_hash": "c9d207ff77b4bb46e46dc2b607a8ec1a", + "translation_date": "2025-08-28T11:12:03+00:00", + "source_file": "SUPPORT.md", + "language_code": "en" + }, + "_404.md": { + "original_hash": "ea9f0804bd62f46d9808e953ec7fc459", + "translation_date": "2025-08-28T11:12:17+00:00", + "source_file": "_404.md", + "language_code": "en" + }, + "docs/_navbar.md": { + "original_hash": "3bd2f51ecf4ac9b39277cba748943793", + "translation_date": "2025-08-28T11:47:45+00:00", + "source_file": "docs/_navbar.md", + "language_code": "en" + }, + "docs/_sidebar.md": { + "original_hash": "655c91b5979de46f1d70d97f0c5f1d14", + "translation_date": "2025-08-28T11:47:26+00:00", + "source_file": "docs/_sidebar.md", + "language_code": "en" + }, + "for-teachers.md": { + "original_hash": "71009af209f81cc01a1f2d324200375f", + "translation_date": "2025-10-03T08:19:51+00:00", + "source_file": "for-teachers.md", + "language_code": "en" + }, + "lesson-template/README.md": { + "original_hash": "0494be70ad7fadd13a8c3d549c23e355", + "translation_date": "2025-08-28T11:48:01+00:00", + "source_file": "lesson-template/README.md", + "language_code": "en" + }, + "lesson-template/assignment.md": { + "original_hash": "b5f62ec256c7e43e771f0d3b4e1a9130", + "translation_date": "2025-08-28T11:48:16+00:00", + "source_file": "lesson-template/assignment.md", + "language_code": "en" + }, + "memory-game/README.md": { + "original_hash": "ff47271e53637b2ba6ba72ad2b70f6d7", + "translation_date": "2025-10-03T11:52:55+00:00", + "source_file": "memory-game/README.md", + "language_code": "en" + }, + "quiz-app/README.md": { + "original_hash": "5301875c55bb305e6046bed3a4fd06d2", + "translation_date": "2025-08-28T11:53:58+00:00", + "source_file": "quiz-app/README.md", + "language_code": "en" + } +} \ No newline at end of file diff --git a/translations/en/1-getting-started-lessons/1-intro-to-programming-languages/README.md b/translations/en/1-getting-started-lessons/1-intro-to-programming-languages/README.md index a46afa139..c6c31b1da 100644 --- a/translations/en/1-getting-started-lessons/1-intro-to-programming-languages/README.md +++ b/translations/en/1-getting-started-lessons/1-intro-to-programming-languages/README.md @@ -1,64 +1,238 @@ - -# Introduction to Programming Languages and Tools of the Trade +# Introduction to Programming Languages and Modern Developer Tools + +Hey there, future developer! 👋 Can I tell you something that still gives me chills every single day? You're about to discover that programming isn't just about computers – it's about having actual superpowers to bring your wildest ideas to life! + +You know that moment when you're using your favorite app and everything just clicks perfectly? When you tap a button and something absolutely magical happens that makes you go "wow, how did they DO that?" Well, someone just like you – probably sitting in their favorite coffee shop at 2 AM with their third espresso – wrote the code that created that magic. And here's what's going to blow your mind: by the end of this lesson, you'll not only understand how they did it, but you'll be itching to try it yourself! + +Look, I totally get it if programming feels intimidating right now. When I first started, I honestly thought you needed to be some kind of math genius or have been coding since you were five years old. But here's what completely changed my perspective: programming is exactly like learning to have conversations in a new language. You start with "hello" and "thank you," then work up to ordering coffee, and before you know it, you're having deep philosophical discussions! Except in this case, you're having conversations with computers, and honestly? They're the most patient conversation partners you'll ever have – they never judge your mistakes and they're always excited to try again! -This lesson introduces the fundamentals of programming languages. The topics discussed here are relevant to most modern programming languages today. In the 'Tools of the Trade' section, you'll explore software that can assist you as a developer. +Today, we're going to explore the incredible tools that make modern web development not just possible, but seriously addictive. I'm talking about the exact same editors, browsers, and workflows that developers at Netflix, Spotify, and your favorite indie app studio use every single day. And here's the part that's going to make you do a happy dance: most of these professional-grade, industry-standard tools are completely free! -![Intro Programming](../../../../translated_images/en/webdev101-programming.d6e3f98e61ac4bff0b27dcbf1c3f16c8ed46984866f2d29988929678b0058fde.png) +![Intro Programming](../../../../translated_images/en/webdev101-programming.d6e3f98e61ac4bff.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) -## Pre-Lecture Quiz -[Pre-lecture quiz](https://forms.office.com/r/dru4TE0U9n?origin=lprLink) +```mermaid +journey + title Your Programming Journey Today + section Discover + What is Programming: 5: You + Programming Languages: 4: You + Tools Overview: 5: You + section Explore + Code Editors: 4: You + Browsers & DevTools: 5: You + Command Line: 3: You + section Practice + Language Detective: 4: You + Tool Exploration: 5: You + Community Connection: 5: You +``` +## Let's See What You Already Know! + +Before we jump into the fun stuff, I'm curious – what do you already know about this programming world? And listen, if you're looking at these questions thinking "I literally have zero clue about any of this," that's not just okay, it's perfect! That means you're in exactly the right place. Think of this quiz like stretching before a workout – we're just warming up those brain muscles! + +[Take the pre-lesson quiz](https://ff-quizzes.netlify.app/web/) + + +## The Adventure We're About to Go On Together + +Okay, I am genuinely bouncing with excitement about what we're going to explore today! Seriously, I wish I could see your face when some of these concepts click. Here's the incredible journey we're taking together: + +- **What programming actually is (and why it's the coolest thing ever!)** – We're going to discover how code is literally the invisible magic powering everything around you, from that alarm that somehow knows it's Monday morning to the algorithm that perfectly curates your Netflix recommendations +- **Programming languages and their amazing personalities** – Imagine walking into a party where each person has completely different superpowers and ways of solving problems. That's what the programming language world is like, and you're going to love meeting them! +- **The fundamental building blocks that make digital magic happen** – Think of these as the ultimate creative LEGO set. Once you understand how these pieces fit together, you'll realize you can literally build anything your imagination dreams up +- **Professional tools that'll make you feel like you just got handed a wizard's wand** – I'm not being dramatic here – these tools will genuinely make you feel like you have superpowers, and the best part? They're the same ones the pros use! + +> 💡 **Here's the thing**: Don't even think about trying to memorize everything today! Right now, I just want you to feel that spark of excitement about what's possible. The details will stick naturally as we practice together – that's how real learning happens! + +> You can take this lesson on [Microsoft Learn](https://learn.microsoft.com/en-us/learn/modules/web-development-101/introduction-programming/?WT.mc_id=academic-77807-sagibbon)! + +## So What Exactly *Is* Programming? + +Alright, let's tackle the million-dollar question: what is programming, really? + +I'll give you a story that completely changed how I think about this. Last week, I was trying to explain to my mom how to use our new smart TV remote. I caught myself saying things like "Press the red button, but not the big red button, the small red button on the left... no, your other left... okay, now hold it for two seconds, not one, not three..." Sound familiar? 😅 + +That's programming! It's the art of giving incredibly detailed, step-by-step instructions to something that's very powerful but needs everything spelled out perfectly. Except instead of explaining to your mom (who can ask "which red button?!"), you're explaining to a computer (which just does exactly what you say, even if what you said isn't quite what you meant). + +Here's what blew my mind when I first learned this: computers are actually pretty simple at their core. They literally only understand two things – 1 and 0, which is basically just "yes" and "no" or "on" and "off." That's it! But here's where it gets magical – we don't have to speak in 1s and 0s like we're in The Matrix. That's where **programming languages** come to the rescue. They're like having the world's best translator who takes your perfectly normal human thoughts and converts them into computer language. + +And here's what still gives me actual chills every morning when I wake up: literally *everything* digital in your life started with someone just like you, probably sitting in their pajamas with a cup of coffee, typing code on their laptop. That Instagram filter that makes you look flawless? Someone coded that. The recommendation that led you to your new favorite song? A developer built that algorithm. The app that helps you split dinner bills with friends? Yep, someone thought "this is annoying, I bet I could fix this" and then... they did! + +When you learn to program, you're not just picking up a new skill – you're becoming part of this incredible community of problem-solvers who spend their days thinking, "What if I could build something that makes someone's day just a little bit better?" Honestly, is there anything cooler than that? + +✅ **Fun Fact Hunt**: Here's something super cool to look up when you have a spare moment – who do you think was the world's first computer programmer? I'll give you a hint: it might not be who you're expecting! The story behind this person is absolutely fascinating and shows that programming has always been about creative problem-solving and thinking outside the box. -## Introduction +### 🧠 **Check-in Time: How Are You Feeling?** -In this lesson, we will cover: +**Take a moment to reflect:** +- Does the idea of "giving instructions to computers" make sense to you now? +- Can you think of a daily task you'd like to automate with programming? +- What questions are bubbling up in your mind about this whole programming thing? -- What programming is -- Types of programming languages -- Basic components of a program -- Useful software and tools for professional developers +> **Remember**: It's totally normal if some concepts feel fuzzy right now. Learning programming is like learning a new language – it takes time for your brain to build those neural pathways. You're doing great! -> You can take this lesson on [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/introduction-programming/?WT.mc_id=academic-77807-sagibbon)! +## Programming Languages Are Like Different Flavors of Magic -## What is Programming? +Okay, this is going to sound weird, but stick with me – programming languages are a lot like different types of music. Think about it: you've got jazz, which is smooth and improvisational, rock that's powerful and straightforward, classical that's elegant and structured, and hip-hop that's creative and expressive. Each style has its own vibe, its own community of passionate fans, and each one is perfect for different moods and occasions. -Programming (also called coding) is the process of writing instructions for a device, such as a computer or mobile device. These instructions are written using a programming language, which the device interprets. These sets of instructions may be referred to by various names, such as *program*, *computer program*, *application (app)*, or *executable*. +Programming languages work exactly the same way! You wouldn't use the same language to build a fun mobile game that you'd use to crunch massive amounts of climate data, just like you wouldn't play death metal at a yoga class (well, most yoga classes anyway! 😄). -A *program* can be anything created with code—websites, games, and phone apps are all programs. While it's possible to create a program without writing code, the underlying logic is interpreted by the device, and that logic is most likely written in code. A program that is *running* or *executing* code is carrying out instructions. The device you're using to read this lesson is running a program to display it on your screen. +But here's what absolutely blows my mind every time I think about it: these languages are like having the most patient, brilliant interpreter in the world sitting right next to you. You can express your ideas in a way that feels natural to your human brain, and they handle all the incredibly complex work of translating that into the 1s and 0s that computers actually speak. It's like having a friend who's perfectly fluent in both "human creativity" and "computer logic" – and they never get tired, never need coffee breaks, and never judge you for asking the same question twice! -✅ Research task: Who is considered the world's first computer programmer? +### Popular Programming Languages and Their Uses -## Programming Languages +```mermaid +mindmap + root((Programming Languages)) + Web Development + JavaScript + Frontend Magic + Interactive Websites + TypeScript + JavaScript + Types + Enterprise Apps + Data & AI + Python + Data Science + Machine Learning + Automation + R + Statistics + Research + Mobile Apps + Java + Android + Enterprise + Swift + iOS + Apple Ecosystem + Kotlin + Modern Android + Cross-platform + Systems & Performance + C++ + Games + Performance Critical + Rust + Memory Safety + System Programming + Go + Cloud Services + Scalable Backend +``` +| Language | Best For | Why It's Popular | +|----------|----------|------------------| +| **JavaScript** | Web development, user interfaces | Runs in browsers and powers interactive websites | +| **Python** | Data science, automation, AI | Easy to read and learn, powerful libraries | +| **Java** | Enterprise applications, Android apps | Platform-independent, robust for large systems | +| **C#** | Windows applications, game development | Strong Microsoft ecosystem support | +| **Go** | Cloud services, backend systems | Fast, simple, designed for modern computing | + +### High-Level vs. Low-Level Languages + +Okay, this was honestly the concept that broke my brain when I first started learning, so I'm going to share the analogy that finally made it click for me – and I really hope it helps you too! + +Imagine you're visiting a country where you don't speak the language, and you desperately need to find the nearest bathroom (we've all been there, right? 😅): + +- **Low-level programming** is like learning the local dialect so well that you can chat with the grandmother selling fruit on the corner using cultural references, local slang, and inside jokes that only someone who grew up there would understand. Super impressive and incredibly efficient... if you happen to be fluent! But pretty overwhelming when you're just trying to find a bathroom. + +- **High-level programming** is like having that amazing local friend who just gets you. You can say "I really need to find a restroom" in plain English, and they handle all the cultural translation and give you directions in a way that makes perfect sense to your non-local brain. + +In programming terms: +- **Low-level languages** (like Assembly or C) let you have incredibly detailed conversations with the computer's actual hardware, but you need to think like a machine, which is... well, let's just say it's a pretty big mental shift! +- **High-level languages** (like JavaScript, Python, or C#) let you think like a human while they handle all the machine-speak behind the scenes. Plus, they have these incredibly welcoming communities full of people who remember what it was like to be new and genuinely want to help! + +Guess which ones I'm going to suggest you start with? 😉 High-level languages are like having training wheels that you never actually want to take off because they make the whole experience so much more enjoyable! + +```mermaid +flowchart TB + A["👤 Human Thought:
'I want to calculate Fibonacci numbers'"] --> B{Choose Language Level} + + B -->|High-Level| C["🌟 JavaScript/Python
Easy to read and write"] + B -->|Low-Level| D["⚙️ Assembly/C
Direct hardware control"] + + C --> E["📝 Write: fibonacci(10)"] + D --> F["📝 Write: mov r0,#00
sub r0,r0,#01"] + + E --> G["🤖 Computer Understanding:
Translator handles complexity"] + F --> G + + G --> H["💻 Same Result:
0, 1, 1, 2, 3, 5, 8, 13..."] + + style C fill:#e1f5fe + style D fill:#fff3e0 + style H fill:#e8f5e8 +``` +### Let Me Show You Why High-Level Languages Are So Much Friendlier + +Alright, I'm about to show you something that perfectly demonstrates why I fell in love with high-level languages, but first – I need you to promise me something. When you see that first code example, don't panic! It's supposed to look intimidating. That's exactly the point I'm making! + +We're going to look at the exact same task written in two completely different styles. Both create what's called the Fibonacci sequence – it's this beautiful mathematical pattern where each number is the sum of the two before it: 0, 1, 1, 2, 3, 5, 8, 13... (Fun fact: you'll find this pattern literally everywhere in nature – sunflower seed spirals, pinecone patterns, even the way galaxies form!) + +Ready to see the difference? Let's go! -Programming languages allow developers to write instructions for a device. Devices only understand binary (1s and 0s), which is not an efficient way for *most* developers to communicate. Programming languages act as a bridge between humans and computers. +**High-level language (JavaScript) – Human-friendly:** -Programming languages come in various formats and serve different purposes. For instance, JavaScript is primarily used for web applications, while Bash is mainly used for operating systems. +```javascript +// Step 1: Basic Fibonacci setup +const fibonacciCount = 10; +let current = 0; +let next = 1; -*Low-level languages* typically require fewer steps for a device to interpret instructions compared to *high-level languages*. However, high-level languages are popular due to their readability and support. JavaScript is considered a high-level language. +console.log('Fibonacci sequence:'); +``` -The following code demonstrates the difference between a high-level language (JavaScript) and a low-level language (ARM assembly code). +**Here's what this code does:** +- **Declare** a constant to specify how many Fibonacci numbers we want to generate +- **Initialize** two variables to track the current and next numbers in the sequence +- **Set up** the starting values (0 and 1) that define the Fibonacci pattern +- **Display** a header message to identify our output ```javascript -let number = 10 -let n1 = 0, n2 = 1, nextTerm; - -for (let i = 1; i <= number; i++) { - console.log(n1); - nextTerm = n1 + n2; - n1 = n2; - n2 = nextTerm; +// Step 2: Generate the sequence with a loop +for (let i = 0; i < fibonacciCount; i++) { + console.log(`Position ${i + 1}: ${current}`); + + // Calculate next number in sequence + const sum = current + next; + current = next; + next = sum; } ``` -```c +**Breaking down what happens here:** +- **Loop** through each position in our sequence using a `for` loop +- **Display** each number with its position using template literal formatting +- **Calculate** the next Fibonacci number by adding current and next values +- **Update** our tracking variables to move to the next iteration + +```javascript +// Step 3: Modern functional approach +const generateFibonacci = (count) => { + const sequence = [0, 1]; + + for (let i = 2; i < count; i++) { + sequence[i] = sequence[i - 1] + sequence[i - 2]; + } + + return sequence; +}; + +// Usage example +const fibSequence = generateFibonacci(10); +console.log(fibSequence); +``` + +**In the above, we've:** +- **Created** a reusable function using modern arrow function syntax +- **Built** an array to store the complete sequence rather than displaying one by one +- **Used** array indexing to calculate each new number from previous values +- **Returned** the complete sequence for flexible use in other parts of our program + +**Low-level language (ARM Assembly) – Computer-friendly:** + +```assembly area ascen,code,readonly entry code32 @@ -83,137 +257,600 @@ back add r0,r1 end ``` -Believe it or not, *both are doing the same thing*: printing a Fibonacci sequence up to 10. +Notice how the JavaScript version reads almost like English instructions, while the Assembly version uses cryptic commands that directly control the computer's processor. Both accomplish the exact same task, but the high-level language is much easier for humans to understand, write, and maintain. + +**Key differences you'll notice:** +- **Readability**: JavaScript uses descriptive names like `fibonacciCount` while Assembly uses cryptic labels like `r0`, `r1` +- **Comments**: High-level languages encourage explanatory comments that make code self-documenting +- **Structure**: JavaScript's logical flow matches how humans think about problems step-by-step +- **Maintenance**: Updating the JavaScript version for different requirements is straightforward and clear + +✅ **About the Fibonacci sequence**: This absolutely gorgeous number pattern (where each number equals the sum of the two before it: 0, 1, 1, 2, 3, 5, 8...) shows up literally *everywhere* in nature! You'll find it in sunflower spirals, pinecone patterns, the way nautilus shells curve, and even in how tree branches grow. It's pretty mind-blowing how math and code can help us understand and recreate the patterns that nature uses to create beauty! + + +## The Building Blocks That Make the Magic Happen + +Alright, now that you've seen what programming languages look like in action, let's break down the fundamental pieces that make up literally every program ever written. Think of these as the essential ingredients in your favorite recipe – once you understand what each one does, you'll be able to read and write code in pretty much any language! + +This is kind of like learning the grammar of programming. Remember back in school when you learned about nouns, verbs, and how to put sentences together? Programming has its own version of grammar, and honestly, it's way more logical and forgiving than English grammar ever was! 😄 + +### Statements: The Step-by-Step Instructions + +Let's start with **statements** – these are like individual sentences in a conversation with your computer. Each statement tells the computer to do one specific thing, kind of like giving directions: "Turn left here," "Stop at the red light," "Park in that spot." + +What I love about statements is how readable they usually are. Check this out: + +```javascript +// Basic statements that perform single actions +const userName = "Alex"; +console.log("Hello, world!"); +const sum = 5 + 3; +``` + +**Here's what this code does:** +- **Declare** a constant variable to store a user's name +- **Display** a greeting message to the console output +- **Calculate** and store the result of a mathematical operation + +```javascript +// Statements that interact with web pages +document.title = "My Awesome Website"; +document.body.style.backgroundColor = "lightblue"; +``` + +**Step by step, here's what's happening:** +- **Modify** the webpage's title that appears in the browser tab +- **Change** the background color of the entire page body + +### Variables: Your Program's Memory System + +Okay, **variables** are honestly one of my absolute favorite concepts to teach because they're so much like things you already use every single day! + +Think about your phone's contact list for a second. You don't memorize everyone's phone number – instead, you save "Mom," "Best Friend," or "Pizza Place That Delivers Until 2 AM" and let your phone remember the actual numbers. Variables work exactly the same way! They're like labeled containers where your program can store information and retrieve it later using a name that actually makes sense. + +Here's what's really cool: variables can change as your program runs (hence the name "variable" – see what they did there?). Just like you might update that pizza place contact when you discover somewhere even better, variables can be updated as your program learns new information or as situations change! + +Let me show you how beautifully simple this can be: + +```javascript +// Step 1: Creating basic variables +const siteName = "Weather Dashboard"; +let currentWeather = "sunny"; +let temperature = 75; +let isRaining = false; +``` + +**Understanding these concepts:** +- **Store** unchanging values in `const` variables (like site name) +- **Use** `let` for values that can change throughout your program +- **Assign** different data types: strings (text), numbers, and booleans (true/false) +- **Choose** descriptive names that explain what each variable contains + +```javascript +// Step 2: Working with objects to group related data +const weatherData = { + location: "San Francisco", + humidity: 65, + windSpeed: 12 +}; +``` + +**In the above, we've:** +- **Created** an object to group related weather information together +- **Organized** multiple pieces of data under one variable name +- **Used** key-value pairs to label each piece of information clearly + +```javascript +// Step 3: Using and updating variables +console.log(`${siteName}: Today is ${currentWeather} and ${temperature}°F`); +console.log(`Wind speed: ${weatherData.windSpeed} mph`); + +// Updating changeable variables +currentWeather = "cloudy"; +temperature = 68; +``` + +**Let's understand each part:** +- **Display** information using template literals with `${}` syntax +- **Access** object properties using dot notation (`weatherData.windSpeed`) +- **Update** variables declared with `let` to reflect changing conditions +- **Combine** multiple variables to create meaningful messages + +```javascript +// Step 4: Modern destructuring for cleaner code +const { location, humidity } = weatherData; +console.log(`${location} humidity: ${humidity}%`); +``` + +**What you need to know:** +- **Extract** specific properties from objects using destructuring assignment +- **Create** new variables automatically with the same names as object keys +- **Simplify** code by avoiding repetitive dot notation + +### Control Flow: Teaching Your Program to Think -✅ A Fibonacci sequence is [defined](https://en.wikipedia.org/wiki/Fibonacci_number) as a series of numbers where each number is the sum of the two preceding ones, starting from 0 and 1. The first 10 numbers in the Fibonacci sequence are 0, 1, 1, 2, 3, 5, 8, 13, 21, and 34. +Okay, this is where programming gets absolutely mind-blowing! **Control flow** is basically teaching your program how to make smart decisions, exactly like you do every single day without even thinking about it. -## Elements of a Program +Picture this: this morning you probably went through something like "If it's raining, I'll grab an umbrella. If it's cold, I'll wear a jacket. If I'm running late, I'll skip breakfast and grab coffee on the way." Your brain naturally follows this if-then logic dozens of times every day! -A single instruction in a program is called a *statement*. Statements usually have a character or line spacing that marks where the instruction ends, or *terminates*. The way a program terminates varies by language. +This is what makes programs feel intelligent and alive instead of just following some boring, predictable script. They can actually look at a situation, evaluate what's happening, and respond appropriately. It's like giving your program a brain that can adapt and make choices! -Statements in a program may depend on data provided by a user or other sources to execute instructions. Data can influence how a program behaves, so programming languages include ways to temporarily store data for later use. These are called *variables*. Variables are statements that instruct a device to save data in its memory. Variables in programs are similar to variables in algebra, where they have a unique name and their value can change over time. +Want to see how beautifully this works? Let me show you: -Some statements may not be executed by a device. This can happen intentionally, as designed by the developer, or accidentally due to unexpected errors. This type of control over an application makes it more robust and maintainable. Typically, these changes in control occur when certain conditions are met. A common statement used in modern programming to control program flow is the `if..else` statement. +```javascript +// Step 1: Basic conditional logic +const userAge = 17; + +if (userAge >= 18) { + console.log("You can vote!"); +} else { + const yearsToWait = 18 - userAge; + console.log(`You'll be able to vote in ${yearsToWait} year(s).`); +} +``` -✅ You'll learn more about this type of statement in future lessons. +**Here's what this code does:** +- **Check** if the user's age meets the voting requirement +- **Execute** different code blocks based on the condition result +- **Calculate** and display how long until voting eligibility if under 18 +- **Provide** specific, helpful feedback for each scenario + +```javascript +// Step 2: Multiple conditions with logical operators +const userAge = 17; +const hasPermission = true; + +if (userAge >= 18 && hasPermission) { + console.log("Access granted: You can enter the venue."); +} else if (userAge >= 16) { + console.log("You need parent permission to enter."); +} else { + console.log("Sorry, you must be at least 16 years old."); +} +``` + +**Breaking down what happens here:** +- **Combine** multiple conditions using the `&&` (and) operator +- **Create** a hierarchy of conditions using `else if` for multiple scenarios +- **Handle** all possible cases with a final `else` statement +- **Provide** clear, actionable feedback for each different situation + +```javascript +// Step 3: Concise conditional with ternary operator +const votingStatus = userAge >= 18 ? "Can vote" : "Cannot vote yet"; +console.log(`Status: ${votingStatus}`); +``` + +**What you need to remember:** +- **Use** the ternary operator (`? :`) for simple two-option conditions +- **Write** condition first, followed by `?`, then true result, then `:`, then false result +- **Apply** this pattern when you need to assign values based on conditions + +```javascript +// Step 4: Handling multiple specific cases +const dayOfWeek = "Tuesday"; + +switch (dayOfWeek) { + case "Monday": + case "Tuesday": + case "Wednesday": + case "Thursday": + case "Friday": + console.log("It's a weekday - time to work!"); + break; + case "Saturday": + case "Sunday": + console.log("It's the weekend - time to relax!"); + break; + default: + console.log("Invalid day of the week"); +} +``` + +**This code accomplishes the following:** +- **Match** the variable value against multiple specific cases +- **Group** similar cases together (weekdays vs. weekends) +- **Execute** the appropriate code block when a match is found +- **Include** a `default` case to handle unexpected values +- **Use** `break` statements to prevent code from continuing to the next case + +> 💡 **Real-world analogy**: Think of control flow like having the world's most patient GPS giving you directions. It might say "If there's traffic on Main Street, take the highway instead. If construction is blocking the highway, try the scenic route." Programs use exactly the same type of conditional logic to respond intelligently to different situations and always give users the best possible experience. + +### 🎯 **Concept Check: Building Blocks Mastery** + +**Let's see how you're doing with the fundamentals:** +- Can you explain the difference between a variable and a statement in your own words? +- Think of a real-world scenario where you'd use an if-then decision (like our voting example) +- What's one thing about programming logic that surprised you? + +**Quick confidence booster:** +```mermaid +flowchart LR + A["📝 Statements
(Instructions)"] --> B["📦 Variables
(Storage)"] --> C["🔀 Control Flow
(Decisions)"] --> D["🎉 Working Program!"] + + style A fill:#ffeb3b + style B fill:#4caf50 + style C fill:#2196f3 + style D fill:#ff4081 +``` +✅ **What's coming up next**: We're going to have an absolute blast diving deeper into these concepts as we continue this incredible journey together! Right now, just focus on feeling that excitement about all the amazing possibilities ahead of you. The specific skills and techniques will stick naturally as we practice together – I promise this is going to be so much more fun than you might expect! ## Tools of the Trade -[![Tools of the Trade](https://img.youtube.com/vi/69WJeXGBdxg/0.jpg)](https://youtube.com/watch?v=69WJeXGBdxg "Tools of the Trade") +Alright, this is honestly where I get so excited I can barely contain myself! 🚀 We're about to talk about the incredible tools that are going to make you feel like you just got handed the keys to a digital spaceship. + +You know how a chef has those perfectly balanced knives that feel like extensions of their hands? Or how a musician has that one guitar that seems to sing the moment they touch it? Well, developers have our own version of these magical tools, and here's what's going to absolutely blow your mind – most of them are completely free! + +I'm practically bouncing in my chair thinking about sharing these with you because they've completely revolutionized how we build software. We're talking about AI-powered coding assistants that can help write your code (I'm not even kidding!), cloud environments where you can build entire applications from literally anywhere with Wi-Fi, and debugging tools so sophisticated they're like having X-ray vision for your programs. + +And here's the part that still gives me chills: these aren't "beginner tools" that you'll outgrow. These are the exact same professional-grade tools that developers at Google, Netflix, and that indie app studio you love are using right this very moment. You're going to feel like such a pro using them! + +```mermaid +graph TD + A["💡 Your Idea"] --> B["⌨️ Code Editor
(VS Code)"] + B --> C["🌐 Browser DevTools
(Testing & Debugging)"] + C --> D["⚡ Command Line
(Automation & Tools)"] + D --> E["📚 Documentation
(Learning & Reference)"] + E --> F["🚀 Amazing Web App!"] + + B -.-> G["🤖 AI Assistant
(GitHub Copilot)"] + C -.-> H["📱 Device Testing
(Responsive Design)"] + D -.-> I["📦 Package Managers
(npm, yarn)"] + E -.-> J["👥 Community
(Stack Overflow)"] + + style A fill:#fff59d + style F fill:#c8e6c9 + style G fill:#e1f5fe + style H fill:#f3e5f5 + style I fill:#ffccbc + style J fill:#e8eaf6 +``` +### Code Editors and IDEs: Your New Digital Best Friends -> 🎥 Click the image above to watch a video about tooling +Let's talk about code editors – these are seriously about to become your new favorite places to hang out! Think of them as your personal coding sanctuary where you'll spend most of your time crafting and perfecting your digital creations. -In this section, you'll explore software that can be very useful as you begin your journey as a professional developer. +But here's what's absolutely magical about modern editors: they're not just fancy text editors. They're like having the most brilliant, supportive coding mentor sitting right next to you 24/7. They catch your typos before you even notice them, suggest improvements that make you look like a genius, help you understand what every piece of code does, and some of them can even predict what you're about to type and offer to finish your thoughts! -A **development environment** is a unique set of tools and features that developers frequently use when writing software. These tools may be customized to meet a developer's specific needs and can evolve over time as priorities shift, personal projects change, or different programming languages are used. Development environments are as unique as the developers who use them. +I remember when I first discovered auto-completion – I literally felt like I was living in the future. You start typing something, and your editor goes, "Hey, were you thinking of this function that does exactly what you need?" It's like having a mind reader as your coding buddy! -### Editors +**What makes these editors so incredible?** -One of the most essential tools for software development is the editor. Editors are where you write your code and sometimes where you run it. +Modern code editors offer an impressive array of features designed to boost your productivity: -Developers rely on editors for several reasons: +| Feature | What It Does | Why It Helps | +|---------|--------------|--------------| +| **Syntax Highlighting** | Colors different parts of your code | Makes code easier to read and spot errors | +| **Auto-completion** | Suggests code as you type | Speeds up coding and reduces typos | +| **Debugging Tools** | Helps you find and fix errors | Saves hours of troubleshooting time | +| **Extensions** | Add specialized features | Customize your editor for any technology | +| **AI Assistants** | Suggest code and explanations | Accelerates learning and productivity | -- *Debugging* helps identify bugs and errors by stepping through the code line by line. Some editors have built-in debugging capabilities, which can be customized for specific programming languages. -- *Syntax highlighting* adds colors and text formatting to code, making it easier to read. Most editors allow syntax highlighting customization. -- *Extensions and Integrations* are specialized tools created by developers for developers. These tools are not part of the base editor. For example, many developers document their code to explain how it works. They might install a spell-check extension to catch typos in the documentation. Most extensions are designed for specific editors, and most editors include a way to search for available extensions. -- *Customization* allows developers to tailor their development environment to their needs. Most editors are highly customizable and may even allow developers to create custom extensions. +> 🎥 **Video Resource**: Want to see these tools in action? Check out this [Tools of the Trade video](https://youtube.com/watch?v=69WJeXGBdxg) for a comprehensive overview. -#### Popular Editors and Web Development Extensions +#### Recommended Editors for Web Development -- [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) - - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) - - [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare) - - [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) -- [Atom](https://atom.io/) - - [spell-check](https://atom.io/packages/spell-check) - - [teletype](https://atom.io/packages/teletype) - - [atom-beautify](https://atom.io/packages/atom-beautify) - -- [Sublimetext](https://www.sublimetext.com/) - - [emmet](https://emmet.io/) - - [SublimeLinter](http://www.sublimelinter.com/en/stable/) +**[Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)** (Free) +- Most popular among web developers +- Excellent extension ecosystem +- Built-in terminal and Git integration +- **Must-have extensions**: + - [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) - AI-powered code suggestions + - [Live Share](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare) - Real-time collaboration + - [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) - Automatic code formatting + - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) - Catch typos in your code -### Browsers +**[JetBrains WebStorm](https://www.jetbrains.com/webstorm/)** (Paid, free for students) +- Advanced debugging and testing tools +- Intelligent code completion +- Built-in version control -Another essential tool is the browser. Web developers use browsers to test how their code runs on the web. Browsers also display the visual elements of a web page written in the editor, such as HTML. +**Cloud-Based IDEs** (Various pricing) +- [GitHub Codespaces](https://github.com/features/codespaces) - Full VS Code in your browser +- [Replit](https://replit.com/) - Great for learning and sharing code +- [StackBlitz](https://stackblitz.com/) - Instant, full-stack web development -Many browsers include *developer tools* (DevTools), which offer features and information to help developers gather and analyze important details about their applications. For example, if a web page has errors, DevTools can be configured to capture information about when the errors occurred. +> 💡 **Getting Started Tip**: Start with Visual Studio Code – it's free, widely used in the industry, and has an enormous community creating helpful tutorials and extensions. -#### Popular Browsers and DevTools -- [Edge](https://docs.microsoft.com/microsoft-edge/devtools-guide-chromium/?WT.mc_id=academic-77807-sagibbon) -- [Chrome](https://developers.google.com/web/tools/chrome-devtools/) -- [Firefox](https://developer.mozilla.org/docs/Tools) +### Web Browsers: Your Secret Development Laboratory -### Command Line Tools +Okay, prepare to have your mind completely blown! You know how you've been using browsers to scroll through social media and watch videos? Well, it turns out they've been hiding this incredible secret developer laboratory this entire time, just waiting for you to discover it! -Some developers prefer a less graphical interface for their daily tasks and rely on the command line. Writing code involves a lot of typing, and some developers prefer not to disrupt their workflow by switching between the keyboard and mouse. They use keyboard shortcuts to navigate between desktop windows, work on different files, and use tools. While most tasks can be completed with a mouse, the command line allows developers to perform many tasks without switching between the mouse and keyboard. Another advantage of the command line is its configurability—you can save custom configurations, modify them later, and import them to other development machines. Since development environments are highly personalized, some developers avoid the command line, others rely on it entirely, and some prefer a mix of both. +Every single time you right-click on a webpage and select "Inspect Element," you're opening up a hidden world of developer tools that are honestly more powerful than some expensive software I used to pay hundreds of dollars for. It's like discovering that your regular old kitchen has been concealing a professional chef's laboratory behind a secret panel! +The first time someone showed me browser DevTools, I spent like three hours just clicking around and going "WAIT, IT CAN DO THAT TOO?!" You can literally edit any website in real-time, see exactly how fast everything loads, test how your site looks on different devices, and even debug JavaScript like a total pro. It's absolutely mind-blowing! -### Popular Command Line Options +**Here's why browsers are your secret weapon:** -Command line options vary depending on the operating system. +When you create a website or web application, you need to see how it looks and behaves in the real world. Browsers not only display your work but also provide detailed feedback about performance, accessibility, and potential issues. -*💻 = preinstalled on the operating system.* +#### Browser Developer Tools (DevTools) -#### Windows +Modern browsers include comprehensive development suites: -- [Powershell](https://docs.microsoft.com/powershell/scripting/overview?view=powershell-7/?WT.mc_id=academic-77807-sagibbon) 💻 -- [Command Line](https://docs.microsoft.com/windows-server/administration/windows-commands/windows-commands/?WT.mc_id=academic-77807-sagibbon) (also known as CMD) 💻 -- [Windows Terminal](https://docs.microsoft.com/windows/terminal/?WT.mc_id=academic-77807-sagibbon) -- [mintty](https://mintty.github.io/) - -#### MacOS +| Tool Category | What It Does | Example Use Case | +|---------------|--------------|------------------| +| **Element Inspector** | View and edit HTML/CSS in real-time | Adjust styling to see immediate results | +| **Console** | View error messages and test JavaScript | Debug problems and experiment with code | +| **Network Monitor** | Track how resources load | Optimize performance and loading times | +| **Accessibility Checker** | Test for inclusive design | Ensure your site works for all users | +| **Device Simulator** | Preview on different screen sizes | Test responsive design without multiple devices | + +#### Recommended Browsers for Development + +- **[Chrome](https://developers.google.com/web/tools/chrome-devtools/)** - Industry-standard DevTools with extensive documentation +- **[Firefox](https://developer.mozilla.org/docs/Tools)** - Excellent CSS Grid and accessibility tools +- **[Edge](https://docs.microsoft.com/microsoft-edge/devtools-guide-chromium/?WT.mc_id=academic-77807-sagibbon)** - Built on Chromium with Microsoft's developer resources + +> ⚠️ **Important Testing Tip**: Always test your websites in multiple browsers! What works perfectly in Chrome might look different in Safari or Firefox. Professional developers test across all major browsers to ensure consistent user experiences. + + +### Command Line Tools: Your Gateway to Developer Superpowers + +Alright, let's have a completely honest moment here about the command line, because I want you to hear this from someone who truly gets it. When I first saw it – just this scary black screen with blinking text – I literally thought, "Nope, absolutely not! This looks like something from a 1980s hacker movie, and I am definitely not smart enough for this!" 😅 + +But here's what I wish someone had told me back then, and what I'm telling you right now: the command line isn't scary – it's actually like having a direct conversation with your computer. Think of it like the difference between ordering food through a fancy app with pictures and menus (which is nice and easy) versus walking into your favorite local restaurant where the chef knows exactly what you like and can whip up something perfect just by you saying "surprise me with something amazing." + +The command line is where developers go to feel like absolute wizards. You type a few seemingly magical words (okay, they're just commands, but they feel magical!), hit enter, and BOOM – you've created entire project structures, installed powerful tools from around the world, or deployed your app to the internet for millions of people to see. Once you get your first taste of that power, it's honestly pretty addictive! + +**Why the command line will become your favorite tool:** + +While graphical interfaces are great for many tasks, the command line excels at automation, precision, and speed. Many development tools work primarily through command line interfaces, and learning to use them efficiently can dramatically improve your productivity. + +```bash +# Step 1: Create and navigate to project directory +mkdir my-awesome-website +cd my-awesome-website +``` + +**Here's what this code does:** +- **Create** a new directory called "my-awesome-website" for your project +- **Navigate** into the newly created directory to begin working + +```bash +# Step 2: Initialize project with package.json +npm init -y + +# Install modern development tools +npm install --save-dev vite prettier eslint +npm install --save-dev @eslint/js +``` + +**Step by step, here's what's happening:** +- **Initialize** a new Node.js project with default settings using `npm init -y` +- **Install** Vite as a modern build tool for fast development and production builds +- **Add** Prettier for automatic code formatting and ESLint for code quality checks +- **Use** the `--save-dev` flag to mark these as development-only dependencies + +```bash +# Step 3: Create project structure and files +mkdir src assets +echo 'My Site

Hello World

' > index.html + +# Start development server +npx vite +``` + +**In the above, we've:** +- **Organized** our project by creating separate folders for source code and assets +- **Generated** a basic HTML file with proper document structure +- **Started** the Vite development server for live reloading and hot module replacement + +#### Essential Command Line Tools for Web Development -- [Terminal](https://support.apple.com/guide/terminal/open-or-quit-terminal-apd5265185d-f365-44cb-8b09-71a064a42125/mac) 💻 -- [iTerm](https://iterm2.com/) -- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7/?WT.mc_id=academic-77807-sagibbon) +| Tool | Purpose | Why You Need It | +|------|---------|-----------------| +| **[Git](https://git-scm.com/)** | Version control | Track changes, collaborate with others, backup your work | +| **[Node.js & npm](https://nodejs.org/)** | JavaScript runtime & package management | Run JavaScript outside browsers, install modern development tools | +| **[Vite](https://vitejs.dev/)** | Build tool & dev server | Lightning-fast development with hot module replacement | +| **[ESLint](https://eslint.org/)** | Code quality | Automatically find and fix problems in your JavaScript | +| **[Prettier](https://prettier.io/)** | Code formatting | Keep your code consistently formatted and readable | -#### Linux +#### Platform-Specific Options -- [Bash](https://www.gnu.org/software/bash/manual/html_node/index.html) 💻 -- [KDE Konsole](https://docs.kde.org/trunk5/en/konsole/konsole/index.html) -- [Powershell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7/?WT.mc_id=academic-77807-sagibbon) +**Windows:** +- **[Windows Terminal](https://docs.microsoft.com/windows/terminal/?WT.mc_id=academic-77807-sagibbon)** - Modern, feature-rich terminal +- **[PowerShell](https://docs.microsoft.com/powershell/?WT.mc_id=academic-77807-sagibbon)** 💻 - Powerful scripting environment +- **[Command Prompt](https://docs.microsoft.com/windows-server/administration/windows-commands/?WT.mc_id=academic-77807-sagibbon)** 💻 - Traditional Windows command line -#### Popular Command Line Tools +**macOS:** +- **[Terminal](https://support.apple.com/guide/terminal/)** 💻 - Built-in terminal application +- **[iTerm2](https://iterm2.com/)** - Enhanced terminal with advanced features -- [Git](https://git-scm.com/) (💻 on most operating systems) -- [NPM](https://www.npmjs.com/) -- [Yarn](https://classic.yarnpkg.com/en/docs/cli/) +**Linux:** +- **[Bash](https://www.gnu.org/software/bash/)** 💻 - Standard Linux shell +- **[KDE Konsole](https://docs.kde.org/trunk5/en/konsole/konsole/index.html)** - Advanced terminal emulator -### Documentation +> 💻 = Pre-installed on the operating system -When developers want to learn something new, they often turn to documentation for guidance. Documentation helps developers understand how to use tools and languages effectively and provides deeper insights into their functionality. +> 🎯 **Learning Path**: Start with basic commands like `cd` (change directory), `ls` or `dir` (list files), and `mkdir` (create folder). Practice with modern workflow commands like `npm install`, `git status`, and `code .` (opens current directory in VS Code). As you become more comfortable, you'll naturally pick up more advanced commands and automation techniques. -#### Popular Documentation on Web Development -- [Mozilla Developer Network (MDN)](https://developer.mozilla.org/docs/Web), from Mozilla, the publishers of the [Firefox](https://www.mozilla.org/firefox/) browser -- [Frontend Masters](https://frontendmasters.com/learn/) -- [Web.dev](https://web.dev), from Google, publishers of [Chrome](https://www.google.com/chrome/) -- [Microsoft's own developer docs](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers), for [Microsoft Edge](https://www.microsoft.com/edge) -- [W3 Schools](https://www.w3schools.com/where_to_start.asp) +### Documentation: Your Always-Available Learning Mentor -✅ Research task: Now that you understand the basics of a web developer's environment, compare it with a web designer's environment. +Okay, let me share a little secret that's going to make you feel so much better about being a beginner: even the most experienced developers spend a huge chunk of their time reading documentation. And that's not because they don't know what they're doing – it's actually a sign of wisdom! + +Think of documentation as having access to the world's most patient, knowledgeable teachers who are available 24/7. Stuck on a problem at 2 AM? Documentation is there with a warm virtual hug and exactly the answer you need. Want to learn about some cool new feature that everyone's talking about? Documentation has your back with step-by-step examples. Trying to understand why something works the way it does? You guessed it – documentation is ready to explain it in a way that finally makes it click! + +Here's something that completely changed my perspective: the web development world moves incredibly fast, and nobody (I mean absolutely nobody!) keeps everything memorized. I've watched senior developers with 15+ years of experience look up basic syntax, and you know what? That's not embarrassing – that's smart! It's not about having a perfect memory; it's about knowing where to find reliable answers quickly and understanding how to apply them. + +**Here's where the real magic happens:** + +Professional developers spend a significant portion of their time reading documentation – not because they don't know what they're doing, but because the web development landscape evolves so rapidly that staying current requires continuous learning. Great documentation helps you understand not just *how* to use something, but *why* and *when* to use it. + +#### Essential Documentation Resources + +**[Mozilla Developer Network (MDN)](https://developer.mozilla.org/docs/Web)** +- The gold standard for web technology documentation +- Comprehensive guides for HTML, CSS, and JavaScript +- Includes browser compatibility information +- Features practical examples and interactive demos + +**[Web.dev](https://web.dev)** (by Google) +- Modern web development best practices +- Performance optimization guides +- Accessibility and inclusive design principles +- Case studies from real-world projects + +**[Microsoft Developer Documentation](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers)** +- Edge browser development resources +- Progressive Web App guides +- Cross-platform development insights + +**[Frontend Masters Learning Paths](https://frontendmasters.com/learn/)** +- Structured learning curricula +- Video courses from industry experts +- Hands-on coding exercises + +> 📚 **Study Strategy**: Don't try to memorize documentation – instead, learn how to navigate it efficiently. Bookmark frequently-used references and practice using the search functions to find specific information quickly. + +### 🔧 **Tool Mastery Check: What Resonates With You?** + +**Take a moment to consider:** +- Which tool are you most excited to try first? (There's no wrong answer!) +- Does the command line still feel intimidating, or are you curious about it? +- Can you imagine using browser DevTools to peek behind the curtain of your favorite websites? + +```mermaid +pie title "Developer Time Spent With Tools" + "Code Editor" : 40 + "Browser Testing" : 25 + "Command Line" : 15 + "Reading Docs" : 15 + "Debugging" : 5 +``` +> **Fun insight**: Most developers spend about 40% of their time in their code editor, but notice how much time goes to testing, learning, and problem-solving. Programming isn't just about writing code – it's about crafting experiences! + +✅ **Food for thought**: Here's something interesting to ponder – how do you think the tools for building websites (development) might be different from tools for designing how they look (design)? It's like the difference between being an architect who designs a beautiful house and the contractor who actually builds it. Both are crucial, but they need different toolboxes! This kind of thinking will really help you see the bigger picture of how websites come to life. + +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Explore the features of a modern code editor or IDE and demonstrate how it can improve your workflow as a web developer. + +**Prompt:** Choose a code editor or IDE (such as Visual Studio Code, WebStorm, or a cloud-based IDE). List three features or extensions that help you write, debug, or maintain code more efficiently. For each, provide a brief explanation of how it benefits your workflow. --- ## 🚀 Challenge -Compare some programming languages. What are some unique characteristics of JavaScript vs. Java? How about COBOL vs. Go? +**Alright, detective, ready for your first case?** + +Now that you've got this awesome foundation, I've got an adventure that's going to help you see just how incredibly diverse and fascinating the programming world really is. And listen – this isn't about writing code yet, so no pressure there! Think of yourself as a programming language detective on your very first exciting case! -## Post-Lecture Quiz -[Post-lecture quiz](https://ff-quizzes.netlify.app/web/) +**Your mission, should you choose to accept it:** +1. **Become a language explorer**: Pick three programming languages from completely different universes – maybe one that builds websites, one that creates mobile apps, and one that crunches data for scientists. Find examples of the same simple task written in each language. I promise you're going to be absolutely amazed at how different they can look while doing the exact same thing! + +2. **Uncover their origin stories**: What makes each language special? Here's a cool fact – every single programming language was created because someone thought, "You know what? There's got to be a better way to solve this specific problem." Can you figure out what those problems were? Some of these stories are genuinely fascinating! + +3. **Meet the communities**: Check out how welcoming and passionate each language's community is. Some have millions of developers sharing knowledge and helping each other, others are smaller but incredibly tight-knit and supportive. You're going to love seeing the different personalities these communities have! + +4. **Follow your gut feeling**: Which language feels most approachable to you right now? Don't stress about making the "perfect" choice – just listen to your instincts! There's honestly no wrong answer here, and you can always explore others later. + +**Bonus detective work**: See if you can discover what major websites or apps are built with each language. I guarantee you'll be shocked to learn what powers Instagram, Netflix, or that mobile game you can't stop playing! + +> 💡 **Remember**: You're not trying to become an expert in any of these languages today. You're just getting to know the neighborhood before you decide where you want to set up shop. Take your time, have fun with it, and let your curiosity guide you! + +## Let's Celebrate What You've Discovered! + +Holy moly, you've absorbed so much incredible information today! I'm genuinely excited to see how much of this amazing journey has stuck with you. And remember – this isn't a test where you need to get everything perfect. This is more like a celebration of all the cool stuff you've learned about this fascinating world you're about to dive into! + +[Take the post-lesson quiz](https://ff-quizzes.netlify.app/web/) ## Review & Self Study -Explore the different programming languages available. Try writing a line of code in one language, then rewrite it in two others. What did you learn? +**Take your time to explore and have fun with it!** +You've covered a lot of ground today, and that's something to be proud of! Now comes the fun part – exploring the topics that sparked your curiosity. Remember, this isn't homework – it's an adventure! + +**Dive deeper into what excites you:** + +**Get hands-on with programming languages:** +- Visit the official websites of 2-3 languages that caught your attention. Each one has its own personality and story! +- Try some online coding playgrounds like [CodePen](https://codepen.io/), [JSFiddle](https://jsfiddle.net/), or [Replit](https://replit.com/). Don't be afraid to experiment – you can't break anything! +- Read about how your favorite language came to be. Seriously, some of these origin stories are fascinating and will help you understand why languages work the way they do. + +**Get comfortable with your new tools:** +- Download Visual Studio Code if you haven't already – it's free and you're going to love it! +- Spend a few minutes browsing the Extensions marketplace. It's like an app store for your code editor! +- Open up your browser's Developer Tools and just click around. Don't worry about understanding everything – just get familiar with what's there. + +**Join the community:** +- Follow some developer communities on [Dev.to](https://dev.to/), [Stack Overflow](https://stackoverflow.com/), or [GitHub](https://github.com/). The programming community is incredibly welcoming to newcomers! +- Watch some beginner-friendly coding videos on YouTube. There are so many great creators out there who remember what it's like to be starting out. +- Consider joining local meetups or online communities. Trust me, developers love helping newcomers! + +> 🎯 **Listen, here's what I want you to remember**: You're not expected to become a coding wizard overnight! Right now, you're just getting to know this amazing new world you're about to be part of. Take your time, enjoy the journey, and remember – every single developer you admire was once sitting exactly where you are right now, feeling excited and maybe a little overwhelmed. That's totally normal, and it means you're doing it right! + + ## Assignment [Reading the Docs](assignment.md) -> Note: When selecting tools for your assignment, do not choose editors, browsers, or command line tools already listed above. +> 💡 **A little nudge for your assignment**: I'd absolutely love to see you explore some tools we haven't covered yet! Skip the editors, browsers, and command line tools we've already talked about – there's this whole incredible universe of amazing development tools out there just waiting to be discovered. Look for ones that are actively maintained and have vibrant, helpful communities (these tend to have the best tutorials and the most supportive people when you inevitably get stuck and need a friendly hand). + +--- + +## 🚀 Your Programming Journey Timeline + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Bookmark 2-3 programming language websites that caught your attention +- [ ] Download Visual Studio Code if you haven't already +- [ ] Open your browser's DevTools (F12) and click around any website +- [ ] Join one programming community (Dev.to, Reddit r/webdev, or Stack Overflow) + +### ⏰ **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and reflect on your answers +- [ ] Set up VS Code with the GitHub Copilot extension +- [ ] Try a "Hello World" example in 2 different programming languages online +- [ ] Watch a "Day in the Life of a Developer" video on YouTube +- [ ] Start your programming language detective work (from the challenge) + +### 📅 **Your Week-Long Adventure** +- [ ] Complete the assignment and explore 3 new development tools +- [ ] Follow 5 developers or programming accounts on social media +- [ ] Try building something tiny in CodePen or Replit (even just "Hello, [Your Name]!") +- [ ] Read one developer blog post about someone's coding journey +- [ ] Join a virtual meetup or watch a programming talk +- [ ] Start learning your chosen language with online tutorials + +### 🗓️ **Your Month-Long Transformation** +- [ ] Build your first small project (even a simple webpage counts!) +- [ ] Contribute to an open-source project (start with documentation fixes) +- [ ] Mentor someone who's just starting their programming journey +- [ ] Create your developer portfolio website +- [ ] Connect with local developer communities or study groups +- [ ] Start planning your next learning milestone + +### 🎯 **Final Reflection Check-in** + +**Before you move on, take a moment to celebrate:** +- What's one thing about programming that excited you today? +- Which tool or concept do you want to explore first? +- How do you feel about starting this programming journey? +- What's one question you'd like to ask a developer right now? + +```mermaid +journey + title Your Confidence Building Journey + section Today + Curious: 3: You + Overwhelmed: 4: You + Excited: 5: You + section This Week + Exploring: 4: You + Learning: 5: You + Connecting: 4: You + section Next Month + Building: 5: You + Confident: 5: You + Helping Others: 5: You +``` +> 🌟 **Remember**: Every expert was once a beginner. Every senior developer once felt exactly like you do right now – excited, maybe a little overwhelmed, and definitely curious about what's possible. You're in amazing company, and this journey is going to be incredible. Welcome to the wonderful world of programming! 🎉 --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/1-getting-started-lessons/1-intro-to-programming-languages/assignment.md b/translations/en/1-getting-started-lessons/1-intro-to-programming-languages/assignment.md index 09e6e1cf8..49f2f309a 100644 --- a/translations/en/1-getting-started-lessons/1-intro-to-programming-languages/assignment.md +++ b/translations/en/1-getting-started-lessons/1-intro-to-programming-languages/assignment.md @@ -1,31 +1,69 @@ - +# Assignment: Exploring Modern Web Development Tools + ## Instructions -There are many tools that a web developer may need that are listed on the [MDN documentation for client-side tooling](https://developer.mozilla.org/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview). Select **three tools** that are **not covered in this lesson** (excluding [list specific tools or refer to lesson content]), explain **why** a web developer would use each tool, and find a tool that fits each category. For each, share a link to its official documentation (not the example used on MDN). +The web development ecosystem includes hundreds of specialized tools that help developers build, test, and maintain applications efficiently. Your task is to research and understand tools that complement the ones covered in this lesson. + +**Your Mission:** Select **three tools** that are **not covered in this lesson** (avoid choosing code editors, browsers, or command line tools already listed). Focus on tools that solve specific problems in modern web development workflows. + +**For each tool, provide:** + +1. **Tool name and category** (e.g., "Figma - Design Tool" or "Jest - Testing Framework") +2. **Purpose and benefits** - Explain in 2-3 sentences why a web developer would use this tool and what problems it solves +3. **Official documentation link** - Provide a link to the tool's official documentation or website (not just tutorial sites) +4. **Real-world context** - Mention one way this tool fits into a professional development workflow + +## Suggested Tool Categories + +Consider exploring tools from these categories: + +| Category | Examples | What They Do | +|----------|----------|--------------| +| **Build Tools** | Vite, Webpack, Parcel, esbuild | Bundle and optimize code for production with fast development servers | +| **Testing Frameworks** | Vitest, Jest, Cypress, Playwright | Ensure code works correctly and catch bugs before deployment | +| **Design Tools** | Figma, Adobe XD, Penpot | Create mockups, prototypes, and design systems collaboratively | +| **Deployment Platforms** | Netlify, Vercel, Cloudflare Pages | Host and distribute websites with automatic CI/CD | +| **Version Control** | GitHub, GitLab, Bitbucket | Manage code changes, collaboration, and project workflows | +| **CSS Frameworks** | Tailwind CSS, Bootstrap, Bulma | Accelerate styling with pre-built component libraries | +| **Package Managers** | npm, pnpm, Yarn | Install and manage code libraries and dependencies | +| **Accessibility Tools** | axe-core, Lighthouse, Pa11y | Test for inclusive design and WCAG compliance | +| **API Development** | Postman, Insomnia, Thunder Client | Test and document APIs during development | -**Format:** -- Tool name -- Why a web developer would use it (2-3 sentences) -- Link to documentation +## Format Requirements -**Length:** -- Each explanation should be 2-3 sentences. +**For each tool:** +``` +### [Tool Name] - [Category] + +**Purpose:** [2-3 sentences explaining why developers use this tool] + +**Documentation:** [Official website/documentation link] + +**Workflow Integration:** [1 sentence about how it fits into development process] +``` + +## Quality Guidelines + +- **Choose current tools**: Select tools that are actively maintained and widely used in 2025 +- **Focus on value**: Explain the specific benefits, not just what the tool does +- **Professional context**: Consider tools used by development teams, not just individual hobbyists +- **Diverse selection**: Pick tools from different categories to show breadth of the ecosystem +- **Modern relevance**: Prioritize tools that align with current web development trends and best practices ## Rubric -Exemplary | Adequate | Needs Improvement ---- | --- | -- | -Explained why web developer would use tool | Explained how, but not why developer would use tool | Did not mention how or why a developer would use tool | +| Excellent | Good | Needs Improvement | +|-----------|------|-------------------| +| **Clearly explained why developers use each tool and what problems it solves** | **Explained what the tool does but missed some context about its value** | **Listed tools but didn't explain their purpose or benefits** | +| **Provided official documentation links for all tools** | **Provided mostly official links with 1-2 tutorial sites** | **Relied mainly on tutorial sites rather than official documentation** | +| **Selected current, professionally-used tools from diverse categories** | **Selected good tools but limited variety in categories** | **Selected outdated tools or only from one category** | +| **Demonstrated understanding of how tools fit into development workflows** | **Showed some understanding of professional context** | **Focused only on tool features without workflow context** | + +> 💡 **Research Tip**: Look for tools mentioned in job postings for web developers, check popular developer surveys, or explore the dependencies used by successful open-source projects on GitHub! --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/1-getting-started-lessons/2-github-basics/README.md b/translations/en/1-getting-started-lessons/2-github-basics/README.md index ab0c7ec08..dd96267ba 100644 --- a/translations/en/1-getting-started-lessons/2-github-basics/README.md +++ b/translations/en/1-getting-started-lessons/2-github-basics/README.md @@ -1,344 +1,769 @@ - # Introduction to GitHub -This lesson introduces the basics of GitHub, a platform for hosting and managing changes to your code. +Hey there, future developer! 👋 Ready to join millions of coders around the world? I'm genuinely excited to introduce you to GitHub – think of it as the social media platform for programmers, except instead of sharing photos of your lunch, we're sharing code and building incredible things together! -![Intro to GitHub](../../../../translated_images/en/webdev101-github.8846d7971abef6f947909b4f9d343e2a23778aa716ca6b9d71df7174ee5009ac.png) +Here's what absolutely blows my mind: every app on your phone, every website you visit, and most of the tools you'll learn to use were built by teams of developers collaborating on platforms just like GitHub. That music app you love? Someone like you contributed to it. That game you can't put down? Yep, probably built with GitHub collaboration. And now YOU'RE going to learn how to be part of that amazing community! + +I know this might feel like a lot at first – heck, I remember staring at my first GitHub page thinking "What on earth does any of this mean?" But here's the thing: every single developer started exactly where you are right now. By the end of this lesson, you'll have your very own GitHub repository (think of it as your personal project showcase in the cloud), and you'll know how to save your work, share it with others, and even contribute to projects that millions of people use. + +We're going to take this journey together, one step at a time. No rushing, no pressure – just you, me, and some really cool tools that are about to become your new best friends! + +![Intro to GitHub](../../../../translated_images/en/webdev101-github.8846d7971abef6f9.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) +```mermaid +journey + title Your GitHub Adventure Today + section Setup + Install Git: 4: You + Create Account: 5: You + First Repository: 5: You + section Master Git + Local Changes: 4: You + Commits & Pushes: 5: You + Branching: 4: You + section Collaborate + Fork Projects: 4: You + Pull Requests: 5: You + Open Source: 5: You +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app) ## Introduction -In this lesson, we'll explore: +Before we dive into the really exciting stuff, let's get your computer ready for some GitHub magic! Think of this like organizing your art supplies before creating a masterpiece – having the right tools ready makes everything so much smoother and way more fun. -- Tracking your work on your computer -- Collaborating on projects with others -- Contributing to open-source software +I'm going to walk you through each setup step personally, and I promise it's not nearly as intimidating as it might look at first glance. If something doesn't click right away, that's completely normal! I remember setting up my first development environment and feeling like I was trying to read ancient hieroglyphics. Every single developer has been exactly where you are right now, wondering if they're doing it right. Spoiler alert: if you're here learning, you're already doing it right! 🌟 + +In this lesson, we'll cover: + +- tracking the work you do on your machine +- working on projects with others +- how to contribute to open source software ### Prerequisites -Before starting, check if Git is installed. In the terminal, type: +Let's get your computer ready for some GitHub magic! Don't worry – this setup is something you only need to do once, and then you'll be all set for your entire coding journey. + +Alright, let's start with the foundation! First, we need to check if Git is already hanging out on your computer. Git is basically like having a super-smart assistant that remembers every single change you make to your code – way better than frantically hitting Ctrl+S every two seconds (we've all been there!). + +Let's see if Git is already installed by typing this magic command in your terminal: `git --version` -If Git isn't installed, [download Git](https://git-scm.com/downloads). Then, set up your local Git profile in the terminal: -* `git config --global user.name "your-name"` -* `git config --global user.email "your-email"` +If Git isn't there yet, no worries! Just head over to [download Git](https://git-scm.com/downloads) and grab it. Once you've got it installed, we need to introduce Git to you properly: + +> 💡 **First Time Setup**: These commands tell Git who you are. This information will be attached to every commit you make, so choose a name and email you're comfortable sharing publicly. + +```bash +git config --global user.name "your-name" +git config --global user.email "your-email" +``` -To verify if Git is already configured, type: -`git config --list` +To check if Git is already configured you can type: +```bash +git config --list +``` -You'll also need a GitHub account, a code editor (like Visual Studio Code), and access to your terminal (or command prompt). +You'll also need a GitHub account, a code editor (like Visual Studio Code), and you'll need to open your terminal (or: command prompt). -Visit [github.com](https://github.com/) to create an account if you don't have one, or log in and complete your profile. +Navigate to [github.com](https://github.com/) and create an account if you haven't already, or log in and fill out your profile. -✅ GitHub isn't the only code repository platform out there, but it's the most widely known. +💡 **Modern tip**: Consider setting up [SSH keys](https://docs.github.com/en/authentication/connecting-to-github-with-ssh) or using [GitHub CLI](https://cli.github.com/) for easier authentication without passwords. + +✅ GitHub isn't the only code repository in the world; there are others, but GitHub is the best known ### Preparation -You'll need a folder containing a code project on your local machine (laptop or PC) and a public repository on GitHub to practice contributing to others' projects. +You'll need both a folder with a code project on your local machine (laptop or PC), and a public repository on GitHub, which will serve as an example for how to contribute to the projects of others. ---- +### Keeping Your Code Safe -## Code Management +Let's talk about security for a moment – but don't worry, we're not going to overwhelm you with scary stuff! Think of these security practices like locking your car or your house. They're simple habits that become second nature and keep your hard work protected. -Imagine you have a folder on your computer with a code project, and you want to start tracking your progress using Git, a version control system. Some people liken using Git to writing a love letter to your future self. By reading your commit messages days, weeks, or months later, you'll recall why you made certain decisions or "roll back" changes—provided you write good commit messages. +We'll show you the modern, secure ways to work with GitHub right from the start. This way, you'll develop good habits that will serve you well throughout your coding career. + +When working with GitHub, it's important to follow security best practices: + +| Security Area | Best Practice | Why It Matters | +|---------------|---------------|----------------| +| **Authentication** | Use SSH keys or Personal Access Tokens | Passwords are less secure and being phased out | +| **Two-Factor Authentication** | Enable 2FA on your GitHub account | Adds an extra layer of account protection | +| **Repository Security** | Never commit sensitive information | API keys and passwords should never be in public repos | +| **Dependency Management** | Enable Dependabot for updates | Keeps your dependencies secure and up-to-date | + +> ⚠️ **Critical Security Reminder**: Never commit API keys, passwords, or other sensitive information to any repository. Use environment variables and `.gitignore` files to protect sensitive data. + +**Modern Authentication Setup:** + +```bash +# Generate SSH key (modern ed25519 algorithm) +ssh-keygen -t ed25519 -C "your_email@example.com" + +# Set up Git to use SSH +git remote set-url origin git@github.com:username/repository.git +``` + +> 💡 **Pro Tip**: SSH keys eliminate the need to enter passwords repeatedly and are more secure than traditional authentication methods. + +--- + +## Managing Your Code Like a Pro + +Okay, THIS is where things get really exciting! 🎉 We're about to learn how to track and manage your code like the pros do, and honestly, this is one of my favorite things to teach because it's such a game-changer. + +Picture this: you're writing an amazing story, and you want to keep track of every draft, every brilliant edit, and every "wait, that's genius!" moment along the way. That's exactly what Git does for your code! It's like having the most incredible time-traveling notebook that remembers EVERYTHING – every keystroke, every change, every "oops, that broke everything" moment that you can instantly undo. + +I'll be honest – this might feel overwhelming at first. When I started, I thought "Why can't I just save my files like normal?" But trust me on this: once Git clicks for you (and it will!), you'll have one of those lightbulb moments where you think "How did I EVER code without this?" It's like discovering you can fly when you've been walking everywhere your whole life! + +Let's say you have a folder locally with some code project and you want to start tracking your progress using git - the version control system. Some people compare using git to writing a love letter to your future self. Reading your commit messages days or weeks or months later you'll be able to recall why you made a decision, or "rollback" a change - that is, when you write good "commit messages". + +```mermaid +flowchart TD + A[📁 Your Project Files] --> B{Is it a Git Repository?} + B -->|No| C[git init] + B -->|Yes| D[Make Changes] + C --> D + D --> E[git add .] + E --> F["git commit -m 'message'"] + F --> G[git push] + G --> H[🌟 Code on GitHub!] + + H --> I{Want to collaborate?} + I -->|Yes| J[Fork & Clone] + I -->|No| D + J --> K[Create Branch] + K --> L[Make Changes] + L --> M[Pull Request] + M --> N[🎉 Contributing!] + + style A fill:#fff59d + style H fill:#c8e6c9 + style N fill:#ff4081,color:#fff +``` +### Task: Create Your First Repository! + +> 🎯 **Your Mission (and I'm so excited for you!)**: We're going to create your very first GitHub repository together! By the time we're done here, you'll have your own little corner of the internet where your code lives, and you'll have made your first "commit" (that's developer speak for saving your work in a really smart way). +> +> This is honestly such a special moment – you're about to officially join the global community of developers! I still remember the thrill of creating my first repo and thinking "Wow, I'm really doing this!" -### Task: Create a Repository and Commit Code +Let's walk through this adventure together, step by step. Take your time with each part – there's no prize for rushing, and I promise every single step will make sense. Remember, every coding superstar you admire was once sitting exactly where you are, about to create their first repository. How cool is that? -> Watch the video +> Check out video > > [![Git and GitHub basics video](https://img.youtube.com/vi/9R31OUPpxU4/0.jpg)](https://www.youtube.com/watch?v=9R31OUPpxU4) -1. **Create a repository on GitHub**. On GitHub.com, go to the repositories tab or use the navigation bar in the top-right corner to find the **new repo** button. +**Let's Do This Together:** - 1. Name your repository (folder). - 1. Click **create repository**. +1. **Create your repository on GitHub**. Head over to GitHub.com and look for that bright green **New** button (or the **+** sign in the top right corner). Click it and select **New repository**. -1. **Navigate to your working folder**. In your terminal, switch to the folder (directory) you want to start tracking. Type: + Here's what to do: + 1. Give your repository a name – make it something meaningful to you! + 1. Add a description if you want (this helps others understand what your project is about) + 1. Decide if you want it public (everyone can see it) or private (just for you) + 1. I recommend checking the box to add a README file – it's like the front page of your project + 1. Click **Create repository** and celebrate – you just created your first repo! 🎉 + +2. **Navigate to your project folder**. Now let's open up your terminal (don't worry, it's not as scary as it looks!). We need to tell your computer where your project files are. Type this command: ```bash cd [name of your folder] ``` -1. **Initialize a Git repository**. In your project folder, type: + **What we're doing here:** + - We're basically saying "Hey computer, take me to my project folder" + - This is like opening a specific folder on your desktop, but we're doing it with text commands + - Replace `[name of your folder]` with the actual name of your project folder + +3. **Turn your folder into a Git repository**. This is where the magic happens! Type: ```bash git init ``` -1. **Check the status**. To check the status of your repository, type: + **Here's what just happened (pretty cool stuff!):** + - Git just created a hidden `.git` folder in your project – you won't see it, but it's there! + - Your regular folder is now a "repository" that can track every change you make + - Think of it like giving your folder superpowers to remember everything + +4. **Check what's happening**. Let's see what Git thinks about your project right now: ```bash git status ``` - The output might look like this: + **Understanding what Git is telling you:** + + You might see something that looks like this: ```output Changes not staged for commit: (use "git add ..." to update what will be committed) - (use "git checkout -- ..." to discard changes in working directory) + (use "git restore ..." to discard changes in working directory) modified: file.txt modified: file2.txt ``` - The `git status` command typically shows information like which files are ready to be saved to the repository or have changes you might want to preserve. + **Don't panic! Here's what this means:** + - Files in **red** are files that have changes but aren't ready to be saved yet + - Files in **green** (when you see them) are ready to be saved + - Git is being helpful by telling you exactly what you can do next -1. **Add all files for tracking** - This is also known as staging files or adding files to the staging area. + > 💡 **Pro tip**: The `git status` command is your best friend! Use it anytime you're confused about what's going on. It's like asking Git "Hey, what's the situation right now?" + +5. **Get your files ready to save** (this is called "staging"): ```bash git add . ``` - The `git add` command with the `.` argument stages all your files and changes for tracking. + **What we just did:** + - We told Git "Hey, I want to include ALL my files in the next save" + - The `.` is like saying "everything in this folder" + - Now your files are "staged" and ready for the next step -1. **Add selected files for tracking** + **Want to be more selective?** You can add just specific files: ```bash git add [file or folder name] ``` - This allows you to stage only specific files when you don't want to commit everything at once. + **Why might you want to do this?** + - Sometimes you want to save related changes together + - It helps you organize your work into logical chunks + - Makes it easier to understand what changed and when -1. **Unstage all files** + **Changed your mind?** No worries! You can unstage files like this: ```bash + # Unstage everything git reset + + # Unstage just one file + git reset [file name] ``` - This command unstages all files at once. + Don't worry – this doesn't delete your work, it just takes files out of the "ready to save" pile. -1. **Unstage a specific file** - - ```bash - git reset [file or folder name] - ``` - - This command unstages only a particular file that you don't want to include in the next commit. - -1. **Save your work**. At this point, you've added files to the staging area, where Git tracks your files. To make the changes permanent, you need to commit the files. A commit represents a save point in your repository's history. Type the following to create a commit: +6. **Save your work permanently** (making your first commit!): ```bash git commit -m "first commit" ``` - This commits all your files with the message "first commit." For future commit messages, aim to be more descriptive to convey the type of change you've made. + **🎉 Congratulations! You just made your first commit!** + + **Here's what just happened:** + - Git took a "snapshot" of all your staged files at this exact moment + - Your commit message "first commit" explains what this save point is about + - Git gave this snapshot a unique ID so you can always find it later + - You've officially started tracking your project's history! -1. **Connect your local Git repository to GitHub**. While a Git repository is useful on your computer, you'll eventually want to back up your files and collaborate with others. GitHub is a great platform for this. Since we've already created a repository on GitHub, we just need to connect it to our local Git repository. Use the `git remote add` command. Type: + > 💡 **Future commit messages**: For your next commits, be more descriptive! Instead of "updated stuff", try "Add contact form to homepage" or "Fix navigation menu bug". Your future self will thank you! - > Before typing the command, go to your GitHub repository page to find the repository URL. Replace ```https://github.com/username/repository_name.git``` with your GitHub URL. +7. **Connect your local project to GitHub**. Right now, your project exists only on your computer. Let's connect it to your GitHub repository so you can share it with the world! + + First, go to your GitHub repository page and copy the URL. Then come back here and type: ```bash git remote add origin https://github.com/username/repository_name.git ``` + + (Replace that URL with your actual repository URL!) - This creates a remote connection named "origin" pointing to the GitHub repository you created earlier. + **What we just did:** + - We created a connection between your local project and your GitHub repository + - "Origin" is just a nickname for your GitHub repository – it's like adding a contact to your phone + - Now your local Git knows where to send your code when you're ready to share it -1. **Push local files to GitHub**. Now that you've established a connection between your local repository and the GitHub repository, send your files to GitHub using the `git push` command: + 💡 **Easier way**: If you have GitHub CLI installed, you can do this in one command: + ```bash + gh repo create my-repo --public --push --source=. + ``` - > Note: Your branch name might differ from ```main```. +8. **Send your code to GitHub** (the big moment!): ```bash git push -u origin main ``` - This pushes your commits from the "main" branch to GitHub. Including `-u` in the command sets the upstream branch, allowing you to use `git push` or `git pull` without specifying the branch name in future commands. + **🚀 This is it! You're uploading your code to GitHub!** + + **What's happening:** + - Your commits are traveling from your computer to GitHub + - The `-u` flag sets up a permanent connection so future pushes are easier + - "main" is the name of your primary branch (like the main folder) + - After this, you can just type `git push` for future uploads! + + 💡 **Quick note**: If your branch is called something else (like "master"), use that name instead. You can check with `git branch --show-current`. + +9. **Your new daily coding rhythm** (this is where it gets addictive!): -2. **Add more changes**. To continue making changes and pushing them to GitHub, use the following three commands: + From now on, whenever you make changes to your project, you've got this simple three-step dance: ```bash git add . - git commit -m "type your commit message here" + git commit -m "describe what you changed" git push ``` - > Tip: Consider adopting a `.gitignore` file to exclude files you don't want to track, such as personal notes stored in the same folder. You can find templates for `.gitignore` files at [.gitignore templates](https://github.com/github/gitignore). + **This becomes your coding heartbeat:** + - Make some awesome changes to your code ✨ + - Stage them with `git add` ("Hey Git, pay attention to these changes!") + - Save them with `git commit` and a descriptive message (future you will thank you!) + - Share them with the world using `git push` 🚀 + - Rinse and repeat – seriously, this becomes as natural as breathing! + + I love this workflow because it's like having multiple save points in a video game. Made a change you love? Commit it! Want to try something risky? No problem – you can always go back to your last commit if things go sideways! + + > 💡 **Tip**: You might also want to adopt a `.gitignore` file to prevent files you don't want to track from showing up on GitHub - like that notes file you store in the same folder but has no place on a public repository. You can find templates for `.gitignore` files at [.gitignore templates](https://github.com/github/gitignore) or create one using [gitignore.io](https://www.toptal.com/developers/gitignore). + +### 🧠 **First Repository Check-in: How Did That Feel?** + +**Take a moment to celebrate and reflect:** +- How did it feel to see your code appear on GitHub for the first time? +- Which step felt the most confusing, and which felt surprisingly easy? +- Can you explain the difference between `git add`, `git commit`, and `git push` in your own words? + +```mermaid +stateDiagram-v2 + [*] --> LocalFiles: Create project + LocalFiles --> Staged: git add . + Staged --> Committed: git commit + Committed --> GitHub: git push + GitHub --> [*]: Success! 🎉 + + note right of Staged + Files ready to save + end note + + note right of Committed + Snapshot created + end note +``` +> **Remember**: Even experienced developers sometimes forget the exact commands. Having this workflow become muscle memory takes practice - you're doing great! + +#### Modern Git workflows + +Consider adopting these modern practices: + +- **Conventional Commits**: Use a standardized commit message format like `feat:`, `fix:`, `docs:`, etc. Learn more at [conventionalcommits.org](https://www.conventionalcommits.org/) +- **Atomic commits**: Make each commit represent a single logical change +- **Frequent commits**: Commit often with descriptive messages rather than large, infrequent commits -#### Commit Messages +#### Commit messages -A great Git commit subject line completes the sentence: -"If applied, this commit will ." +A great Git commit subject line completes the following sentence: +If applied, this commit will -For the subject, use the imperative, present tense: "change" instead of "changed" or "changes." -Similarly, in the optional body, use the imperative, present tense. The body should explain the motivation for the change and contrast it with previous behavior. Focus on the `why`, not the `how`. +For the subject use the imperative, present tense: "change" not "changed" nor "changes". +As in the subject, in the body (optional) also use the imperative, present tense. The body should include the motivation for the change and contrast this with previous behavior. You're explaining the `why`, not the `how`. -✅ Spend a few minutes exploring GitHub. Can you find an excellent commit message? How about a very minimal one? What information do you think is most important to include in a commit message? +✅ Take a few minutes to surf around GitHub. Can you find a really great commit message? Can you find a really minimal one? What information do you think is the most important and useful to convey in a commit message? -### Task: Collaborate +## Working with Others (The Fun Part!) -The primary reason for uploading projects to GitHub is to enable collaboration with other developers. +Hold onto your hat because THIS is where GitHub becomes absolutely magical! 🪄 You've mastered managing your own code, but now we're diving into my absolute favorite part – collaborating with amazing people from all over the world. -## Working on Projects with Others +Picture this: you wake up tomorrow and see that someone in Tokyo improved your code while you were sleeping. Then someone in Berlin fixes a bug you've been stuck on. By afternoon, a developer in São Paulo has added a feature you never even thought of. That's not science fiction – that's just Tuesday in the GitHub universe! -> Watch the video +What gets me really excited is that the collaboration skills you're about to learn? These are the EXACT same workflows that teams at Google, Microsoft, and your favorite startups use every single day. You're not just learning a cool tool – you're learning the secret language that makes the entire software world work together. + +Seriously, once you experience the rush of having someone merge your first pull request, you'll understand why developers get so passionate about open source. It's like being part of the world's biggest, most creative team project! + +> Check out video > > [![Git and GitHub basics video](https://img.youtube.com/vi/bFCM-PC3cu8/0.jpg)](https://www.youtube.com/watch?v=bFCM-PC3cu8) -In your repository, navigate to `Insights > Community` to see how your project aligns with recommended community standards. +The main reason for putting things on GitHub was to make it possible to collaborate with other developers. + +```mermaid +flowchart LR + A[🔍 Find Project] --> B[🍴 Fork Repository] + B --> C[📥 Clone to Local] + C --> D[🌿 Create Branch] + D --> E[✏️ Make Changes] + E --> F[💾 Commit Changes] + F --> G[📤 Push Branch] + G --> H[🔄 Create Pull Request] + H --> I{Maintainer Review} + I -->|✅ Approved| J[🎉 Merge!] + I -->|❓ Changes Requested| K[📝 Make Updates] + K --> F + J --> L[🧹 Clean Up Branches] + + style A fill:#e3f2fd + style J fill:#e8f5e8 + style L fill:#fff3e0 +``` +In your repository, navigate to `Insights > Community` to see how your project compares to recommended community standards. + +Want to make your repository look professional and welcoming? Head over to your repository and click on `Insights > Community`. This cool feature shows you how your project compares to what the GitHub community considers "good repository practices." + +> 🎯 **Making Your Project Shine**: A well-organized repository with good documentation is like having a clean, welcoming storefront. It tells people you care about your work and makes others want to contribute! + +**Here's what makes a repository awesome:** + +| What to Add | Why It's Important | What It Does for You | +|-------------|-------------------|---------------------| +| **Description** | First impression matters! | People know instantly what your project does | +| **README** | Your project's front page | Like a friendly tour guide for new visitors | +| **Contributing Guidelines** | Shows you welcome help | People know exactly how they can help you | +| **Code of Conduct** | Creates a friendly space | Everyone feels welcome to participate | +| **License** | Legal clarity | Others know how they can use your code | +| **Security Policy** | Shows you're responsible | Demonstrates professional practices | + +> 💡 **Pro Tip**: GitHub provides templates for all of these files. When creating a new repository, check the boxes to automatically generate these files. + +**Modern GitHub Features to Explore:** + +🤖 **Automation & CI/CD:** +- **GitHub Actions** for automated testing and deployment +- **Dependabot** for automatic dependency updates + +💬 **Community & Project Management:** +- **GitHub Discussions** for community conversations beyond issues +- **GitHub Projects** for kanban-style project management +- **Branch protection rules** to enforce code quality standards -Here are some ways to improve your GitHub repository: -- **Description**: Have you added a description for your project? -- **README**: Have you included a README? GitHub offers guidance for writing a [README](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon). -- **Contributing Guidelines**: Does your project have [contributing guidelines](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/?WT.mc_id=academic-77807-sagibbon)? -- **Code of Conduct**: Have you added a [Code of Conduct](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/)? -- **License**: Perhaps most importantly, have you added a [license](https://docs.github.com/articles/adding-a-license-to-a-repository/)? -These resources help onboard new team members. They're often the first things new contributors review before even looking at your code to determine if your project is worth their time. +All these resources will benefit onboarding new team members. And those are typically the kind of things new contributors look at before even looking at your code, to find out if your project is the right place for them to be spending their time. -✅ README files, while time-consuming to prepare, are often overlooked by busy maintainers. Can you find an example of a particularly detailed README? Note: There are [tools to help create good READMEs](https://www.makeareadme.com/) that you might want to try. +✅ README files, although they take time to prepare, are often neglected by busy maintainers. Can you find an example of a particularly descriptive one? Note: there are some [tools to help create good READMEs](https://www.makeareadme.com/) that you might like to try. -### Task: Merge Code +### Task: Merge some code -Contributing documentation helps people contribute to your project. It explains the types of contributions you're looking for and outlines the process. Contributors will need to follow several steps to contribute to your GitHub repository: +Contributing docs help people contribute to the project. It explains what types of contributions you're looking for and how the process works. Contributors will need to go through a series of steps to be able to contribute to your repo on GitHub: -1. **Fork your repository**: Contributors will likely need to _fork_ your project, creating a copy of your repository on their GitHub profile. -1. **Clone**: From there, they will clone the project to their local machine. -1. **Create a branch**: Ask contributors to create a _branch_ for their work. -1. **Focus on one area**: Encourage contributors to focus their changes on one specific area at a time. This increases the likelihood of successfully merging their work. For example, if they fix a bug, add a new feature, and update tests, you might only want to implement 1 or 2 of those changes. -✅ Think of situations where branches are particularly important for writing and shipping good code. What use cases come to mind? +1. **Forking your repo** You will probably want people to _fork_ your project. Forking means creating a replica of your repository on their GitHub profile. +1. **Clone**. From there they will clone the project to their local machine. +1. **Create a branch**. You will want to ask them to create a _branch_ for their work. +1. **Focus their change on one area**. Ask contributors to concentrate their contributions on one thing at a time - that way the chances that you can _merge_ in their work is higher. Imagine they write a bug fix, add a new feature, and update several tests - what if you want to, or can only implement 2 out of 3, or 1 out of 3 changes? -> Note: Be the change you want to see in the world—create branches for your own work too. Any commits you make will apply to the branch you're currently "checked out" to. Use `git status` to see which branch you're on. +✅ Imagine a situation where branches are particularly critical to writing and shipping good code. What use cases can you think of? -Let's walk through a contributor workflow. Assume the contributor has already _forked_ and _cloned_ the repository, so they have a Git repository ready to work on locally: +> Note, be the change you want to see in the world, and create branches for your own work as well. Any commits you make will be made on the branch you’re currently “checked out” to. Use `git status` to see which branch that is. -1. **Create a branch**: Use the `git branch` command to create a branch for the changes they plan to contribute: +Let's go through a contributor workflow. Assume the contributor has already _forked_ and _cloned_ the repo so they have a Git repo ready to be worked on, on their local machine: + +1. **Create a branch**. Use the command `git branch` to create a branch that will contain the changes they mean to contribute: ```bash git branch [branch-name] ``` -1. **Switch to the working branch**: Switch to the specified branch and update the working directory using `git switch`: + > 💡 **Modern Approach**: You can also create and switch to the new branch in one command: + ```bash + git switch -c [branch-name] + ``` + +1. **Switch to working branch**. Switch to the specified branch and update the working directory with `git switch`: ```bash git switch [branch-name] ``` -1. **Make changes**: Add your changes and inform Git using the following commands: + > 💡 **Modern Note**: `git switch` is the modern replacement for `git checkout` when changing branches. It's clearer and safer for beginners. + +1. **Do work**. At this point you want to add your changes. Don't forget to tell Git about it with the following commands: ```bash git add . git commit -m "my changes" ``` - Ensure your commit message is clear and descriptive for both yourself and the repository maintainer. + > ⚠️ **Commit Message Quality**: Ensure you give your commit a good name, both for your sake and the maintainer of the repo you are helping on. Be specific about what you changed! -1. **Merge your work with the `main` branch**: Once you're done working, you'll want to merge your changes with the `main` branch. Since the `main` branch might have changed in the meantime, update it first using the following commands: +1. **Combine your work with the `main` branch**. At some point you are done working and you want to combine your work with that of the `main` branch. The `main` branch might have changed meanwhile so make sure you first update it to the latest with the following commands: ```bash git switch main git pull ``` - To ensure any conflicts (situations where Git can't automatically merge changes) occur in your working branch, run the following commands: + At this point you want to make sure that any _conflicts_, situations where Git can't easily _combine_ the changes happens in your working branch. Therefore run the following commands: ```bash git switch [branch_name] git merge main ``` - The `git merge main` command incorporates all changes from `main` into your branch. Ideally, you can proceed without issues. If conflicts arise, VS Code will highlight where Git is "confused," allowing you to resolve the affected files. + The `git merge main` command will bring in all changes from `main` into your branch. Hopefully you can just continue. If not, VS Code will tell you where Git is _confused_ and you just alter the affected files to say which content is the most accurate. - To switch to a different branch, use the modern `git switch` command: + 💡 **Modern alternative**: Consider using `git rebase` for a cleaner history: ```bash - git switch [branch_name] - + git rebase main + ``` + This replays your commits on top of the latest main branch, creating a linear history. -1. **Push your work to GitHub**: Sending your work to GitHub involves two steps: pushing your branch to your repository and opening a Pull Request (PR). +1. **Send your work to GitHub**. Sending your work to GitHub means two things. Pushing your branch to your repo and then open up a PR, Pull Request. ```bash git push --set-upstream origin [branch-name] ``` - The above command creates the branch on your forked repository. -1. **Open a PR**. Next, you’ll want to open a PR. To do this, navigate to the forked repository on GitHub. GitHub will show an option asking if you want to create a new PR. Click on it, and you’ll be taken to an interface where you can edit the commit message title and provide a more suitable description. Now, the maintainer of the repository you forked will see this PR and, _fingers crossed_, they’ll appreciate it and _merge_ your PR. Congratulations, you’re now a contributor, yay! :) + The above command creates the branch on your forked repo. + +### 🤝 **Collaboration Skills Check: Ready to Work with Others?** + +**Let's see how you're feeling about collaboration:** +- Does the idea of forking and pull requests make sense to you now? +- What's one thing about working with branches that you want to practice more? +- How comfortable do you feel about contributing to someone else's project? + +```mermaid +mindmap + root((Git Collaboration)) + Branching + Feature branches + Bug fix branches + Experimental work + Pull Requests + Code review + Discussion + Testing + Best Practices + Clear commit messages + Small focused changes + Good documentation +``` +> **Confidence booster**: Every single developer you admire was once nervous about their first pull request. The GitHub community is incredibly welcoming to newcomers! + +1. **Open a PR**. Next, you want to open up a PR. You do that by navigating to the forked repo on GitHub. You will see an indication on GitHub where it asks whether you want to create a new PR, you click that and you are taken to an interface where you can change commit message title, give it a more suitable description. Now the maintainer of the repo you forked will see this PR and _fingers crossed_ they will appreciate and _merge_ your PR. You are now a contributor, yay :) + + 💡 **Modern tip**: You can also create PRs using GitHub CLI: + ```bash + gh pr create --title "Your PR title" --body "Description of changes" + ``` + + 🔧 **Best practices for PRs**: + - Link to related issues using keywords like "Fixes #123" + - Add screenshots for UI changes + - Request specific reviewers + - Use draft PRs for work-in-progress + - Ensure all CI checks pass before requesting review -1. **Clean up**. It’s considered good practice to _clean up_ after successfully merging a PR. You should clean up both your local branch and the branch you pushed to GitHub. First, delete it locally using the following command: +1. **Clean up**. It's considered good practice to _clean up_ after you successfully merge a PR. You want to clean up both your local branch and the branch you pushed to GitHub. First let's delete it locally with the following command: ```bash git branch -d [branch-name] ``` - Next, go to the GitHub page for the forked repository and remove the remote branch you just pushed. + Ensure you go the GitHub page for the forked repo next and remove the remote branch you just pushed to it. -The term `Pull request` might sound a bit odd because you’re essentially pushing your changes to the project. However, the maintainer (project owner) or core team needs to review your changes before merging them into the project’s "main" branch. So, in reality, you’re requesting a decision from the maintainer to accept your changes. +`Pull request` seems like a silly term because really you want to push your changes to the project. But the maintainer (project owner) or core team needs to consider your changes before merging it with the project's "main" branch, so you're really requesting a change decision from a maintainer. -A pull request is a space where you can compare and discuss the differences introduced in a branch, with reviews, comments, integrated tests, and more. A good pull request follows similar rules to a commit message. You can also reference an issue in the issue tracker, especially if your work fixes a specific issue. To do this, use a `#` followed by the issue number, for example, `#97`. +A pull request is the place to compare and discuss the differences introduced on a branch with reviews, comments, integrated tests, and more. A good pull request follows roughly the same rules as a commit message. You can add a reference to an issue in the issue tracker, when your work for instance fixes an issue. This is done using a `#` followed by the number of your issue. For example `#97`. -🤞Fingers crossed that all checks pass and the project owner(s) merge your changes into the project 🤞 +🤞Fingers crossed that all checks pass and the project owner(s) merge your changes into the project🤞 Update your current local working branch with all new commits from the corresponding remote branch on GitHub: `git pull` -## How to contribute to open source +## Contributing to Open Source (Your Chance to Make an Impact!) -First, find a repository (or **repo**) on GitHub that interests you and to which you’d like to contribute. You’ll need to copy its contents to your machine. +Are you ready for something that's going to absolutely blow your mind? 🤯 Let's talk about contributing to open source projects – and I'm getting goosebumps just thinking about sharing this with you! -✅ A great way to find 'beginner-friendly' repositories is to [search by the tag 'good-first-issue'](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/). +This is your chance to become part of something truly extraordinary. Imagine improving the tools that millions of developers use every day, or fixing a bug in an app that your friends love. That's not just a dream – that's what open source contribution is all about! -![Copy a repo locally](../../../../translated_images/en/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.png) +Here's what gives me chills every time I think about it: every single tool you've been learning with – your code editor, the frameworks we'll explore, even the browser you're reading this in – started with someone exactly like you making their very first contribution. That brilliant developer who built your favorite VS Code extension? They were once a beginner clicking "create pull request" with shaky hands, just like you're about to do. -There are several ways to copy code. One way is to "clone" the repository’s contents using HTTPS, SSH, or the GitHub CLI (Command Line Interface). +And here's the most beautiful part: the open source community is like the internet's biggest group hug. Most projects actively look for newcomers and have issues tagged "good first issue" specifically for people like you! Maintainers genuinely get excited when they see new contributors because they remember their own first steps. -Open your terminal and clone the repository like this: -`git clone https://github.com/ProjectURL` +```mermaid +flowchart TD + A[🔍 Explore GitHub] --> B[🏷️ Find "good first issue"] + B --> C[📖 Read Contributing Guidelines] + C --> D[🍴 Fork Repository] + D --> E[💻 Set Up Local Environment] + E --> F[🌿 Create Feature Branch] + F --> G[✨ Make Your Contribution] + G --> H[🧪 Test Your Changes] + H --> I[📝 Write Clear Commit] + I --> J[📤 Push & Create PR] + J --> K[💬 Engage with Feedback] + K --> L[🎉 Merged! You're a Contributor!] + L --> M[🌟 Find Next Issue] + + style A fill:#e1f5fe + style L fill:#c8e6c9 + style M fill:#fff59d +``` +You're not just learning to code here – you're preparing to join a global family of builders who wake up every day thinking "How can we make the digital world a little bit better?" Welcome to the club! 🌟 -To start working on the project, navigate to the correct folder: +First, let's find a repository (or **repo**) on GitHub of interest to you and to which you'd like to contribute a change. You will want to copy its contents to your machine. + +✅ A good way to find 'beginner-friendly' repos is to [search by the tag 'good-first-issue'](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/). + +![Copy a repo locally](../../../../translated_images/en/clone_repo.5085c48d666ead57.webp) + +There are several ways of copying code. One way is to "clone" the contents of the repository, using HTTPS, SSH, or using the GitHub CLI (Command Line Interface). + +Open your terminal and clone the repository like so: +```bash +# Using HTTPS +git clone https://github.com/ProjectURL + +# Using SSH (requires SSH key setup) +git clone git@github.com:username/repository.git + +# Using GitHub CLI +gh repo clone username/repository +``` + +To work on the project, switch to the right folder: `cd ProjectURL` -You can also open the entire project using [Codespaces](https://github.com/features/codespaces), GitHub’s built-in code editor/cloud development environment, or [GitHub Desktop](https://desktop.github.com/). +You can also open the entire project using: +- **[GitHub Codespaces](https://github.com/features/codespaces)** - GitHub's cloud development environment with VS Code in the browser +- **[GitHub Desktop](https://desktop.github.com/)** - A GUI application for Git operations +- **[GitHub.dev](https://github.dev)** - Press the `.` key on any GitHub repo to open VS Code in the browser +- **VS Code** with the GitHub Pull Requests extension -Alternatively, you can download the code as a zipped folder. +Lastly, you can download the code in a zipped folder. ### A few more interesting things about GitHub -You can star, watch, and/or "fork" any public repository on GitHub. Your starred repositories can be found in the drop-down menu at the top-right corner. It’s like bookmarking, but for code. +You can star, watch and/or "fork" any public repository on GitHub. You can find your starred repositories in the top-right drop-down menu. It's like bookmarking, but for code. + +Projects have an issue tracker, mostly on GitHub in the "Issues" tab unless indicated otherwise, where people discuss issues related to the project. And the Pull Requests tab is where people discuss and review changes that are in progress. -Projects typically have an issue tracker, usually found in the "Issues" tab on GitHub unless stated otherwise. This is where people discuss project-related issues. The Pull Requests tab is where people discuss and review ongoing changes. +Projects might also have discussion in forums, mailing lists, or chat channels like Slack, Discord or IRC. -Projects may also have discussions in forums, mailing lists, or chat channels like Slack, Discord, or IRC. +🔧 **Modern GitHub features**: +- **GitHub Discussions** - Built-in forum for community conversations +- **GitHub Sponsors** - Support maintainers financially +- **Security tab** - Vulnerability reports and security advisories +- **Actions tab** - See automated workflows and CI/CD pipelines +- **Insights tab** - Analytics about contributors, commits, and project health +- **Projects tab** - GitHub's built-in project management tools -✅ Explore your new GitHub repository and try out a few features, like editing settings, adding information to your repo, and creating a project (like a Kanban board). There’s a lot to discover! +✅ Take a look around your new GitHub repo and try a few things, like editing settings, adding information to your repo, creating a project (like a Kanban board), and setting up GitHub Actions for automation. There's a lot you can do! --- ## 🚀 Challenge -Pair up with a friend to work on each other’s code. Collaboratively create a project, fork code, create branches, and merge changes. +Alright, it's time to put your shiny new GitHub superpowers to the test! 🚀 Here's a challenge that's going to make everything click in the most satisfying way: + +Grab a friend (or that family member who's always asking what you're up to with all this "computer stuff") and embark on a collaborative coding adventure together! This is where the real magic happens – create a project, let them fork it, make some branches, and merge changes like the pros you're becoming. + +I'm not gonna lie – you'll probably laugh at some point (especially when you both try to change the same line), maybe scratch your heads in confusion, but you'll definitely have those amazing "aha!" moments that make all the learning worth it. Plus, there's something special about sharing that first successful merge with someone else – it's like a tiny celebration of how far you've come! + +Don't have a coding buddy yet? No worries at all! The GitHub community is packed with incredibly welcoming people who remember what it was like to be new. Look for repositories with "good first issue" labels – they're basically saying "Hey beginners, come learn with us!" How awesome is that? ## Post-Lecture Quiz [Post-lecture quiz](https://ff-quizzes.netlify.app/web/en/) -## Review & Self Study +## Review & Keep Learning -Read more about [contributing to open source software](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution). +Whew! 🎉 Look at you – you've just conquered GitHub basics like an absolute champion! If your brain feels a little full right now, that's completely normal and honestly a good sign. You've just learned tools that took me weeks to feel comfortable with when I started. -[Git cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/). +Git and GitHub are incredibly powerful (like, seriously powerful), and every developer I know – including the ones who seem like wizards now – had to practice and stumble around a bit before it all clicked. The fact that you've made it through this lesson means you're already on your way to mastering some of the most important tools in a developer's toolkit. -Practice, practice, practice. GitHub offers excellent learning paths via [skills.github.com](https://skills.github.com): +Here are some absolutely fantastic resources to help you practice and become even more awesome: -- [First Week on GitHub](https://skills.github.com/#first-week-on-github) +- [Contributing to open source software guide](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution) – Your roadmap to making a difference +- [Git cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/) – Keep this handy for quick reference! -You’ll also find more advanced courses. +And remember: practice makes progress, not perfection! The more you use Git and GitHub, the more natural it becomes. GitHub has created some amazing interactive courses that let you practice in a safe environment: + +- [Introduction to GitHub](https://github.com/skills/introduction-to-github) +- [Communicate using Markdown](https://github.com/skills/communicate-using-markdown) +- [GitHub Pages](https://github.com/skills/github-pages) +- [Managing merge conflicts](https://github.com/skills/resolve-merge-conflicts) + +**Feeling adventurous? Check out these modern tools:** +- [GitHub CLI documentation](https://cli.github.com/manual/) – For when you want to feel like a command-line wizard +- [GitHub Codespaces documentation](https://docs.github.com/en/codespaces) – Code in the cloud! +- [GitHub Actions documentation](https://docs.github.com/en/actions) – Automate all the things +- [Git best practices](https://www.atlassian.com/git/tutorials/comparing-workflows) – Level up your workflow game + +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Create a collaborative web development project that demonstrates the complete GitHub workflow you've learned in this lesson. This challenge will help you practice repository creation, collaboration features, and modern Git workflows in a real-world scenario. + +**Prompt:** Create a new public GitHub repository for a simple "Web Development Resources" project. The repository should include a well-structured README.md file listing useful web development tools and resources, organized by categories (HTML, CSS, JavaScript, etc.). Set up the repository with proper community standards including a license, contributing guidelines, and a code of conduct. Create at least two feature branches: one for adding CSS resources and another for JavaScript resources. Make commits to each branch with descriptive commit messages, then create pull requests to merge the changes back to main. Enable GitHub features like Issues, Discussions, and set up a basic GitHub Actions workflow for automated checks. ## Assignment -Complete [the First Week on GitHub course](https://skills.github.com/#first-week-on-github) +Your mission, should you choose to accept it: Complete the [Introduction to GitHub](https://github.com/skills/introduction-to-github) course on GitHub Skills. This interactive course will let you practice everything you've learned in a safe, guided environment. Plus, you'll get a cool badge when you finish! 🏅 + +**Feeling ready for more challenges?** +- Set up SSH authentication for your GitHub account (no more passwords!) +- Try using GitHub CLI for your daily Git operations +- Create a repository with a GitHub Actions workflow +- Explore GitHub Codespaces by opening this very repository in a cloud-based editor + +--- + +## 🚀 Your GitHub Mastery Timeline + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Star this repository and 3 other projects that interest you +- [ ] Set up two-factor authentication on your GitHub account +- [ ] Create a simple README for your first repository +- [ ] Follow 5 developers whose work inspires you + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and reflect on your GitHub journey +- [ ] Set up SSH keys for password-free GitHub authentication +- [ ] Create your first meaningful commit with a great commit message +- [ ] Explore GitHub's "Explore" tab to discover trending projects +- [ ] Practice forking a repository and making a small change + +### 📅 **Your Week-Long GitHub Adventure** +- [ ] Complete the GitHub Skills courses (Introduction to GitHub, Markdown) +- [ ] Make your first pull request to an open source project +- [ ] Set up a GitHub Pages site to showcase your work +- [ ] Join GitHub Discussions on projects you're interested in +- [ ] Create a repository with proper community standards (README, License, etc.) +- [ ] Try GitHub Codespaces for cloud-based development + +### 🌟 **Your Month-Long Transformation** +- [ ] Contribute to 3 different open source projects +- [ ] Mentor someone new to GitHub (pay it forward!) +- [ ] Set up automated workflows with GitHub Actions +- [ ] Build a portfolio showcasing your GitHub contributions +- [ ] Participate in Hacktoberfest or similar community events +- [ ] Become a maintainer of your own project that others contribute to + +### 🎓 **Final GitHub Mastery Check-in** + +**Celebrate how far you've come:** +- What's your favorite thing about using GitHub? +- Which collaboration feature excites you most? +- How confident do you feel about contributing to open source now? +- What's the first project you want to contribute to? + +```mermaid +journey + title Your GitHub Confidence Journey + section Today + Nervous: 3: You + Curious: 4: You + Excited: 5: You + section This Week + Practicing: 4: You + Contributing: 5: You + Connecting: 5: You + section Next Month + Collaborating: 5: You + Leading: 5: You + Inspiring Others: 5: You +``` +> 🌍 **Welcome to the global developer community!** You now have the tools to collaborate with millions of developers worldwide. Your first contribution might seem small, but remember - every major open source project started with someone making their very first commit. The question isn't if you'll make an impact, but what amazing project will benefit from your unique perspective first! 🚀 + +Remember: every expert was once a beginner. You've got this! 💪 --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/1-getting-started-lessons/3-accessibility/README.md b/translations/en/1-getting-started-lessons/3-accessibility/README.md index bcbb26336..47cea7dae 100644 --- a/translations/en/1-getting-started-lessons/3-accessibility/README.md +++ b/translations/en/1-getting-started-lessons/3-accessibility/README.md @@ -1,17 +1,24 @@ - # Creating Accessible Webpages -![All About Accessibility](../../../../translated_images/en/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.png) +![All About Accessibility](../../../../translated_images/en/webdev101-a11y.8ef3025c858d897a.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) +```mermaid +journey + title Your Accessibility Learning Adventure + section Foundation + Understanding Users: 5: You + Testing Tools: 4: You + POUR Principles: 5: You + section Build Skills + Semantic HTML: 4: You + Visual Design: 5: You + ARIA Techniques: 4: You + section Master Practice + Keyboard Navigation: 5: You + Form Accessibility: 4: You + Real-world Testing: 5: You +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/) @@ -19,225 +26,1466 @@ CO_OP_TRANSLATOR_METADATA: > > \- Sir Timothy Berners-Lee, W3C Director and inventor of the World Wide Web -This quote perfectly captures the importance of building accessible websites. An application that excludes certain users is inherently discriminatory. As web developers, we should always prioritize accessibility. By focusing on it from the start, you'll be well on your way to ensuring that everyone can access the pages you create. In this lesson, you'll learn about tools that can help you ensure your web assets are accessible and how to design with accessibility in mind. - +Here's something that might surprise you: when you build accessible websites, you're not just helping people with disabilities—you're actually making the web better for everyone! + +Ever notice those curb cuts at street corners? They were originally designed for wheelchairs, but now they help people with strollers, delivery workers with dollies, travelers with rolling luggage, and cyclists too. That's exactly how accessible web design works—solutions that help one group often end up benefiting everyone. Pretty cool, right? + +In this lesson, we're going to explore how to create websites that truly work for everyone, no matter how they browse the web. You'll discover practical techniques that are already built into web standards, get hands-on with testing tools, and see how accessibility makes your sites more usable for all users. + +By the end of this lesson, you'll have the confidence to make accessibility a natural part of your development workflow. Ready to explore how thoughtful design choices can open up the web to billions of users? Let's dive in! + +```mermaid +mindmap + root((Web Accessibility)) + Users + Screen readers + Keyboard navigation + Voice control + Magnification + Technologies + HTML semantics + ARIA attributes + CSS focus indicators + Keyboard events + Benefits + Wider audience + Better SEO + Legal compliance + Universal design + Testing + Automated tools + Manual testing + User feedback + Real assistive tech +``` > You can take this lesson on [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon)! -## Tools to use +## Understanding Assistive Technologies + +Before we jump into coding, let's take a moment to understand how people with different abilities actually experience the web. This isn't just theory—understanding these real-world navigation patterns will make you a much better developer! + +Assistive technologies are pretty amazing tools that help people with disabilities interact with websites in ways that might surprise you. Once you get the hang of how these technologies work, creating accessible web experiences becomes way more intuitive. It's like learning to see your code through someone else's eyes. ### Screen readers -Screen readers are among the most well-known accessibility tools. +[Screen readers](https://en.wikipedia.org/wiki/Screen_reader) are pretty sophisticated pieces of technology that convert digital text into speech or braille output. While they're primarily used by people with visual impairments, they're also super helpful for users with learning disabilities like dyslexia. + +I like to think of a screen reader as having a really smart narrator reading a book to you. It reads content aloud in a logical order, announces interactive elements like "button" or "link," and provides keyboard shortcuts for jumping around a page. But here's the thing—screen readers can only work their magic if we build websites with proper structure and meaningful content. That's where you come in as a developer! + +**Popular screen readers across platforms:** +- **Windows**: [NVDA](https://www.nvaccess.org/about-nvda/) (free and most popular), [JAWS](https://webaim.org/articles/jaws/), [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) (built-in) +- **macOS/iOS**: [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) (built-in and very capable) +- **Android**: [TalkBack](https://support.google.com/accessibility/android/answer/6283677) (built-in) +- **Linux**: [Orca](https://wiki.gnome.org/Projects/Orca) (free and open-source) + +**How screen readers navigate web content:** + +Screen readers provide multiple navigation methods that make browsing efficient for experienced users: +- **Sequential reading**: Reads content from top to bottom, like following a book +- **Landmark navigation**: Jump between page sections (header, nav, main, footer) +- **Heading navigation**: Skip between headings to understand page structure +- **Link lists**: Generate a list of all links for quick access +- **Form controls**: Navigate directly between input fields and buttons + +> 💡 **Here's something that blew my mind**: 68% of screen reader users navigate primarily by headings ([WebAIM Survey](https://webaim.org/projects/screenreadersurvey9/#finding)). This means your heading structure is like a roadmap for users—when you get it right, you're literally helping people find their way around your content faster! + +### Building your testing workflow + +Here's some good news—effective accessibility testing doesn't have to be overwhelming! You'll want to combine automated tools (they're fantastic at catching obvious issues) with some hands-on testing. Here's a systematic approach that I've found catches the most issues without eating up your entire day: + +**Essential manual testing workflow:** + +```mermaid +flowchart TD + A[🚀 Start Testing] --> B{⌨️ Keyboard Navigation} + B --> C[Tab through all interactive elements] + C --> D{🎧 Screen Reader Testing} + D --> E[Test with NVDA/VoiceOver] + E --> F{🔍 Zoom Testing} + F --> G[Zoom to 200% and test functionality] + G --> H{🎨 Color/Contrast Check} + H --> I[Verify all text meets contrast ratios] + I --> J{👁️ Focus Management} + J --> K[Ensure focus indicators are visible] + K --> L[✅ Testing Complete] + + style A fill:#e3f2fd + style L fill:#e8f5e8 + style B fill:#fff3e0 + style D fill:#f3e5f5 + style F fill:#e0f2f1 + style H fill:#fce4ec + style J fill:#e8eaf6 +``` +**Step-by-step testing checklist:** +1. **Keyboard navigation**: Use only Tab, Shift+Tab, Enter, Space, and Arrow keys +2. **Screen reader testing**: Enable NVDA, VoiceOver, or Narrator and navigate with eyes closed +3. **Zoom testing**: Test at 200% and 400% zoom levels +4. **Color contrast verification**: Check all text and UI components +5. **Focus indicator testing**: Ensure all interactive elements have visible focus states -[Screen readers](https://en.wikipedia.org/wiki/Screen_reader) are commonly used by individuals with vision impairments. Just as we ensure browsers display information correctly, we must also ensure screen readers convey the same information accurately. +✅ **Start with Lighthouse**: Open your browser's DevTools, run a Lighthouse accessibility audit, then use the results to guide your manual testing focus areas. -At their core, screen readers audibly read a page from top to bottom. If your page is entirely text, the reader will present the information similarly to a browser. However, web pages often include links, images, colors, and other visual elements. Care must be taken to ensure this information is conveyed correctly by a screen reader. +### Zoom and magnification tools -Every web developer should become familiar with screen readers. Just as you understand how browsers work, you should also learn how screen readers operate. Fortunately, most operating systems come with built-in screen readers. +You know how you sometimes pinch to zoom on your phone when text is too small, or squint at your laptop screen in bright sunlight? Many users rely on magnification tools to make content readable every single day. This includes people with low vision, older adults, and anyone who's ever tried to read a website outdoors. -Some browsers also include tools and extensions that can read text aloud or provide basic navigation features, such as [these accessibility-focused Edge browser tools](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). While useful, these tools function differently from screen readers and should not be used as substitutes for screen reader testing. +Modern zoom technologies have evolved beyond just making things bigger. Understanding how these tools work will help you create responsive designs that remain functional and attractive at any magnification level. -✅ Try a screen reader and browser text reader. On Windows, [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) is included by default, and [JAWS](https://webaim.org/articles/jaws/) and [NVDA](https://www.nvaccess.org/about-nvda/) can also be installed. On macOS and iOS, [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) is pre-installed. +**Modern browser zoom capabilities:** +- **Page zoom**: Scales all content proportionally (text, images, layout) - this is the preferred method +- **Text-only zoom**: Increases font size while maintaining original layout +- **Pinch-to-zoom**: Mobile gesture support for temporary magnification +- **Browser support**: All modern browsers support zoom up to 500% without breaking functionality -### Zoom +**Specialized magnification software:** +- **Windows**: [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) (built-in), [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) +- **macOS/iOS**: [Zoom](https://www.apple.com/accessibility/mac/vision/) (built-in with advanced features) -Zooming is another tool frequently used by individuals with vision impairments. +> ⚠️ **Design Consideration**: WCAG requires that content remain functional when zoomed to 200%. At this level, horizontal scrolling should be minimal, and all interactive elements should remain accessible. -The simplest form of zooming is static zoom, which can be controlled using `Control + plus sign (+)` or by lowering the screen resolution. This type of zoom enlarges the entire page, so using [responsive design](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) is essential to ensure a good user experience at higher zoom levels. +✅ **Test your responsive design**: Zoom your browser to 200% and 400%. Does your layout adapt gracefully? Can you still access all functionality without excessive scrolling? -Another type of zoom involves specialized software that magnifies specific areas of the screen and allows panning, similar to using a magnifying glass. On Windows, [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) is built in, while [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) is a third-party magnification tool with additional features and a larger user base. Both macOS and iOS include a built-in magnification tool called [Zoom](https://www.apple.com/accessibility/mac/vision/). +## Modern Accessibility Testing Tools -### Contrast checkers +Now that you understand how people navigate the web with assistive technologies, let's explore the tools that help you build and test accessible websites. -Colors on websites must be chosen carefully to accommodate users who are color-blind or have difficulty perceiving low-contrast colors. +Think of it like this: automated tools are great at catching obvious issues (like missing alt text), while hands-on testing helps you ensure your site feels good to use in the real world. Together, they give you confidence that your sites work for everyone. -✅ Test a website you enjoy using for its color choices with a browser extension like [WCAG's color checker](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon). What do you learn? +### Color contrast testing -### Lighthouse +Here's some good news: color contrast is one of the most common accessibility issues, but it's also one of the easiest to fix. Good contrast benefits everyone—from users with visual impairments to people trying to read their phones at the beach. -Your browser's developer tools include the Lighthouse tool, which provides an initial analysis of a website's accessibility (along with other metrics). While you shouldn't rely solely on Lighthouse, achieving a 100% score is a helpful starting point. +**WCAG contrast requirements:** -✅ Open Lighthouse in your browser's developer tools and analyze any website. What do you discover? +| Text Type | WCAG AA (Minimum) | WCAG AAA (Enhanced) | +|-----------|-------------------|---------------------| +| **Normal text** (under 18pt) | 4.5:1 contrast ratio | 7:1 contrast ratio | +| **Large text** (18pt+ or 14pt+ bold) | 3:1 contrast ratio | 4.5:1 contrast ratio | +| **UI components** (buttons, form borders) | 3:1 contrast ratio | 3:1 contrast ratio | -## Designing for accessibility +**Essential testing tools:** +- [Colour Contrast Analyser](https://www.tpgi.com/color-contrast-checker/) - Desktop app with color picker +- [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/) - Web-based with instant feedback +- [Stark](https://www.getstark.co/) - Design tool plugin for Figma, Sketch, Adobe XD +- [Accessible Colors](https://accessible-colors.com/) - Find accessible color palettes -Accessibility is a broad topic, but there are many resources available to help you. +✅ **Build better color palettes**: Start with your brand colors and use contrast checkers to create accessible variations. Document these as your design system's accessible color tokens. -- [Accessible U - University of Minnesota](https://accessibility.umn.edu/your-role/web-developers) +### Comprehensive accessibility auditing -While we can't cover every aspect of creating accessible websites, the following are some core principles to implement. Designing an accessible page from the beginning is **always** easier than retrofitting an existing page. +The most effective accessibility testing combines multiple approaches. No single tool catches everything, so building a testing routine with various methods ensures thorough coverage. -## Good display principles +**Browser-based testing (built into DevTools):** +- **Chrome/Edge**: Lighthouse accessibility audit + Accessibility panel +- **Firefox**: Accessibility Inspector with detailed tree view +- **Safari**: Audit tab in Web Inspector with VoiceOver simulation -### Color-safe palettes +**Professional testing extensions:** +- [axe DevTools](https://www.deque.com/axe/devtools/) - Industry-standard automated testing +- [WAVE](https://wave.webaim.org/extension/) - Visual feedback with error highlighting +- [Accessibility Insights](https://accessibilityinsights.io/) - Microsoft's comprehensive testing suite -People perceive colors differently. When choosing a color scheme for your site, ensure it's accessible to everyone. A great [tool for generating color palettes is Color Safe](http://colorsafe.co/). +**Command-line and CI/CD integration:** +- [axe-core](https://github.com/dequelabs/axe-core) - JavaScript library for automated testing +- [Pa11y](https://pa11y.org/) - Command-line accessibility testing tool +- [Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci) - Automated accessibility scoring -✅ Identify a website with problematic color usage. Why is it an issue? +> 🎯 **Testing Goal**: Aim for a Lighthouse accessibility score of 95+ as your baseline. Remember, automated tools only catch about 30-40% of accessibility issues—manual testing is still essential! -### Use the correct HTML +### 🧠 **Testing Skills Check: Ready to Find Issues?** -With CSS and JavaScript, you can make any element look like any type of control. For example, a `` could be styled to look like a ` + + +
+

Latest News

+ +
+ + + +
+ Password must contain at least 8 characters, including uppercase, lowercase, and numbers. +
+
+ +
+``` + +**Live regions for dynamic content:** + +```html + +
+ +
+ + +
+ +
+ + + +
+ +
+``` + +**Interactive widget example (accordion):** + +```html +
+

+ +

+ +
+``` + +```javascript +// JavaScript to manage accordion state +function toggleAccordion(trigger) { + const panel = document.getElementById(trigger.getAttribute('aria-controls')); + const isExpanded = trigger.getAttribute('aria-expanded') === 'true'; + + // Toggle states + trigger.setAttribute('aria-expanded', !isExpanded); + panel.hidden = isExpanded; + + // Announce change to screen readers + const status = document.getElementById('status-updates'); + status.textContent = isExpanded ? 'Section collapsed' : 'Section expanded'; +} +``` + +### ARIA implementation best practices + +ARIA is powerful but requires careful implementation. Following these guidelines helps ensure your ARIA enhances rather than hinders accessibility: + +**🛡️ Core principles:** + +```mermaid +flowchart TD + A[🚀 Start with semantic HTML] --> B{Does HTML provide needed semantics?} + B -->|Yes| C[✅ Use HTML only] + B -->|No| D[Consider ARIA enhancement] + D --> E{Can you achieve it with simpler means?} + E -->|Yes| F[🔄 Simplify approach] + E -->|No| G[📝 Implement ARIA carefully] + G --> H[🧪 Test with real AT] + H --> I{Works as expected?} + I -->|No| J[🔧 Debug and fix] + I -->|Yes| K[✅ Success!] + J --> H + F --> C + + style A fill:#e3f2fd + style C fill:#e8f5e8 + style K fill:#e8f5e8 + style G fill:#fff3e0 + style H fill:#f3e5f5 +``` +1. **Semantic HTML first**: Always prefer ` +``` + +**Complex images** - charts, diagrams, infographics: +```html +Quarterly sales data +
+

Detailed description: Sales data shows a steady increase across all quarters...

+
+``` + +### Video and audio accessibility + +**Video requirements:** +- **Captions**: Text version of spoken content and sound effects +- **Audio descriptions**: Narration of visual elements for blind users +- **Transcripts**: Full text version of all audio and visual content + +```html + +``` + +**Audio requirements:** +- **Transcripts**: Text version of all spoken content +- **Visual indicators**: For audio-only content, provide visual cues + +### Modern image techniques + +**Using CSS for decorative images:** +```css +.hero-section { + background-image: url('decorative-hero.jpg'); + /* Decorative images in CSS don't need alt text */ +} +``` + +**Responsive images with accessibility:** +```html + + + + Website traffic increased 40% after accessibility improvements + +``` + +✅ **Test image accessibility**: Use a screen reader to navigate a page with images. Are you getting enough information to understand the content? + +## Keyboard navigation and focus management + +Many users navigate the web entirely with their keyboards. This includes people with motor disabilities, power users who find keyboards faster than mice, and anyone whose mouse has stopped working. Making sure your site works well with keyboard input is essential and often makes your site more efficient for everyone. + +```mermaid +flowchart LR + A[⌨️ Keyboard Navigation] --> B[Tab Order] + A --> C[Focus Indicators] + A --> D[Skip Links] + A --> E[Keyboard Shortcuts] + + B --> B1[Logical sequence
All interactive elements
No tab traps] + C --> C1[Visible outlines
High contrast
Clear boundaries] + D --> D1[Skip to main
Skip to nav
Bypass repetitive] + E --> E1[Escape to close
Enter to activate
Arrows in groups] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 +``` +### Essential keyboard navigation patterns + +**Standard keyboard interactions:** +- **Tab**: Move focus forward through interactive elements +- **Shift + Tab**: Move focus backward +- **Enter**: Activate buttons and links +- **Space**: Activate buttons, check checkboxes +- **Arrow keys**: Navigate within component groups (radio buttons, menus) +- **Escape**: Close modals, dropdowns, or cancel operations + +### Focus management best practices + +**Visible focus indicators:** +```css +/* Ensure focus is always visible */ +button:focus-visible { + outline: 2px solid #4A90A4; + outline-offset: 2px; +} + +/* Custom focus styles for different components */ +.card:focus-within { + box-shadow: 0 0 0 3px rgba(74, 144, 164, 0.5); +} +``` + +**Skip links for efficient navigation:** +```html + + + + +
+ +
+``` + +**Proper tab order:** +```html + +
+ + + + + + + +
+``` + +### Focus trapping in modals + +When opening modal dialogs, focus should be trapped within the modal: + +```javascript +// Modern focus trap implementation +function trapFocus(element) { + const focusableElements = element.querySelectorAll( + 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' + ); + + const firstElement = focusableElements[0]; + const lastElement = focusableElements[focusableElements.length - 1]; + + element.addEventListener('keydown', (e) => { + if (e.key === 'Tab') { + if (e.shiftKey && document.activeElement === firstElement) { + e.preventDefault(); + lastElement.focus(); + } else if (!e.shiftKey && document.activeElement === lastElement) { + e.preventDefault(); + firstElement.focus(); + } + } + + if (e.key === 'Escape') { + closeModal(); + } + }); + + // Focus the first element when the modal opens + firstElement.focus(); +} +``` + +✅ **Test keyboard navigation**: Try navigating your website using only the Tab key. Can you reach all interactive elements? Is the focus order logical? Are focus indicators clearly visible? + +## Form accessibility + +Forms are critical for user interaction and require special attention to accessibility. + +### Label and form control association + +**Every form control needs a label:** +```html + + + + + + + + + +``` + +### Error handling and validation + +**Accessible error messages:** +```html + + + +``` + +**Form validation best practices:** +- Use `aria-invalid` to indicate invalid fields +- Provide clear, specific error messages +- Use `role="alert"` for important error announcements +- Show errors both immediately and on form submission + +### Fieldsets and grouping + +**Group related form controls:** +```html +
+ Shipping Address + + + + + +
+ +
+ Preferred Contact Method + + + + + +
+``` + +## Your Accessibility Journey: Key Takeaways + +Congratulations! You've just gained the foundational knowledge to create truly inclusive web experiences. This is pretty exciting stuff! Web accessibility isn't just about checking compliance boxes—it's about recognizing the diverse ways people interact with digital content and designing for that amazing complexity. + +You're now part of a growing community of developers who understand that great design works for everyone. Welcome to the club! + +**🎯 Your accessibility toolkit now includes:** + +| Core Principle | Implementation | Impact | +|----------------|----------------|---------| +| **Semantic HTML Foundation** | Use proper HTML elements for their intended purpose | Screen readers can navigate efficiently, keyboards work automatically | +| **Inclusive Visual Design** | Sufficient contrast, meaningful color use, visible focus indicators | Clear for everyone in any lighting condition | +| **Descriptive Content** | Meaningful link text, alt text, headings | Users understand content without visual context | +| **Keyboard Accessibility** | Tab order, keyboard shortcuts, focus management | Motor accessibility and power user efficiency | +| **ARIA Enhancement** | Strategic use to fill semantic gaps | Complex applications work with assistive technologies | +| **Comprehensive Testing** | Automated tools + manual verification + real user testing | Catch issues before they impact users | + +**🚀 Your next steps:** + +1. **Build accessibility into your workflow**: Make testing a natural part of your development process +2. **Learn from real users**: Seek out feedback from people who use assistive technologies +3. **Stay current**: Accessibility techniques evolve with new technologies and standards +4. **Advocate for inclusion**: Share your knowledge and make accessibility a team priority + +> 💡 **Remember**: Accessibility constraints often lead to innovative, elegant solutions that benefit everyone. Curb cuts, captions, and voice controls all started as accessibility features and became mainstream improvements. + +**The business case is crystal clear**: Accessible websites reach more users, rank better in search engines, have lower maintenance costs, and avoid legal risks. But honestly? The real reason to care about accessibility goes so much deeper. Accessible websites embody the best values of the web—openness, inclusivity, and the idea that everyone deserves equal access to information. + +You're now equipped to build the inclusive web of the future. Every accessible site you create makes the internet a more welcoming place for everyone. That's pretty amazing when you think about it! + +## Additional Resources + +Continue your accessibility learning journey with these essential resources: + +**📚 Official Standards and Guidelines:** +- [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/) - The official accessibility standard with quick reference +- [ARIA Authoring Practices Guide](https://w3c.github.io/aria-practices/) - Comprehensive patterns for interactive widgets +- [WebAIM Guidelines](https://webaim.org/) - Practical, beginner-friendly accessibility guidance + +**🛠️ Tools and Testing Resources:** +- [axe DevTools](https://www.deque.com/axe/devtools/) - Industry-standard accessibility testing +- [A11y Project Checklist](https://www.a11yproject.com/checklist/) - Step-by-step accessibility verification +- [Accessibility Insights](https://accessibilityinsights.io/) - Microsoft's comprehensive testing suite +- [Color Oracle](https://colororacle.org/) - Color blindness simulator for design testing + +**🎓 Learning and Community:** +- [WebAIM Screen Reader Survey](https://webaim.org/projects/screenreadersurvey9/) - Real user preferences and behaviors +- [Inclusive Components](https://inclusive-components.design/) - Modern accessible component patterns +- [A11y Coffee](https://a11y.coffee/) - Quick accessibility tips and insights +- [Web Accessibility Initiative (WAI)](https://www.w3.org/WAI/) - W3C's comprehensive accessibility resources + +**🎥 Hands-on Learning:** +- [Accessibility Developer Guide](https://www.accessibility-developer-guide.com/) - Practical implementation guidance +- [Deque University](https://dequeuniversity.com/) - Professional accessibility training courses + +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Create an accessible modal dialog component that demonstrates proper focus management, ARIA attributes, and keyboard navigation patterns. + +**Prompt:** Build a complete modal dialog component with HTML, CSS, and JavaScript that includes: proper focus trapping, ESC key to close, click outside to close, ARIA attributes for screen readers, and visible focus indicators. The modal should contain a form with proper labels and error handling. Ensure the component meets WCAG 2.1 AA standards. ---- ## 🚀 Challenge -Take this HTML and rewrite it to be as accessible as possible, using the strategies you've learned. +Take this HTML and rewrite it to be as accessible as possible, given the strategies you learned. ```html - + - - Example - + + + Turtle Ipsum - The World's Premier Turtle Fan Club - - -
-
-

Welcome to Turtle Ipsum. - Click here to learn more. + + +

+ +
+
+

Welcome to Turtle Ipsum

+

+ Learn more about our turtle community and discover fascinating facts about these amazing creatures.

- Turtle ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum -

-
-
- + + + +
+ + + + + +
``` +**Key improvements made:** +- Added proper semantic HTML structure +- Fixed heading hierarchy (single h1, logical progression) +- Added meaningful link text instead of "click here" +- Included proper ARIA labels for navigation +- Added lang attribute and proper meta tags +- Used button element for interactive elements +- Structured footer content with proper landmarks + ## Post-Lecture Quiz [Post-lecture quiz](https://ff-quizzes.netlify.app/web/en/) ## Review & Self Study -Many governments have laws related to accessibility requirements. Research the accessibility laws in your country. What aspects are included, and what are not? An example is [this government website](https://accessibility.blog.gov.uk/). -## Assignment +Many governments have laws regarding accessibility requirements. Read up on your home country's accessibility laws. What is covered, and what isn't? An example is [this government web site](https://accessibility.blog.gov.uk/). -[Analyze a non-accessible website](assignment.md) +## Assignment + +[Analyze a non-accessible web site](assignment.md) Credits: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) by Instrument --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file +## 🚀 Your Accessibility Mastery Timeline + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Install axe DevTools extension in your browser +- [ ] Run a Lighthouse accessibility audit on your favorite website +- [ ] Try navigating any website using only the Tab key +- [ ] Test your browser's built-in screen reader (Narrator/VoiceOver) + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and reflect on accessibility insights +- [ ] Practice writing meaningful alt text for 10 different images +- [ ] Audit a website's heading structure using HeadingsMap extension +- [ ] Fix accessibility issues found in the challenge HTML +- [ ] Test color contrast on your current project with WebAIM's tool + +### 📅 **Your Week-Long Accessibility Journey** +- [ ] Complete the assignment analyzing a non-accessible website +- [ ] Set up your development environment with accessibility testing tools +- [ ] Practice keyboard navigation on 5 different complex websites +- [ ] Build a simple form with proper labels, error handling, and ARIA +- [ ] Join an accessibility community (A11y Slack, WebAIM forum) +- [ ] Watch real users with disabilities navigate websites (YouTube has great examples) + +### 🌟 **Your Month-Long Transformation** +- [ ] Integrate accessibility testing into your development workflow +- [ ] Contribute to an open source project by fixing accessibility issues +- [ ] Conduct usability testing with someone who uses assistive technology +- [ ] Build an accessible component library for your team +- [ ] Advocate for accessibility in your workplace or community +- [ ] Mentor someone new to accessibility concepts + +### 🏆 **Final Accessibility Champion Check-in** + +**Celebrate your accessibility journey:** +- What's the most surprising thing you learned about how people use the web? +- Which accessibility principle resonates most with your development style? +- How has learning about accessibility changed your perspective on design? +- What's the first accessibility improvement you want to make on a real project? + +```mermaid +journey + title Your Accessibility Confidence Evolution + section Today + Overwhelmed: 3: You + Curious: 4: You + Motivated: 5: You + section This Week + Practicing: 4: You + Testing: 5: You + Understanding: 5: You + section Next Month + Advocating: 5: You + Leading: 5: You + Inclusive by Default: 5: You +``` +> 🌍 **You're now an accessibility champion!** You understand that great web experiences work for everyone, regardless of how they access the web. Every accessible feature you build makes the internet more inclusive. The web needs developers like you who see accessibility not as a constraint, but as an opportunity to create better experiences for all users. Welcome to the movement! 🎉 + +--- + + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/1-getting-started-lessons/3-accessibility/assignment.md b/translations/en/1-getting-started-lessons/3-accessibility/assignment.md index 7287a3a2a..100014acb 100644 --- a/translations/en/1-getting-started-lessons/3-accessibility/assignment.md +++ b/translations/en/1-getting-started-lessons/3-accessibility/assignment.md @@ -1,29 +1,252 @@ - -# Analyze an inaccessible site +# Comprehensive Website Accessibility Audit ## Instructions -Identify a website that you believe is NOT accessible and create an action plan to enhance its accessibility. -Your first step is to identify this site, describe the ways in which you think it is inaccessible without using analytical tools, and then run a Lighthouse analysis on it. Save a PDF of the analysis results and create a detailed plan with at least ten points explaining how the site can be improved. +In this assignment, you'll conduct a professional-level accessibility audit of a real website, applying the principles and techniques you've learned. This hands-on experience will deepen your understanding of accessibility barriers and solutions. -## Table to test site accessibility +Choose a website that appears to have accessibility issues—this gives you more learning opportunities than analyzing an already-perfect site. Good candidates include older websites, complex web applications, or sites with rich multimedia content. -| Criteria | Exemplary | Adequate | Needs Improvement | -|----------|-----------|----------|-------------------| -| | missing <10% of what is required | missing 20% of what is required | missing 50% of what is required | +### Phase 1: Strategic manual evaluation ----- -Student Report: includes paragraphs describing how inaccessible the site is, the Lighthouse report saved as a PDF, a list of ten improvement points, and detailed explanations on how to implement them. +Before reaching for automated tools, perform a comprehensive manual assessment. This human-centered approach often reveals issues that tools miss and helps you understand the real user experience. + +**🔍 Essential evaluation criteria:** + +**Navigation and Structure:** +- Can you navigate the entire site using only keyboard (Tab, Shift+Tab, Enter, Space, Arrow keys)? +- Are focus indicators clearly visible on all interactive elements? +- Does the heading structure (H1-H6) create a logical content outline? +- Are there skip links to jump to main content? + +**Visual Accessibility:** +- Is there sufficient color contrast throughout the site (minimum 4.5:1 for normal text)? +- Does the site rely solely on color to convey important information? +- Do all images have appropriate alternative text? +- Does the layout remain functional when zoomed to 200%? + +**Content and Communication:** +- Are there any "click here" or ambiguous link texts? +- Can you understand the content and functionality without visual cues? +- Are form fields properly labeled and grouped? +- Are error messages clear and helpful? + +**Interactive Elements:** +- Do all buttons and form controls work with keyboard alone? +- Are dynamic content changes announced to screen readers? +- Do modal dialogs and complex widgets follow proper accessibility patterns? + +📝 **Document your findings** with specific examples, screenshots, and page URLs. Note both issues and things done well. + +### Phase 2: Comprehensive automated testing + +Now validate and expand your manual findings using industry-standard accessibility testing tools. Each tool has different strengths, so using multiple tools gives you complete coverage. + +**🛠️ Required testing tools:** + +1. **Lighthouse Accessibility Audit** (built into Chrome/Edge DevTools) + - Run audit on multiple pages + - Focus on specific metrics and recommendations + - Note your accessibility score and specific violations + +2. **axe DevTools** (browser extension - industry standard) + - More detailed issue detection than Lighthouse + - Provides specific code examples for fixes + - Tests against WCAG 2.1 criteria + +3. **WAVE Web Accessibility Evaluator** (browser extension) + - Visual representation of accessibility features + - Highlights both errors and positive features + - Great for understanding page structure + +4. **Color Contrast Analyzers** + - WebAIM Contrast Checker for specific color pairs + - Browser extensions for page-wide analysis + - Test against both WCAG AA and AAA standards + +**🎧 Real assistive technology testing:** +- **Screen reader testing**: Use NVDA (Windows), VoiceOver (Mac), or TalkBack (Android) +- **Keyboard-only navigation**: Unplug your mouse and navigate the entire site +- **Zoom testing**: Test functionality at 200% and 400% zoom levels +- **Voice control testing**: If available, try voice navigation tools + +**📊 Organize your results** by creating a master spreadsheet with: +- Issue description and location +- Severity level (Critical/High/Medium/Low) +- WCAG success criteria violated +- Tool that detected the issue +- Screenshots and evidence + +### Phase 3: Comprehensive findings documentation + +Create a professional accessibility audit report that demonstrates your understanding of both technical issues and their human impact. + +**📋 Required report sections:** + +1. **Executive Summary** (1 page) + - Website URL and brief description + - Overall accessibility maturity level + - Top 3 most critical issues + - Estimated impact on users with disabilities + +2. **Methodology** (½ page) + - Testing approach and tools used + - Pages evaluated and device/browser combinations + - Standards evaluated against (WCAG 2.1 AA) + +3. **Detailed Findings** (2-3 pages) + - Issues categorized by WCAG principle (Perceivable, Operable, Understandable, Robust) + - Include screenshots and specific examples + - Note positive accessibility features you found + - Cross-reference with automated tool results + +4. **User Impact Assessment** (1 page) + - How identified issues affect users with different disabilities + - Scenarios describing real user experiences + - Business impact (legal risk, SEO, user base expansion) + +**📸 Evidence collection:** +- Screenshots of accessibility violations +- Screen recordings of problematic user flows +- Tool reports (save as PDFs) +- Code examples showing issues + +### Phase 4: Professional remediation plan + +Develop a strategic, prioritized plan for fixing accessibility issues. This demonstrates your ability to think like a professional web developer addressing real business constraints. + +**🎯 Create detailed improvement recommendations (minimum 10 issues):** + +**For each identified issue, provide:** + +- **Issue Description**: Clear explanation of what's wrong and why it's problematic +- **WCAG Reference**: Specific success criteria violated (e.g., "2.4.4 Link Purpose (In Context) - Level A") +- **User Impact**: How this affects people with different disabilities +- **Solution**: Specific code changes, design modifications, or process improvements +- **Priority Level**: Critical (blocks basic usage) / High (significant barrier) / Medium (usability issue) / Low (enhancement) +- **Implementation Effort**: Time/complexity estimate (Quick win / Moderate effort / Major refactor) +- **Testing Verification**: How to verify the fix works + +**Example improvement entry:** + +``` +Issue: Generic "Read more" link text appears 8 times on homepage +WCAG Reference: 2.4.4 Link Purpose (In Context) - Level A +User Impact: Screen reader users cannot distinguish between links when viewed in link list +Solution: Replace with descriptive text like "Read more about sustainability initiatives" +Priority: High (major navigation barrier) +Effort: Low (30 minutes to update content) +Testing: Generate link list with screen reader - each link should be meaningful standalone +``` + +**📈 Strategic implementation phases:** + +- **Phase 1 (0-2 weeks)**: Critical issues that block basic functionality +- **Phase 2 (1-2 months)**: High-priority improvements for better user experience +- **Phase 3 (3-6 months)**: Medium-priority enhancements and process improvements +- **Phase 4 (Ongoing)**: Continuous monitoring and enhancement + +## Evaluation Rubric + +Your accessibility audit will be assessed on both technical accuracy and professional presentation: + +| Criteria | Excellent (90-100%) | Good (80-89%) | Satisfactory (70-79%) | Needs Improvement (<70%) | +|----------|-------------------|---------------|---------------------|------------------------| +| **Manual Testing Depth** | Comprehensive evaluation covering all POUR principles with detailed observations and user scenarios | Good coverage of most accessibility areas with clear findings and some user impact analysis | Basic evaluation covering key areas with adequate observations | Limited testing with superficial observations and minimal user impact consideration | +| **Tool Utilization & Analysis** | Uses all required tools effectively, cross-references findings, includes clear evidence, and analyzes tool limitations | Uses most tools with good documentation, some cross-referencing, and adequate evidence | Uses required tools with basic documentation and some evidence | Minimal tool usage, poor documentation, or missing evidence | +| **Issue Identification & Categorization** | Identifies 15+ specific issues across all WCAG principles, accurately categorizes by severity, demonstrates deep understanding | Identifies 10-14 issues across most WCAG principles, good categorization, shows solid understanding | Identifies 7-9 issues with adequate WCAG coverage and basic categorization | Identifies <7 issues with limited scope or poor categorization | +| **Solution Quality & Feasibility** | 10+ detailed, actionable solutions with accurate WCAG references, realistic implementation timelines, and verification methods | 8-9 well-developed solutions with mostly accurate references and good implementation details | 6-7 basic solutions with some detail and generally realistic approaches | <6 solutions or insufficient detail, unrealistic implementations | +| **Professional Communication** | Report is excellently organized, clearly written, includes executive summary, uses appropriate technical language, and follows business document standards | Well-organized with good writing quality, includes most required sections, appropriate tone | Adequately organized with acceptable writing, includes basic required sections | Poor organization, unclear writing, or missing key sections | +| **Real-World Application** | Demonstrates understanding of business impact, legal considerations, user diversity, and practical implementation challenges | Shows good understanding of practical applications with some business context | Basic understanding of real-world applications | Limited connection to practical applications | + +## Advanced Challenge Options + +**🚀 For students seeking additional challenge:** + +- **Comparative Analysis**: Audit 2-3 competing websites and compare their accessibility maturity +- **Mobile Accessibility Focus**: Deep dive into mobile-specific accessibility issues using Android TalkBack or iOS VoiceOver +- **International Perspective**: Research and apply accessibility standards from different countries (EN 301 549, Section 508, ADA) +- **Accessibility Statement Review**: Evaluate the website's existing accessibility statement (if any) against your findings + +## Deliverables + +Submit a comprehensive accessibility audit report that demonstrates professional-level analysis and practical implementation planning: + +**📄 Final Report Requirements:** + +1. **Executive Summary** (1 page) + - Website overview and accessibility maturity assessment + - Key findings summary with business impact + - Recommended priority actions + +2. **Methodology and Scope** (1 page) + - Testing approach, tools used, and evaluation criteria + - Pages/sections evaluated and any limitations + - Standards compliance framework (WCAG 2.1 AA) + +3. **Detailed Findings Report** (3-4 pages) + - Manual testing observations with user scenarios + - Automated tool results with cross-referencing + - Issues organized by WCAG principles with evidence + - Positive accessibility features identified + +4. **Strategic Remediation Plan** (3-4 pages) + - Prioritized improvement recommendations (minimum 10) + - Implementation timeline with effort estimates + - Success metrics and verification methods + - Long-term accessibility maintenance strategy + +5. **Supporting Evidence** (Appendices) + - Screenshots of accessibility violations and testing tools + - Code examples demonstrating issues and solutions + - Tool reports and audit summaries + - Screen reader testing notes or recordings + +**📊 Format Requirements:** +- **Document format**: PDF (professional presentation) +- **Word count**: 2,500-3,500 words (excluding appendices and screenshots) +- **Visual elements**: Include screenshots, diagrams, and examples throughout +- **Citations**: Reference WCAG guidelines and accessibility resources appropriately + +**💡 Pro Tips for Excellence:** +- Use professional report formatting with consistent headings and styling +- Include a table of contents for easy navigation +- Balance technical accuracy with clear, business-appropriate language +- Demonstrate understanding of both technical implementation and user impact + +## Learning Outcomes + +After completing this comprehensive accessibility audit, you will have developed essential professional skills: + +**🎯 Technical Competencies:** +- **Accessibility Testing Mastery**: Proficiency with industry-standard manual and automated testing methods +- **WCAG Application**: Practical experience applying Web Content Accessibility Guidelines to real-world scenarios +- **Assistive Technology Understanding**: Hands-on experience with screen readers and keyboard navigation +- **Problem-Solution Mapping**: Ability to identify accessibility barriers and develop specific, actionable remediation strategies + +**💼 Professional Skills:** +- **Technical Communication**: Experience writing professional accessibility reports for diverse stakeholders +- **Strategic Planning**: Ability to prioritize accessibility improvements based on user impact and implementation feasibility +- **Quality Assurance**: Understanding of accessibility testing as part of the development lifecycle +- **Risk Assessment**: Appreciation for legal, business, and ethical implications of accessibility compliance + +**🌍 Inclusive Design Mindset:** +- **User Empathy**: Deep understanding of diverse user needs and assistive technology interactions +- **Universal Design Principles**: Recognition that accessible design benefits all users, not just those with disabilities +- **Continuous Improvement**: Framework for ongoing accessibility assessment and enhancement +- **Advocacy Skills**: Confidence to promote accessibility best practices in future projects and teams + +**🚀 Career Preparation:** +This assignment mirrors real-world accessibility consulting projects, giving you portfolio-worthy experience that demonstrates: +- Systematic problem-solving approach +- Attention to both technical details and business impact +- Clear communication of complex technical concepts +- Understanding of legal and ethical responsibilities in web development + +Upon completion, you'll be prepared to contribute meaningfully to accessibility initiatives in any web development role and advocate for inclusive design practices throughout your career. --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/1-getting-started-lessons/README.md b/translations/en/1-getting-started-lessons/README.md index bfbac11b1..e3651e012 100644 --- a/translations/en/1-getting-started-lessons/README.md +++ b/translations/en/1-getting-started-lessons/README.md @@ -1,12 +1,3 @@ - # Getting Started with Web Development In this section of the curriculum, you will learn about non-project-based concepts that are essential for becoming a professional developer. diff --git a/translations/en/10-ai-framework-project/README.md b/translations/en/10-ai-framework-project/README.md index 076a6c498..69c4a53fd 100644 --- a/translations/en/10-ai-framework-project/README.md +++ b/translations/en/10-ai-framework-project/README.md @@ -1,41 +1,178 @@ - # AI Framework -There are many AI frameworks available that can significantly speed up the process of building a project. In this project, we will focus on understanding the problems these frameworks address and create such a project ourselves. +Ever felt overwhelmed trying to build AI applications from scratch? You're not alone! AI frameworks are like having a Swiss Army knife for AI development - they're powerful tools that can save you time and headaches when building intelligent applications. Think of an AI framework as a well-organized library: it provides pre-built components, standardized APIs, and smart abstractions so you can focus on solving problems instead of wrestling with implementation details. + +In this lesson, we'll explore how frameworks like LangChain can turn what used to be complex AI integration tasks into clean, readable code. You'll discover how to tackle real-world challenges like keeping track of conversations, implementing tool calling, and juggling different AI models through one unified interface. + +By the time we're done, you'll know when to reach for frameworks instead of raw API calls, how to use their abstractions effectively, and how to build AI applications that are ready for real-world use. Let's explore what AI frameworks can do for your projects. + +## ⚡ What You Can Do in the Next 5 Minutes + +**Quick Start Pathway for Busy Developers** -## Why use a framework +```mermaid +flowchart LR + A[⚡ 5 minutes] --> B[Install LangChain] + B --> C[Create ChatOpenAI client] + C --> D[Send first prompt] + D --> E[See framework power] +``` +- **Minute 1**: Install LangChain: `pip install langchain langchain-openai` +- **Minute 2**: Set up your GitHub token and import the ChatOpenAI client +- **Minute 3**: Create a simple conversation with system and human messages +- **Minute 4**: Add a basic tool (like an add function) and see AI tool calling +- **Minute 5**: Experience the difference between raw API calls and framework abstraction + +**Quick Test Code**: +```python +from langchain_openai import ChatOpenAI +from langchain_core.messages import SystemMessage, HumanMessage + +llm = ChatOpenAI( + api_key=os.environ["GITHUB_TOKEN"], + base_url="https://models.github.ai/inference", + model="openai/gpt-4o-mini" +) + +response = llm.invoke([ + SystemMessage(content="You are a helpful coding assistant"), + HumanMessage(content="Explain Python functions briefly") +]) +print(response.content) +``` -When working with AI, there are different approaches and reasons for choosing them. Here are some: +**Why This Matters**: In 5 minutes, you'll experience how AI frameworks transform complex AI integration into simple method calls. This is the foundation that powers production AI applications. -- **No SDK**: Most AI models allow you to interact directly with the model, for example, via HTTP requests. This approach works and may sometimes be your only option if an SDK is unavailable. -- **SDK**: Using an SDK is usually the recommended approach as it requires less code to interact with your model. However, it is often limited to a specific model, and if you use different models, you might need to write new code to support those additional models. -- **A framework**: A framework typically takes things to the next level by providing a unified API for interacting with different models, with differences usually limited to the initial setup. Frameworks also offer useful abstractions, such as tools, memory, workflows, agents, and more, while requiring less code. Because frameworks are often opinionated, they can be very helpful if you align with their approach, but they may fall short if you need to implement something custom that the framework isn't designed for. Additionally, frameworks can sometimes oversimplify things, which might prevent you from learning important concepts that could later impact performance. +## Why choose a framework? -In general, use the right tool for the job. +So you're ready to build an AI app - awesome! But here's the thing: you've got several different paths you can take, and each one has its own pros and cons. It's kind of like choosing between walking, biking, or driving to get somewhere - they'll all get you there, but the experience (and effort) will be totally different. + +Let's break down the three main ways you can integrate AI into your projects: + +| Approach | Advantages | Best For | Considerations | +|----------|------------|----------|--------------| +| **Direct HTTP Requests** | Full control, no dependencies | Simple queries, learning fundamentals | More verbose code, manual error handling | +| **SDK Integration** | Less boilerplate, model-specific optimization | Single-model applications | Limited to specific providers | +| **AI Frameworks** | Unified API, built-in abstractions | Multi-model apps, complex workflows | Learning curve, potential over-abstraction | + +### Framework Benefits in Practice + +```mermaid +graph TD + A[Your Application] --> B[AI Framework] + B --> C[OpenAI GPT] + B --> D[Anthropic Claude] + B --> E[GitHub Models] + B --> F[Local Models] + + B --> G[Built-in Tools] + G --> H[Memory Management] + G --> I[Conversation History] + G --> J[Function Calling] + G --> K[Error Handling] +``` +**Why frameworks matter:** +- **Unifies** multiple AI providers under one interface +- **Handles** conversation memory automatically +- **Provides** ready-made tools for common tasks like embeddings and function calling +- **Manages** error handling and retry logic +- **Turns** complex workflows into readable method calls + +> 💡 **Pro Tip**: Use frameworks when switching between different AI models or building complex features like agents, memory, or tool calling. Stick with direct APIs when learning the basics or building simple, focused applications. + +**Bottom line**: Like choosing between a craftsman's specialized tools and a complete workshop, it's about matching the tool to the task. Frameworks excel for complex, feature-rich applications, while direct APIs work well for straightforward use cases. + +## 🗺️ Your Learning Journey Through AI Framework Mastery + +```mermaid +journey + title From Raw APIs to Production AI Applications + section Framework Foundations + Understand abstraction benefits: 4: You + Master LangChain basics: 6: You + Compare approaches: 7: You + section Conversation Systems + Build chat interfaces: 5: You + Implement memory patterns: 7: You + Handle streaming responses: 8: You + section Advanced Features + Create custom tools: 6: You + Master structured output: 8: You + Build document systems: 8: You + section Production Applications + Combine all features: 7: You + Handle error scenarios: 8: You + Deploy complete systems: 9: You +``` +**Your Journey Destination**: By the end of this lesson, you'll have mastered AI framework development and be able to build sophisticated, production-ready AI applications that rival commercial AI assistants. ## Introduction In this lesson, we'll learn to: - Use a common AI framework. -- Address common challenges like chat conversations, tool usage, memory, and context. -- Leverage these capabilities to build AI applications. +- Address common problems like chat conversations, tool usage, memory and context. +- Leverage this to build AI apps. + +## 🧠 AI Framework Development Ecosystem + +```mermaid +mindmap + root((AI Frameworks)) + Abstraction Benefits + Code Simplification + Unified APIs + Built-in Error Handling + Consistent Patterns + Reduced Boilerplate + Multi-Model Support + Provider Agnostic + Easy Switching + Fallback Options + Cost Optimization + Core Components + Conversation Management + Message Types + Memory Systems + Context Tracking + History Persistence + Tool Integration + Function Calling + API Connections + Custom Tools + Workflow Automation + Advanced Features + Structured Output + Pydantic Models + JSON Schemas + Type Safety + Validation Rules + Document Processing + Embeddings + Vector Stores + Similarity Search + RAG Systems + Production Patterns + Application Architecture + Modular Design + Error Boundaries + Async Operations + State Management + Deployment Strategies + Scalability + Monitoring + Performance + Security +``` +**Core Principle**: AI frameworks abstract complexity while providing powerful abstractions for conversation management, tool integration, and document processing, enabling developers to build sophisticated AI applications with clean, maintainable code. -## First prompt +## Your first AI prompt -In our first app example, we'll learn how to connect to an AI model and query it using a prompt. +Let's start with the fundamentals by creating your first AI application that sends a question and gets an answer back. Like Archimedes discovering the principle of displacement in his bath, sometimes the simplest observations lead to the most powerful insights - and frameworks make these insights accessible. -### Using Python +### Setting up LangChain with GitHub Models -For this example, we'll use Langchain to connect to GitHub Models. We can use a class called `ChatOpenAI` and provide it with the fields `api_key`, `base_url`, and `model`. The token is automatically populated within GitHub Codespaces, but if you're running the app locally, you'll need to set up a personal access token for this to work. +We're going to use LangChain to connect to GitHub Models, which is pretty sweet because it gives you free access to various AI models. The best part? You only need a few simple configuration parameters to get started: ```python from langchain_openai import ChatOpenAI @@ -47,32 +184,58 @@ llm = ChatOpenAI( model="openai/gpt-4o-mini", ) -# works -response = llm.invoke("What's the capital of France?") +# Send a simple prompt +response = llm.invoke("What's the capital of France?") print(response.content) ``` -In this code, we: - -- Call `ChatOpenAI` to create a client. -- Use `llm.invoke` with a prompt to generate a response. -- Print the response using `print(response.content)`. +**Let's break down what's happening here:** +- **Creates** a LangChain client using the `ChatOpenAI` class - this is your gateway to AI! +- **Configures** the connection to GitHub Models with your authentication token +- **Specifies** which AI model to use (`gpt-4o-mini`) - think of this as choosing your AI assistant +- **Sends** your question using the `invoke()` method - this is where the magic happens +- **Extracts** and displays the response - and voilà, you're chatting with AI! -You should see a response similar to: +> 🔧 **Setup Note**: If you're using GitHub Codespaces, you're in luck - the `GITHUB_TOKEN` is already set up for you! Working locally? No worries, you'll just need to create a personal access token with the right permissions. +**Expected output:** ```text The capital of France is Paris. ``` -## Chat conversation +```mermaid +sequenceDiagram + participant App as Your Python App + participant LC as LangChain + participant GM as GitHub Models + participant AI as GPT-4o-mini + + App->>LC: llm.invoke("What's the capital of France?") + LC->>GM: HTTP request with prompt + GM->>AI: Process prompt + AI->>GM: Generated response + GM->>LC: Return response + LC->>App: response.content +``` +## Building conversational AI -In the previous section, we used what's commonly known as zero-shot prompting—a single prompt followed by a response. +That first example demonstrates the basics, but it's just a single exchange - you ask a question, get an answer, and that's it. In real applications, you want your AI to remember what you've been discussing, like how Watson and Holmes built their investigative conversations over time. -However, you may often find yourself in situations where you need to maintain a conversation involving multiple exchanges between you and the AI assistant. +This is where LangChain becomes particularly useful. It provides different message types that help structure conversations and let you give your AI a personality. You'll be building chat experiences that maintain context and character. -### Using Python +### Understanding message types -In Langchain, we can store the conversation in a list. The `HumanMessage` represents a message from the user, and `SystemMessage` is a message meant to set the "personality" of the AI. In the example below, we instruct the AI to take on the personality of Captain Picard, and the user asks, "Tell me about you" as the prompt. +Think of these message types as different "hats" that participants wear in a conversation. LangChain uses different message classes to keep track of who's saying what: + +| Message Type | Purpose | Example Use Case | +|--------------|---------|------------------| +| `SystemMessage` | Defines AI personality and behavior | "You are a helpful coding assistant" | +| `HumanMessage` | Represents user input | "Explain how functions work" | +| `AIMessage` | Stores AI responses | Previous AI responses in conversation | + +### Creating your first conversation + +Let's create a conversation where our AI assumes a specific role. We'll have it embody Captain Picard - a character known for his diplomatic wisdom and leadership: ```python messages = [ @@ -81,7 +244,12 @@ messages = [ ] ``` -The full code for this example looks like this: +**Breaking down this conversation setup:** +- **Establishes** the AI's role and personality through `SystemMessage` +- **Provides** the initial user query via `HumanMessage` +- **Creates** a foundation for multi-turn conversation + +The full code for this example looks like so: ```python from langchain_core.messages import HumanMessage, SystemMessage @@ -105,7 +273,7 @@ response = llm.invoke(messages) print(response.content) ``` -You should see an output similar to: +You should see an outcome similar to: ```text I am Captain Jean-Luc Picard, the commanding officer of the USS Enterprise (NCC-1701-D), a starship in the United Federation of Planets. My primary mission is to explore new worlds, seek out new life and new civilizations, and boldly go where no one has gone before. @@ -115,7 +283,7 @@ I believe in the importance of diplomacy, reason, and the pursuit of knowledge. I hold the ideals of the Federation close to my heart, believing in the importance of cooperation, understanding, and respect for all sentient beings. My experiences have shaped my leadership style, and I strive to be a thoughtful and just captain. How may I assist you further? ``` -To maintain the state of the conversation, you can add the response from the chat so the conversation is remembered. Here's how to do that: +To maintain conversation continuity (instead of resetting context each time), you need to keep adding responses to your message list. Like the oral traditions that preserved stories across generations, this approach builds lasting memory: ```python from langchain_core.messages import HumanMessage, SystemMessage @@ -150,9 +318,9 @@ print(response.content) ``` -From the above conversation, we can see how the LLM is invoked twice—first with a conversation consisting of just two messages, and then a second time with additional messages added to the conversation. +Pretty neat, right? What's happening here is that we're calling the LLM twice - first with just our initial two messages, but then again with the full conversation history. It's like the AI is actually following along with our chat! -If you run this, you'll see the second response being something like: +When you run this code, you'll get a second response that sounds something like: ```text Welcome aboard, Chris! It's always a pleasure to meet those who share a passion for exploration and discovery. While I cannot formally offer you a position on the Enterprise right now, I encourage you to pursue your aspirations. We are always in need of talented individuals with diverse skills and backgrounds. @@ -160,27 +328,165 @@ Welcome aboard, Chris! It's always a pleasure to meet those who share a passion If you are interested in space exploration, consider education and training in the sciences, engineering, or diplomacy. The values of curiosity, resilience, and teamwork are crucial in Starfleet. Should you ever find yourself on a starship, remember to uphold the principles of the Federation: peace, understanding, and respect for all beings. Your journey can lead you to remarkable adventures, whether in the stars or on the ground. Engage! ``` +```mermaid +sequenceDiagram + participant User + participant App + participant LangChain + participant AI + + User->>App: "Tell me about you" + App->>LangChain: [SystemMessage, HumanMessage] + LangChain->>AI: Formatted conversation + AI->>LangChain: Captain Picard response + LangChain->>App: AIMessage object + App->>User: Display response + + Note over App: Add AIMessage to conversation + + User->>App: "Can I join your crew?" + App->>LangChain: [SystemMessage, HumanMessage, AIMessage, HumanMessage] + LangChain->>AI: Full conversation context + AI->>LangChain: Contextual response + LangChain->>App: New AIMessage + App->>User: Display contextual response +``` I'll take that as a maybe ;) ## Streaming responses -TODO +Ever notice how ChatGPT seems to "type" its responses in real-time? That's streaming in action. Like watching a skilled calligrapher work - seeing the characters appear stroke by stroke rather than materializing instantly - streaming makes the interaction feel more natural and provides immediate feedback. + +### Implementing streaming with LangChain + +```python +from langchain_openai import ChatOpenAI +import os + +llm = ChatOpenAI( + api_key=os.environ["GITHUB_TOKEN"], + base_url="https://models.github.ai/inference", + model="openai/gpt-4o-mini", + streaming=True +) + +# Stream the response +for chunk in llm.stream("Write a short story about a robot learning to code"): + print(chunk.content, end="", flush=True) +``` + +**Why streaming is awesome:** +- **Shows** content as it's being created - no more awkward waiting! +- **Makes** users feel like something's actually happening +- **Feels** faster, even when it technically isn't +- **Lets** users start reading while the AI is still "thinking" + +> 💡 **User Experience Tip**: Streaming really shines when you're dealing with longer responses like code explanations, creative writing, or detailed tutorials. Your users will love seeing progress instead of staring at a blank screen! + +### 🎯 Pedagogical Check-in: Framework Abstraction Benefits + +**Pause and Reflect**: You've just experienced the power of AI framework abstractions. Compare what you've learned to raw API calls from previous lessons. + +**Quick Self-Assessment**: +- Can you explain how LangChain simplifies conversation management compared to manual message tracking? +- What's the difference between `invoke()` and `stream()` methods, and when would you use each? +- How does the framework's message type system improve code organization? + +**Real-World Connection**: The abstraction patterns you've learned (message types, streaming interfaces, conversation memory) are used in every major AI application - from ChatGPT's interface to GitHub Copilot's code assistance. You're mastering the same architectural patterns used by professional AI development teams. + +**Challenge Question**: How would you design a framework abstraction for handling different AI model providers (OpenAI, Anthropic, Google) with a single interface? Consider the benefits and trade-offs. ## Prompt templates -TODO +Prompt templates work like the rhetorical structures used in classical oratory - think of how Cicero would adapt his speech patterns for different audiences while maintaining the same persuasive framework. They let you create reusable prompts where you can swap out different pieces of information without rewriting everything from scratch. Once you set up the template, you just fill in the variables with whatever values you need. + +### Creating reusable prompts + +```python +from langchain_core.prompts import ChatPromptTemplate + +# Define a template for code explanations +template = ChatPromptTemplate.from_messages([ + ("system", "You are an expert programming instructor. Explain concepts clearly with examples."), + ("human", "Explain {concept} in {language} with a practical example for {skill_level} developers") +]) + +# Use the template with different values +questions = [ + {"concept": "functions", "language": "JavaScript", "skill_level": "beginner"}, + {"concept": "classes", "language": "Python", "skill_level": "intermediate"}, + {"concept": "async/await", "language": "JavaScript", "skill_level": "advanced"} +] + +for question in questions: + prompt = template.format_messages(**question) + response = llm.invoke(prompt) + print(f"Topic: {question['concept']}\n{response.content}\n---\n") +``` + +**Why you'll love using templates:** +- **Keeps** your prompts consistent across your entire app +- **No more** messy string concatenation - just clean, simple variables +- **Your AI** behaves predictably because the structure stays the same +- **Updates** are a breeze - change the template once, and it's fixed everywhere ## Structured output -TODO +Ever get frustrated trying to parse AI responses that come back as unstructured text? Structured output is like teaching your AI to follow the systematic approach that Linnaeus used for biological classification - organized, predictable, and easy to work with. You can request JSON, specific data structures, or any format you need. + +### Defining output schemas + +```python +from langchain_core.prompts import ChatPromptTemplate +from langchain_core.output_parsers import JsonOutputParser +from pydantic import BaseModel, Field + +class CodeReview(BaseModel): + score: int = Field(description="Code quality score from 1-10") + strengths: list[str] = Field(description="List of code strengths") + improvements: list[str] = Field(description="List of suggested improvements") + overall_feedback: str = Field(description="Summary feedback") + +# Set up the parser +parser = JsonOutputParser(pydantic_object=CodeReview) + +# Create prompt with format instructions +prompt = ChatPromptTemplate.from_messages([ + ("system", "You are a code reviewer. {format_instructions}"), + ("human", "Review this code: {code}") +]) + +# Format the prompt with instructions +chain = prompt | llm | parser + +# Get structured response +code_sample = """ +def calculate_average(numbers): + return sum(numbers) / len(numbers) +""" + +result = chain.invoke({ + "code": code_sample, + "format_instructions": parser.get_format_instructions() +}) + +print(f"Score: {result['score']}") +print(f"Strengths: {', '.join(result['strengths'])}") +``` + +**Why structured output is a game-changer:** +- **No more** guessing what format you'll get back - it's consistent every time +- **Plugs** directly into your databases and APIs without extra work +- **Catches** weird AI responses before they break your app +- **Makes** your code cleaner because you know exactly what you're working with ## Tool calling -Tools allow us to give the LLM additional capabilities. The idea is to inform the LLM about available functions, and if a prompt matches the description of one of these tools, the tool is invoked. +Now we reach one of the most powerful features: tools. This is how you give your AI practical capabilities beyond conversation. Like how medieval guilds developed specialized tools for specific crafts, you can equip your AI with focused instruments. You describe what tools are available, and when someone requests something that matches, your AI can take action. ### Using Python -Let's add some tools like this: +Let's add some tools like so: ```python from typing_extensions import Annotated, TypedDict @@ -199,9 +505,9 @@ functions = { } ``` -Here, we create a description of a tool called `add`. By inheriting from `TypedDict` and adding members like `a` and `b` of type `Annotated`, this can be converted into a schema that the LLM can understand. The creation of functions is managed through a dictionary that ensures we know what to do if a specific tool is identified. +So what's happening here? We're creating a blueprint for a tool called `add`. By inheriting from `TypedDict` and using those fancy `Annotated` types for `a` and `b`, we're giving the LLM a clear picture of what this tool does and what it needs. The `functions` dictionary is like our toolbox - it tells our code exactly what to do when the AI decides to use a specific tool. -Next, let's see how we call the LLM with this tool: +Let's see how we call the LLM with this tool next: ```python llm = ChatOpenAI( @@ -213,9 +519,9 @@ llm = ChatOpenAI( llm_with_tools = llm.bind_tools(tools) ``` -Here, we use `bind_tools` with our `tools` array, enabling the LLM `llm_with_tools` to recognize this tool. +Here we call `bind_tools` with our `tools` array and thereby the LLM `llm_with_tools` now has knowledge of this tool. -To use this new LLM, we can write the following code: +To use this new LLM, we can type the following code: ```python query = "What is 3 + 12?" @@ -227,7 +533,7 @@ if(res.tool_calls): print("CONTENT: ",res.content) ``` -When we call `invoke` on this new LLM that has tools, the property `tool_calls` may be populated. If so, any identified tools will have a `name` and `args` property that specifies which tool should be called and with what arguments. The full code looks like this: +Now that we call `invoke` on this new llm, that has tools, we maybe the the property `tool_calls` populated. If so, any identified tools has a `name` and `args` property that identifies what tool should be called and with arguments. The full code looks like so: ```python from langchain_core.messages import HumanMessage, SystemMessage @@ -272,15 +578,14 @@ TOOL CALL: 15 CONTENT: ``` -This output indicates that the LLM interpreted the prompt "What is 3 + 12" as requiring the `add` tool, based on its name, description, and member field descriptions. The answer, 15, is derived from our code using the dictionary `functions` to invoke it: +The AI examined "What is 3 + 12" and recognized this as a task for the `add` tool. Like how a skilled librarian knows which reference to consult based on the type of question asked, it made this determination from the tool's name, description, and field specifications. The result of 15 comes from our `functions` dictionary executing the tool: ```python print("TOOL CALL: ", functions[tool["name"]](../../../10-ai-framework-project/**tool["args"])) ``` ### A more interesting tool that calls a web API - -While tools that add two numbers are useful for illustrating how tool calling works, tools often perform more complex tasks, such as calling a web API. Let's implement that with this code: +Adding numbers demonstrates the concept, but real tools typically perform more complex operations, like calling web APIs. Let's expand our example to have the AI fetch content from the internet - similar to how telegraph operators once connected distant locations: ```python class joke(TypedDict): @@ -305,14 +610,40 @@ query = "Tell me a joke about animals" # the rest of the code is the same ``` -Running this code will produce a response similar to: +Now if you run this code you will get a response saying something like: ```text TOOL CALL: Chuck Norris once rode a nine foot grizzly bear through an automatic car wash, instead of taking a shower. CONTENT: ``` -Here's the complete code: +```mermaid +flowchart TD + A[User Query: "Tell me a joke about animals"] --> B[LangChain Analysis] + B --> C{Tool Available?} + C -->|Yes| D[Select joke tool] + C -->|No| E[Generate direct response] + + D --> F[Extract Parameters] + F --> G[Call joke(category="animals")] + G --> H[API Request to chucknorris.io] + H --> I[Return joke content] + I --> J[Display to user] + + E --> K[AI-generated response] + K --> J + + subgraph "Tool Definition Layer" + L[TypedDict Schema] + M[Function Implementation] + N[Parameter Validation] + end + + D --> L + F --> N + G --> M +``` +Here's the code in its entirety: ```python from langchain_openai import ChatOpenAI @@ -364,25 +695,443 @@ if(res.tool_calls): print("CONTENT: ",res.content) ``` -## Embedding +## Embeddings and document processing -Vectorize content and compare using cosine similarity. +Embeddings represent one of the most elegant solutions in modern AI. Imagine if you could take any piece of text and convert it into numerical coordinates that capture its meaning. That's exactly what embeddings do - they transform text into points in multi-dimensional space where similar concepts cluster together. It's like having a coordinate system for ideas, reminiscent of how Mendeleev organized the periodic table by atomic properties. -https://python.langchain.com/docs/how_to/embed_text/ +### Creating and using embeddings + +```python +from langchain_openai import OpenAIEmbeddings +from langchain_community.vectorstores import FAISS +from langchain_community.document_loaders import TextLoader +from langchain.text_splitter import CharacterTextSplitter + +# Initialize embeddings +embeddings = OpenAIEmbeddings( + api_key=os.environ["GITHUB_TOKEN"], + base_url="https://models.github.ai/inference", + model="text-embedding-3-small" +) -### Document loaders +# Load and split documents +loader = TextLoader("documentation.txt") +documents = loader.load() + +text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) +texts = text_splitter.split_documents(documents) + +# Create vector store +vectorstore = FAISS.from_documents(texts, embeddings) + +# Perform similarity search +query = "How do I handle user authentication?" +similar_docs = vectorstore.similarity_search(query, k=3) + +for doc in similar_docs: + print(f"Relevant content: {doc.page_content[:200]}...") +``` + +### Document loaders for various formats + +```python +from langchain_community.document_loaders import ( + PyPDFLoader, + CSVLoader, + JSONLoader, + WebBaseLoader +) + +# Load different document types +pdf_loader = PyPDFLoader("manual.pdf") +csv_loader = CSVLoader("data.csv") +json_loader = JSONLoader("config.json") +web_loader = WebBaseLoader("https://example.com/docs") + +# Process all documents +all_documents = [] +for loader in [pdf_loader, csv_loader, json_loader, web_loader]: + docs = loader.load() + all_documents.extend(docs) +``` + +**What you can do with embeddings:** +- **Build** search that actually understands what you mean, not just keyword matching +- **Create** AI that can answer questions about your documents +- **Make** recommendation systems that suggest truly relevant content +- **Automatically** organize and categorize your content + +```mermaid +flowchart LR + A[Documents] --> B[Text Splitter] + B --> C[Create Embeddings] + C --> D[Vector Store] + + E[User Query] --> F[Query Embedding] + F --> G[Similarity Search] + G --> D + D --> H[Relevant Documents] + H --> I[AI Response] + + subgraph "Vector Space" + J[Document A: [0.1, 0.8, 0.3...]] + K[Document B: [0.2, 0.7, 0.4...]] + L[Query: [0.15, 0.75, 0.35...]] + end + + C --> J + C --> K + F --> L + G --> J + G --> K +``` +## Building a complete AI application + +Now we'll integrate everything you've learned into a comprehensive application - a coding assistant that can answer questions, use tools, and maintain conversation memory. Like how the printing press combined existing technologies (movable type, ink, paper, and pressure) into something transformative, we'll combine our AI components into something practical and useful. + +### Complete application example + +```python +from langchain_openai import ChatOpenAI, OpenAIEmbeddings +from langchain_core.prompts import ChatPromptTemplate +from langchain_core.messages import HumanMessage, SystemMessage, AIMessage +from langchain_community.vectorstores import FAISS +from typing_extensions import Annotated, TypedDict +import os +import requests + +class CodingAssistant: + def __init__(self): + self.llm = ChatOpenAI( + api_key=os.environ["GITHUB_TOKEN"], + base_url="https://models.github.ai/inference", + model="openai/gpt-4o-mini" + ) + + self.conversation_history = [ + SystemMessage(content="""You are an expert coding assistant. + Help users learn programming concepts, debug code, and write better software. + Use tools when needed and maintain a helpful, encouraging tone.""") + ] + + # Define tools + self.setup_tools() + + def setup_tools(self): + class web_search(TypedDict): + """Search for programming documentation or examples.""" + query: Annotated[str, "Search query for programming help"] + + class code_formatter(TypedDict): + """Format and validate code snippets.""" + code: Annotated[str, "Code to format"] + language: Annotated[str, "Programming language"] + + self.tools = [web_search, code_formatter] + self.llm_with_tools = self.llm.bind_tools(self.tools) + + def chat(self, user_input: str): + # Add user message to conversation + self.conversation_history.append(HumanMessage(content=user_input)) + + # Get AI response + response = self.llm_with_tools.invoke(self.conversation_history) + + # Handle tool calls if any + if response.tool_calls: + for tool_call in response.tool_calls: + tool_result = self.execute_tool(tool_call) + print(f"🔧 Tool used: {tool_call['name']}") + print(f"📊 Result: {tool_result}") + + # Add AI response to conversation + self.conversation_history.append(response) + + return response.content + + def execute_tool(self, tool_call): + tool_name = tool_call['name'] + args = tool_call['args'] + + if tool_name == 'web_search': + return f"Found documentation for: {args['query']}" + elif tool_name == 'code_formatter': + return f"Formatted {args['language']} code: {args['code'][:50]}..." + + return "Tool execution completed" + +# Usage example +assistant = CodingAssistant() + +print("🤖 Coding Assistant Ready! Type 'quit' to exit.\n") + +while True: + user_input = input("You: ") + if user_input.lower() == 'quit': + break + + response = assistant.chat(user_input) + print(f"🤖 Assistant: {response}\n") +``` + +**Application architecture:** + +```mermaid +graph TD + A[User Input] --> B[Coding Assistant] + B --> C[Conversation Memory] + B --> D[Tool Detection] + B --> E[LLM Processing] + + D --> F[Web Search Tool] + D --> G[Code Formatter Tool] + + E --> H[Response Generation] + F --> H + G --> H + + H --> I[User Interface] + H --> C +``` +**Key features we've implemented:** +- **Remembers** your entire conversation for context continuity +- **Performs actions** through tool calling, not just conversation +- **Follows** predictable interaction patterns +- **Manages** error handling and complex workflows automatically -PDF and CSV +### 🎯 Pedagogical Check-in: Production AI Architecture -## Building an app +**Architecture Understanding**: You've built a complete AI application that combines conversation management, tool calling, and structured workflows. This represents production-level AI application development. -TODO +**Key Concepts Mastered**: +- **Class-Based Architecture**: Organized, maintainable AI application structure +- **Tool Integration**: Custom functionality beyond conversation +- **Memory Management**: Persistent conversation context +- **Error Handling**: Robust application behavior -## Assignment +**Industry Connection**: The architecture patterns you've implemented (conversation classes, tool systems, memory management) are the same patterns used in enterprise AI applications like Slack's AI assistant, GitHub Copilot, and Microsoft Copilot. You're building with professional-grade architectural thinking. + +**Reflection Question**: How would you extend this application to handle multiple users, persistent storage, or integration with external databases? Consider scalability and state management challenges. + +## Assignment: Build your own AI-powered study assistant + +**Objective**: Create an AI application that helps students learn programming concepts by providing explanations, code examples, and interactive quizzes. + +### Requirements + +**Core Features (Required):** +1. **Conversational Interface**: Implement a chat system that maintains context across multiple questions +2. **Educational Tools**: Create at least two tools that help with learning: + - Code explanation tool + - Concept quiz generator +3. **Personalized Learning**: Use system messages to adapt responses to different skill levels +4. **Response Formatting**: Implement structured output for quiz questions + +### Implementation Steps + +**Step 1: Setup your environment** +```bash +pip install langchain langchain-openai +``` + +**Step 2: Basic chat functionality** +- Create a `StudyAssistant` class +- Implement conversation memory +- Add personality configuration for educational support + +**Step 3: Add educational tools** +- **Code Explainer**: Breaks down code into understandable parts +- **Quiz Generator**: Creates questions about programming concepts +- **Progress Tracker**: Keeps track of topics covered + +**Step 4: Enhanced features (Optional)** +- Implement streaming responses for better user experience +- Add document loading to incorporate course materials +- Create embeddings for similarity-based content retrieval + +### Evaluation Criteria + +| Feature | Excellent (4) | Good (3) | Satisfactory (2) | Needs Work (1) | +|---------|---------------|----------|------------------|----------------| +| **Conversation Flow** | Natural, context-aware responses | Good context retention | Basic conversation | No memory between exchanges | +| **Tool Integration** | Multiple useful tools working seamlessly | 2+ tools implemented correctly | 1-2 basic tools | Tools not functional | +| **Code Quality** | Clean, well-documented, error handling | Good structure, some documentation | Basic functionality works | Poor structure, no error handling | +| **Educational Value** | Truly helpful for learning, adaptive | Good learning support | Basic explanations | Limited educational benefit | + +### Sample code structure + +```python +class StudyAssistant: + def __init__(self, skill_level="beginner"): + # Initialize LLM, tools, and conversation memory + pass + + def explain_code(self, code, language): + # Tool: Explain how code works + pass + + def generate_quiz(self, topic, difficulty): + # Tool: Create practice questions + pass + + def chat(self, user_input): + # Main conversation interface + pass + +# Example usage +assistant = StudyAssistant(skill_level="intermediate") +response = assistant.chat("Explain how Python functions work") +``` + +**Bonus Challenges:** +- Add voice input/output capabilities +- Implement a web interface using Streamlit or Flask +- Create a knowledge base from course materials using embeddings +- Add progress tracking and personalized learning paths + +## 📈 Your AI Framework Development Mastery Timeline + +```mermaid +timeline + title Production AI Framework Development Journey + + section Framework Foundations + Understanding Abstractions + : Master framework vs API decisions + : Learn LangChain core concepts + : Implement message type systems + + Basic Integration + : Connect to AI providers + : Handle authentication + : Manage configuration + + section Conversation Systems + Memory Management + : Build conversation history + : Implement context tracking + : Handle session persistence + + Advanced Interactions + : Master streaming responses + : Create prompt templates + : Implement structured output + + section Tool Integration + Custom Tool Development + : Design tool schemas + : Implement function calling + : Handle external APIs + + Workflow Automation + : Chain multiple tools + : Create decision trees + : Build agent behaviors + + section Production Applications + Complete System Architecture + : Combine all framework features + : Implement error boundaries + : Create maintainable code + + Enterprise Readiness + : Handle scalability concerns + : Implement monitoring + : Build deployment strategies +``` +**🎓 Graduation Milestone**: You've successfully mastered AI framework development using the same tools and patterns that power modern AI applications. These skills represent the cutting edge of AI application development and prepare you for building enterprise-grade intelligent systems. + +**🔄 Next Level Capabilities**: +- Ready to explore advanced AI architectures (agents, multi-agent systems) +- Prepared to build RAG systems with vector databases +- Equipped to create multi-modal AI applications +- Foundation set for AI application scaling and optimization ## Summary +🎉 You've now mastered the fundamentals of AI framework development and learned how to build sophisticated AI applications using LangChain. Like completing a comprehensive apprenticeship, you've acquired a substantial toolkit of skills. Let's review what you've accomplished. + +### What you've learned + +**Core Framework Concepts:** +- **Framework Benefits**: Understanding when to choose frameworks over direct API calls +- **LangChain Basics**: Setting up and configuring AI model connections +- **Message Types**: Using `SystemMessage`, `HumanMessage`, and `AIMessage` for structured conversations + +**Advanced Features:** +- **Tool Calling**: Creating and integrating custom tools for enhanced AI capabilities +- **Conversation Memory**: Maintaining context across multiple conversation turns +- **Streaming Responses**: Implementing real-time response delivery +- **Prompt Templates**: Building reusable, dynamic prompts +- **Structured Output**: Ensuring consistent, parseable AI responses +- **Embeddings**: Creating semantic search and document processing capabilities + +**Practical Applications:** +- **Building Complete Apps**: Combining multiple features into production-ready applications +- **Error Handling**: Implementing robust error management and validation +- **Tool Integration**: Creating custom tools that extend AI capabilities + +### Key takeaways + +> 🎯 **Remember**: AI frameworks like LangChain are basically your complexity-hiding, feature-packed best friends. They're perfect when you need conversation memory, tool calling, or want to work with multiple AI models without losing your sanity. + +**Decision framework for AI integration:** + +```mermaid +flowchart TD + A[AI Integration Need] --> B{Simple single query?} + B -->|Yes| C[Direct API calls] + B -->|No| D{Need conversation memory?} + D -->|No| E[SDK Integration] + D -->|Yes| F{Need tools or complex features?} + F -->|No| G[Framework with basic setup] + F -->|Yes| H[Full framework implementation] + + C --> I[HTTP requests, minimal dependencies] + E --> J[Provider SDK, model-specific] + G --> K[LangChain basic chat] + H --> L[LangChain with tools, memory, agents] +``` +### Where do you go from here? + +**Start building right now:** +- Take these concepts and build something that excites YOU! +- Play around with different AI models through LangChain - it's like having a playground of AI models +- Create tools that solve actual problems you face in your work or projects + +**Ready for the next level?** +- **AI Agents**: Build AI systems that can actually plan and execute complex tasks on their own +- **RAG (Retrieval-Augmented Generation)**: Combine AI with your own knowledge bases for super-powered applications +- **Multi-Modal AI**: Work with text, images, and audio all together - the possibilities are endless! +- **Production Deployment**: Learn how to scale your AI apps and monitor them in the real world + +**Join the community:** +- The LangChain community is fantastic for staying up-to-date and learning best practices +- GitHub Models gives you access to cutting-edge AI capabilities - perfect for experimenting +- Keep practicing with different use cases - each project will teach you something new + +You now have the knowledge to build intelligent, conversational applications that can help people solve real problems. Like the Renaissance craftsmen who combined artistic vision with technical skill, you can now merge AI capabilities with practical application. The question is: what will you create? 🚀 + +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Build an advanced AI-powered code review assistant that combines multiple LangChain features including tool calling, structured output, and conversation memory to provide comprehensive feedback on code submissions. + +**Prompt:** Create a CodeReviewAssistant class that implements: +1. A tool for analyzing code complexity and suggesting improvements +2. A tool for checking code against best practices +3. Structured output using Pydantic models for consistent review format +4. Conversation memory to track review sessions +5. A main chat interface that can handle code submissions and provide detailed, actionable feedback + +The assistant should be able to review code in multiple programming languages, maintain context across multiple code submissions in a session, and provide both summary scores and detailed improvement suggestions. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/2-js-basics/1-data-types/README.md b/translations/en/2-js-basics/1-data-types/README.md index b7cbe2985..feeea7277 100644 --- a/translations/en/2-js-basics/1-data-types/README.md +++ b/translations/en/2-js-basics/1-data-types/README.md @@ -1,161 +1,361 @@ - # JavaScript Basics: Data Types -![JavaScript Basics - Data types](../../../../translated_images/en/webdev101-js-datatypes.4cc470179730702c756480d3ffa46507f746e5975ebf80f99fdaaf1cff09a7f4.png) +![JavaScript Basics - Data types](../../../../translated_images/en/webdev101-js-datatypes.4cc470179730702c.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) +```mermaid +journey + title Your JavaScript Data Types Adventure + section Foundation + Variables & Constants: 5: You + Declaration Syntax: 4: You + Assignment Concepts: 5: You + section Core Types + Numbers & Math: 4: You + Strings & Text: 5: You + Booleans & Logic: 4: You + section Apply Knowledge + Type Conversion: 4: You + Real-world Examples: 5: You + Best Practices: 5: You +``` +Data types are one of the fundamental concepts in JavaScript that you'll encounter in every program you write. Think of data types like the filing system used by ancient librarians in Alexandria – they had specific places for scrolls containing poetry, mathematics, and historical records. JavaScript organizes information in a similar way with different categories for different kinds of data. + +In this lesson, we'll explore the core data types that make JavaScript work. You'll learn how to handle numbers, text, true/false values, and understand why choosing the correct type is essential for your programs. These concepts might seem abstract at first, but with practice, they'll become second nature. + +Understanding data types will make everything else in JavaScript much clearer. Just as architects need to understand different building materials before constructing a cathedral, these fundamentals will support everything you build going forward. + ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/) -This lesson introduces the basics of JavaScript, the language that makes websites interactive. +This lesson covers the basics of JavaScript, the language that provides interactivity on the web. -> You can follow this lesson on [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-variables/?WT.mc_id=academic-77807-sagibbon)! +> You can take this lesson on [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-variables/?WT.mc_id=academic-77807-sagibbon)! [![Variables](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "Variables in JavaScript") [![Data Types in JavaScript](https://img.youtube.com/vi/AWfA95eLdq8/0.jpg)](https://youtube.com/watch?v=AWfA95eLdq8 "Data Types in JavaScript") -> 🎥 Click the images above to watch videos about variables and data types. - -Let’s dive into variables and the data types they can hold! - +> 🎥 Click the images above for videos about variables and data types + +Let's start with variables and the data types that populate them! + +```mermaid +mindmap + root((JavaScript Data)) + Variables + let myVar + const PI = 3.14 + var oldStyle + Primitive Types + number + 42 + 3.14 + -5 + string + "Hello" + 'World' + `Template` + boolean + true + false + undefined + null + Operations + Arithmetic + + - * / % + String Methods + concatenation + template literals + Type Conversion + implicit + explicit +``` ## Variables -Variables are used to store values that can be accessed and modified throughout your code. +Variables are fundamental building blocks in programming. Like the labeled jars that medieval alchemists used to store different substances, variables let you store information and give it a descriptive name so you can reference it later. Need to remember someone's age? Store it in a variable called `age`. Want to track a user's name? Keep it in a variable called `userName`. + +We'll focus on the modern approach to creating variables in JavaScript. The techniques you'll learn here represent years of language evolution and best practices developed by the programming community. -To **declare** a variable, use the syntax **[keyword] [name]**. This consists of two parts: +Creating and **declaring** a variable has the following syntax **[keyword] [name]**. It's made up of the two parts: -- **Keyword**. The keywords `let` or `var` can be used. +- **Keyword**. Use `let` for variables that can change, or `const` for values that stay the same. +- **The variable name**, this is a descriptive name you choose yourself. -✅ The `let` keyword, introduced in ES6, provides _block scope_ for your variable. It’s recommended to use `let` instead of `var`. We’ll explore block scopes in more detail later. -- **Variable name**, which is a name you choose. +✅ The keyword `let` was introduced in ES6 and gives your variable a so called _block scope_. It's recommended that you use `let` or `const` instead of the older `var` keyword. We will cover block scopes more in depth in future parts. -### Task - Working with Variables +### Task - working with variables -1. **Declare a variable**. Use the `let` keyword to declare a variable: +1. **Declare a variable**. Let's start by creating our first variable: ```javascript let myVariable; ``` - Here, `myVariable` is declared using the `let` keyword but doesn’t yet have a value. + **What this accomplishes:** + - This tells JavaScript to create a storage location called `myVariable` + - JavaScript allocates space in memory for this variable + - The variable currently has no value (undefined) -1. **Assign a value**. Use the `=` operator to assign a value to the variable: +2. **Give it a value**. Now let's put something in our variable: ```javascript myVariable = 123; ``` - > Note: In this lesson, the `=` operator is used as an "assignment operator" to assign a value to a variable. It does not represent equality. + **How assignment works:** + - The `=` operator assigns the value 123 to our variable + - The variable now contains this value instead of being undefined + - You can reference this value throughout your code using `myVariable` - Now, `myVariable` is *initialized* with the value 123. + > Note: the use of `=` in this lesson means we make use of an "assignment operator", used to set a value to a variable. It doesn't denote equality. -1. **Refactor**. Replace your code with the following statement: +3. **Do it the smart way**. Actually, let's combine those two steps: ```javascript let myVariable = 123; ``` - This is called _explicit initialization_, where a variable is declared and assigned a value at the same time. + **This approach is more efficient:** + - You're declaring the variable and assigning a value in one statement + - This is the standard practice among developers + - It reduces code length while maintaining clarity -1. **Change the variable value**. Update the variable’s value like this: +4. **Change your mind**. What if we want to store a different number? ```javascript myVariable = 321; ``` - Once a variable is declared, you can change its value at any point in your code using the `=` operator and the new value. + **Understanding reassignment:** + - The variable now contains 321 instead of 123 + - The previous value is replaced – variables store only one value at a time + - This mutability is the key characteristic of variables declared with `let` + + ✅ Try it! You can write JavaScript right in your browser. Open a browser window and navigate to Developer Tools. In the console, you will find a prompt; type `let myVariable = 123`, press return, then type `myVariable`. What happens? Note, you'll learn more about these concepts in subsequent lessons. + +### 🧠 **Variables Mastery Check: Getting Comfortable** - ✅ Try it! You can write JavaScript directly in your browser. Open Developer Tools, go to the console, and type `let myVariable = 123`. Press Enter, then type `myVariable`. What happens? You’ll learn more about these concepts in upcoming lessons. +**Let's see how you're feeling about variables:** +- Can you explain the difference between declaring and assigning a variable? +- What happens if you try to use a variable before you declare it? +- When would you choose `let` over `const` for a variable? + +```mermaid +stateDiagram-v2 + [*] --> Declared: let myVar + Declared --> Assigned: myVar = 123 + Assigned --> Reassigned: myVar = 456 + Assigned --> [*]: Variable ready! + Reassigned --> [*]: Updated value + + note right of Declared + Variable exists but + has no value (undefined) + end note + + note right of Assigned + Variable contains + the value 123 + end note +``` +> **Quick tip**: Think of variables as labeled storage boxes. You create the box (`let`), put something in it (`=`), and can later replace the contents if needed! ## Constants -Declaring and initializing a constant is similar to a variable, but you use the `const` keyword. Constants are often written in uppercase letters. +Sometimes you need to store information that should never change during program execution. Think of constants like the mathematical principles that Euclid established in ancient Greece – once proven and documented, they remained fixed for all future reference. + +Constants work similarly to variables, but with an important restriction: once you assign their value, it cannot be changed. This immutability helps prevent accidental modifications to critical values in your program. + +Declaration and initialization of a constant follows the same concepts as a variable, with the exception of the `const` keyword. Constants are typically declared with all uppercase letters. ```javascript const MY_VARIABLE = 123; ``` -Constants are like variables, but with two key differences: +**Here's what this code does:** +- **Creates** a constant named `MY_VARIABLE` with the value 123 +- **Uses** uppercase naming convention for constants +- **Prevents** any future changes to this value + +Constants have two main rules: + +- **You must give them a value right away** – no empty constants allowed! +- **You can never change that value** – JavaScript will throw an error if you try. Let's see what I mean: -- **Must have a value**. A constant must be initialized, or an error will occur when the code runs. -- **Reference cannot be changed**. Once initialized, the reference of a constant cannot be changed, or an error will occur. Let’s look at some examples: - - **Simple value**. The following is NOT allowed: + **Simple value** - The following is NOT allowed: ```javascript const PI = 3; PI = 4; // not allowed ``` + + **What you need to remember:** + - **Attempts** to reassign a constant will cause an error + - **Protects** important values from accidental changes + - **Ensures** the value remains consistent throughout your program - - **Object reference is protected**. The following is NOT allowed: + **Object reference is protected** - The following is NOT allowed: ```javascript const obj = { a: 3 }; obj = { b: 5 } // not allowed ``` - - **Object value is not protected**. The following IS allowed: + **Understanding these concepts:** + - **Prevents** replacing the entire object with a new one + - **Protects** the reference to the original object + - **Maintains** the object's identity in memory + + **Object value is not protected** - The following IS allowed: ```javascript const obj = { a: 3 }; obj.a = 5; // allowed ``` - In this case, you’re changing the object’s value, not its reference, so it’s allowed. + **Breaking down what happens here:** + - **Modifies** the property value inside the object + - **Keeps** the same object reference + - **Demonstrates** that object contents can change while the reference stays constant - > Note: A `const` protects the reference from reassignment. However, the value itself is not _immutable_ and can change, especially for complex constructs like objects. + > Note, a `const` means the reference is protected from reassignment. The value is not _immutable_ though and can change, especially if it's a complex construct like an object. ## Data Types -Variables can hold different types of values, such as numbers or text. These types of values are called **data types**. Understanding data types is crucial in software development because it helps determine how code should be written and how the program should behave. Additionally, some data types have unique features that allow you to manipulate or extract information from a value. +JavaScript organizes information into different categories called data types. This concept mirrors how ancient scholars categorized knowledge – Aristotle distinguished between different types of reasoning, knowing that logical principles couldn't be applied uniformly to poetry, mathematics, and natural philosophy. -✅ Data types are also known as JavaScript data primitives, as they are the most basic data types provided by the language. There are 7 primitive data types: string, number, bigint, boolean, undefined, null, and symbol. Take a moment to think about what each of these represents. What is a `zebra`? How about `0`? `true`? +Data types matter because different operations work with different kinds of information. Just as you can't perform arithmetic on a person's name or alphabetize a mathematical equation, JavaScript requires the appropriate data type for each operation. Understanding this prevents errors and makes your code more reliable. + +Variables can store many different types of values, like numbers and text. These various types of values are known as the **data type**. Data types are an important part of software development because it helps developers make decisions on how the code should be written and how the software should run. Furthermore, some data types have unique features that help transform or extract additional information in a value. + +✅ Data Types are also referred to as JavaScript data primitives, as they are the lowest-level data types that are provided by the language. There are 7 primitive data types: string, number, bigint, boolean, undefined, null and symbol. Take a minute to visualize what each of these primitives might represent. What is a `zebra`? How about `0`? `true`? ### Numbers -In the earlier example, the value of `myVariable` was a number data type. +Numbers are the most straightforward data type in JavaScript. Whether you're working with whole numbers like 42, decimals like 3.14, or negative numbers like -5, JavaScript handles them uniformly. + +Remember our variable from earlier? That 123 we stored was actually a number data type: + +```javascript +let myVariable = 123; +``` -`let myVariable = 123;` +**Key characteristics:** +- JavaScript automatically recognizes numeric values +- You can perform mathematical operations with these variables +- No explicit type declaration is required -Variables can store all kinds of numbers, including decimals and negative numbers. Numbers can also be used with arithmetic operators, which we’ll cover in the [next section](../../../../2-js-basics/1-data-types). +Variables can store all types of numbers, including decimals or negative numbers. Numbers also can be used with arithmetic operators, covered in the [next section](../../../../2-js-basics/1-data-types). +```mermaid +flowchart LR + A["🔢 Numbers"] --> B["➕ Addition"] + A --> C["➖ Subtraction"] + A --> D["✖️ Multiplication"] + A --> E["➗ Division"] + A --> F["📊 Remainder %"] + + B --> B1["1 + 2 = 3"] + C --> C1["5 - 3 = 2"] + D --> D1["4 * 3 = 12"] + E --> E1["10 / 2 = 5"] + F --> F1["7 % 3 = 1"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 + style F fill:#fce4ec +``` ### Arithmetic Operators -JavaScript provides several operators for performing arithmetic operations. Here are some examples: +Arithmetic operators allow you to perform mathematical calculations in JavaScript. These operators follow the same principles mathematicians have used for centuries – the same symbols that appeared in the works of scholars like Al-Khwarizmi, who developed algebraic notation. + +The operators work as you would expect from traditional mathematics: plus for addition, minus for subtraction, and so forth. + +There are several types of operators to use when performing arithmetic functions, and some are listed here: | Symbol | Description | Example | | ------ | ------------------------------------------------------------------------ | -------------------------------- | -| `+` | **Addition**: Adds two numbers | `1 + 2 //expected answer is 3` | -| `-` | **Subtraction**: Subtracts one number from another | `1 - 2 //expected answer is -1` | -| `*` | **Multiplication**: Multiplies two numbers | `1 * 2 //expected answer is 2` | -| `/` | **Division**: Divides one number by another | `1 / 2 //expected answer is 0.5` | -| `%` | **Remainder**: Finds the remainder of a division | `1 % 2 //expected answer is 1` | - -✅ Try it! Test an arithmetic operation in your browser’s console. Were the results what you expected? +| `+` | **Addition**: Calculates the sum of two numbers | `1 + 2 //expected answer is 3` | +| `-` | **Subtraction**: Calculates the difference of two numbers | `1 - 2 //expected answer is -1` | +| `*` | **Multiplication**: Calculates the product of two numbers | `1 * 2 //expected answer is 2` | +| `/` | **Division**: Calculates the quotient of two numbers | `1 / 2 //expected answer is 0.5` | +| `%` | **Remainder**: Calculates the remainder from the division of two numbers | `1 % 2 //expected answer is 1` | + +✅ Try it! Try an arithmetic operation in your browser's console. Do the results surprise you? + +### 🧮 **Math Skills Check: Calculating with Confidence** + +**Test your arithmetic understanding:** +- What's the difference between `/` (division) and `%` (remainder)? +- Can you predict what `10 % 3` equals? (Hint: it's not 3.33...) +- Why might the remainder operator be useful in programming? + +```mermaid +pie title "JavaScript Number Operations Usage" + "Addition (+)" : 35 + "Subtraction (-)" : 20 + "Multiplication (*)" : 20 + "Division (/)" : 15 + "Remainder (%)" : 10 +``` +> **Real-world insight**: The remainder operator (%) is super useful for checking if numbers are even/odd, creating patterns, or cycling through arrays! ### Strings -Strings are sequences of characters enclosed in single or double quotes. +In JavaScript, textual data is represented as strings. The term "string" comes from the concept of characters strung together in sequence, much like the way scribes in medieval monasteries would connect letters to form words and sentences in their manuscripts. -- `'This is a string'` -- `"This is also a string"` -- `let myString = 'This is a string value stored in a variable';` +Strings are fundamental to web development. Every piece of text displayed on a website – usernames, button labels, error messages, content – is handled as string data. Understanding strings is essential for creating functional user interfaces. -Always use quotes when writing a string; otherwise, JavaScript will interpret it as a variable name. +Strings are sets of characters that reside between single or double quotes. +```javascript +'This is a string' +"This is also a string" +let myString = 'This is a string value stored in a variable'; +``` + +**Understanding these concepts:** +- **Uses** either single quotes `'` or double quotes `"` to define strings +- **Stores** text data that can include letters, numbers, and symbols +- **Assigns** string values to variables for later use +- **Requires** quotes to distinguish text from variable names + +Remember to use quotes when writing a string, or else JavaScript will assume it's a variable name. + +```mermaid +flowchart TD + A["📝 Strings"] --> B["Single Quotes"] + A --> C["Double Quotes"] + A --> D["Template Literals"] + + B --> B1["'Hello World'"] + C --> C1["\"Hello World\""] + D --> D1["`Hello \${name}`"] + + E["String Operations"] --> F["Concatenation"] + E --> G["Template Insertion"] + E --> H["Length & Methods"] + + F --> F1["'Hello' + ' ' + 'World'"] + G --> G1["`Hello \${firstName} \${lastName}`"] + H --> H1["myString.length"] + + style A fill:#e3f2fd + style E fill:#fff3e0 + style D fill:#e8f5e8 + style G fill:#e8f5e8 +``` ### Formatting Strings -Strings are textual and often need formatting. +String manipulation allows you to combine text elements, incorporate variables, and create dynamic content that responds to program state. This technique enables you to construct text programmatically. + +Often you need to join multiple strings together – this process is called concatenation. -To **concatenate** (join) two or more strings, use the `+` operator. +To **concatenate** two or more strings, or join them together, use the `+` operator. ```javascript let myString1 = "Hello"; @@ -164,12 +364,17 @@ let myString2 = "World"; myString1 + myString2 + "!"; //HelloWorld! myString1 + " " + myString2 + "!"; //Hello World! myString1 + ", " + myString2 + "!"; //Hello, World! - ``` -✅ Why does `1 + 1 = 2` in JavaScript, but `'1' + '1' = 11`? Think about it. What about `'1' + 1`? +**Step by step, here's what's happening:** +- **Combines** multiple strings using the `+` operator +- **Joins** strings directly together without spaces in the first example +- **Adds** space characters `" "` between strings for readability +- **Inserts** punctuation like commas to create proper formatting + +✅ Why does `1 + 1 = 2` in JavaScript, but `'1' + '1' = 11?` Think about it. What about `'1' + 1`? -**Template literals** offer another way to format strings. Instead of quotes, use backticks. Place anything that isn’t plain text inside `${ }`, including variables. +**Template literals** are another way to format strings, except instead of quotes, the backtick is used. Anything that is not plain text must be placed inside placeholders `${ }`. This includes any variables that may be strings. ```javascript let myString1 = "Hello"; @@ -179,37 +384,227 @@ let myString2 = "World"; `${myString1}, ${myString2}!` //Hello, World! ``` -Both methods work, but template literals preserve spaces and line breaks. - -✅ When would you use a template literal instead of a plain string? +**Let's understand each part:** +- **Uses** backticks `` ` `` instead of regular quotes to create template literals +- **Embeds** variables directly using `${}` placeholder syntax +- **Preserves** spaces and formatting exactly as written +- **Provides** a cleaner way to create complex strings with variables + +You can achieve your formatting goals with either method, but template literals will respect any spaces and line breaks. + +✅ When would you use a template literal vs. a plain string? + +### 🔤 **String Mastery Check: Text Manipulation Confidence** + +**Evaluate your string skills:** +- Can you explain why `'1' + '1'` equals `'11'` instead of `2`? +- Which string method do you find more readable: concatenation or template literals? +- What happens if you forget the quotes around a string? + +```mermaid +stateDiagram-v2 + [*] --> PlainText: "Hello" + [*] --> Variable: name = "Alice" + PlainText --> Concatenated: + " " + name + Variable --> Concatenated + PlainText --> Template: `Hello ${name}` + Variable --> Template + Concatenated --> Result: "Hello Alice" + Template --> Result + + note right of Concatenated + Traditional method + More verbose + end note + + note right of Template + Modern ES6 syntax + Cleaner & more readable + end note +``` +> **Pro tip**: Template literals are generally preferred for complex string building because they're more readable and handle multi-line strings beautifully! ### Booleans -Booleans have only two possible values: `true` or `false`. They are useful for making decisions about which parts of the code should execute under certain conditions. Often, [operators](../../../../2-js-basics/1-data-types) are used to set Boolean values, and you’ll frequently see variables being initialized or updated with an operator. +Booleans represent the simplest form of data: they can only hold one of two values – `true` or `false`. This binary logic system traces back to the work of George Boole, a 19th-century mathematician who developed Boolean algebra. + +Despite their simplicity, booleans are essential for program logic. They enable your code to make decisions based on conditions – whether a user is logged in, if a button was clicked, or if certain criteria are met. + +Booleans can be only two values: `true` or `false`. Booleans can help make decisions on which lines of code should run when certain conditions are met. In many cases, [operators](../../../../2-js-basics/1-data-types) assist with setting the value of a Boolean and you will often notice and write variables being initialized or their values being updated with an operator. -- `let myTrueBool = true` -- `let myFalseBool = false` +```javascript +let myTrueBool = true; +let myFalseBool = false; +``` -✅ A variable is considered 'truthy' if it evaluates to `true`. Interestingly, in JavaScript, [all values are truthy unless explicitly defined as falsy](https://developer.mozilla.org/docs/Glossary/Truthy). +**In the above, we've:** +- **Created** a variable that stores the Boolean value `true` +- **Demonstrated** how to store the Boolean value `false` +- **Used** the exact keywords `true` and `false` (no quotes needed) +- **Prepared** these variables for use in conditional statements + +✅ A variable can be considered 'truthy' if it evaluates to a boolean `true`. Interestingly, in JavaScript, [all values are truthy unless defined as falsy](https://developer.mozilla.org/docs/Glossary/Truthy). + +```mermaid +flowchart LR + A["🔘 Boolean Values"] --> B["true"] + A --> C["false"] + + D["Truthy Values"] --> D1["'hello'"] + D --> D2["42"] + D --> D3["[]"] + D --> D4["{}"] + + E["Falsy Values"] --> E1["false"] + E --> E2["0"] + E --> E3["''"] + E --> E4["null"] + E --> E5["undefined"] + E --> E6["NaN"] + + style B fill:#e8f5e8 + style C fill:#ffebee + style D fill:#e3f2fd + style E fill:#fff3e0 +``` +### 🎯 **Boolean Logic Check: Decision Making Skills** + +**Test your boolean understanding:** +- Why do you think JavaScript has "truthy" and "falsy" values beyond just `true` and `false`? +- Can you predict which of these is falsy: `0`, `"0"`, `[]`, `"false"`? +- How might booleans be useful in controlling program flow? + +```mermaid +pie title "Common Boolean Use Cases" + "Conditional Logic" : 40 + "User State" : 25 + "Feature Toggles" : 20 + "Validation" : 15 +``` +> **Remember**: In JavaScript, only 6 values are falsy: `false`, `0`, `""`, `null`, `undefined`, and `NaN`. Everything else is truthy! --- +## 📊 **Your Data Types Toolkit Summary** + +```mermaid +graph TD + A["🎯 JavaScript Data Types"] --> B["📦 Variables"] + A --> C["🔢 Numbers"] + A --> D["📝 Strings"] + A --> E["🔘 Booleans"] + + B --> B1["let mutable"] + B --> B2["const immutable"] + + C --> C1["42, 3.14, -5"] + C --> C2["+ - * / %"] + + D --> D1["'quotes' or \\\"quotes\\\""] + D --> D2["`template literals`"] + + E --> E1["true or false"] + E --> E2["truthy vs falsy"] + + F["⚡ Key Concepts"] --> F1["Type matters for operations"] + F --> F2["JavaScript is dynamically typed"] + F --> F3["Variables can change types"] + F --> F4["Naming is case-sensitive"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 + style F fill:#fce4ec +``` +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Create a personal information manager that demonstrates all the JavaScript data types you've learned in this lesson while handling real-world data scenarios. + +**Prompt:** Build a JavaScript program that creates a user profile object containing: a person's name (string), age (number), is a student status (boolean), favorite colors as an array, and an address object with street, city, and zip code properties. Include functions to display the profile information and update individual fields. Make sure to demonstrate string concatenation, template literals, arithmetic operations with the age, and boolean logic for the student status. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + ## 🚀 Challenge -JavaScript is known for its quirky behavior with data types. Research some of these 'gotchas'. For example: case sensitivity can be tricky! Try this in your console: `let age = 1; let Age = 2; age == Age` (it resolves to `false`—why?). What other surprises can you find? +JavaScript has some behaviors that can catch developers off guard. Here's a classic example to explore: try typing this in your browser console: `let age = 1; let Age = 2; age == Age` and observe the result. It returns `false` – can you determine why? + +This represents one of many JavaScript behaviors worth understanding. Familiarity with these quirks will help you write more reliable code and debug issues more effectively. ## Post-Lecture Quiz [Post-lecture quiz](https://ff-quizzes.netlify.app) ## Review & Self Study -Check out [this list of JavaScript exercises](https://css-tricks.com/snippets/javascript/) and try one. What did you learn? +Take a look at [this list of JavaScript exercises](https://css-tricks.com/snippets/javascript/) and try one. What did you learn? ## Assignment [Data Types Practice](assignment.md) +## 🚀 Your JavaScript Data Types Mastery Timeline + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open your browser console and create 3 variables with different data types +- [ ] Try the challenge: `let age = 1; let Age = 2; age == Age` and figure out why it's false +- [ ] Practice string concatenation with your name and favorite number +- [ ] Test what happens when you add a number to a string + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and review any confusing concepts +- [ ] Create a mini calculator that adds, subtracts, multiplies, and divides two numbers +- [ ] Build a simple name formatter using template literals +- [ ] Explore the differences between `==` and `===` comparison operators +- [ ] Practice converting between different data types + +### 📅 **Your Week-Long JavaScript Foundation** +- [ ] Complete the assignment with confidence and creativity +- [ ] Create a personal profile object using all data types learned +- [ ] Practice with [JavaScript exercises from CSS-Tricks](https://css-tricks.com/snippets/javascript/) +- [ ] Build a simple form validator using boolean logic +- [ ] Experiment with array and object data types (preview of coming lessons) +- [ ] Join a JavaScript community and ask questions about data types + +### 🌟 **Your Month-Long Transformation** +- [ ] Integrate data type knowledge into larger programming projects +- [ ] Understand when and why to use each data type in real applications +- [ ] Help other beginners understand JavaScript fundamentals +- [ ] Build a small application that manages different types of user data +- [ ] Explore advanced data type concepts like type coercion and strict equality +- [ ] Contribute to open source JavaScript projects with documentation improvements + +### 🧠 **Final Data Types Mastery Check-in** + +**Celebrate your JavaScript foundation:** +- Which data type surprised you the most in terms of its behavior? +- How comfortable do you feel explaining variables vs. constants to a friend? +- What's the most interesting thing you discovered about JavaScript's type system? +- Which real-world application can you imagine building with these fundamentals? + +```mermaid +journey + title Your JavaScript Confidence Journey + section Today + Confused: 3: You + Curious: 4: You + Excited: 5: You + section This Week + Practicing: 4: You + Understanding: 5: You + Building: 5: You + section Next Month + Problem Solving: 5: You + Teaching Others: 5: You + Real Projects: 5: You +``` +> 💡 **You've built the foundation!** Understanding data types is like learning the alphabet before writing stories. Every JavaScript program you'll ever write will use these fundamental concepts. You now have the building blocks to create interactive websites, dynamic applications, and solve real-world problems with code. Welcome to the wonderful world of JavaScript! 🎉 + --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/2-js-basics/1-data-types/assignment.md b/translations/en/2-js-basics/1-data-types/assignment.md index 07ac644b7..436954cc6 100644 --- a/translations/en/2-js-basics/1-data-types/assignment.md +++ b/translations/en/2-js-basics/1-data-types/assignment.md @@ -1,25 +1,94 @@ - -# Data Types Practice +# Data Types Practice: E-commerce Shopping Cart ## Instructions -Imagine you are creating a shopping cart. Write documentation on the data types you would need to enhance the shopping experience. For each data type, explain its purpose and usage, and provide an example. The six JavaScript data types are: String, Number, Boolean, Null, Undefined, and Object. +Imagine you are building a modern e-commerce shopping cart system. This assignment will help you understand how different JavaScript data types work together to create real-world applications. + +### Your Task + +Create a comprehensive analysis of how you would use JavaScript data types in a shopping cart application. For each of the seven primitive data types and objects, you need to: + +1. **Identify** the data type and its purpose +2. **Explain** why this data type is the best choice for specific shopping cart features +3. **Provide** realistic code examples showing the data type in action +4. **Describe** how this data type interacts with other parts of the shopping cart + +### Required Data Types to Cover + +**Primitive Data Types:** +- **String**: Product names, descriptions, user information +- **Number**: Prices, quantities, tax calculations +- **Boolean**: Item availability, user preferences, cart status +- **Null**: Intentionally empty values (like missing discount codes) +- **Undefined**: Uninitialized values or missing data +- **Symbol**: Unique identifiers (advanced use) +- **BigInt**: Large financial calculations (advanced use) + +**Reference Types:** +- **Object**: Product details, user profiles, cart contents +- **Array**: List of products, order history, categories + +### Example Format for Each Data Type + +For each data type, structure your response like this: + +```markdown +## [Data Type Name] + +**Purpose in Shopping Cart:** [Explain what this data type does] + +**Why This Type:** [Explain why this is the best choice] + +**Code Example:** +```javascript +// Your realistic code example here +``` + +**Real-world Usage:** [Describe how this would work in practice] + +**Interactions:** [Explain how this data type works with others] +``` + +### Bonus Challenges + +1. **Type Coercion**: Show an example where JavaScript automatically converts between data types in your shopping cart (e.g., string "5" + number 10) + +2. **Data Validation**: Demonstrate how you would check if user input is the correct data type before processing + +3. **Performance Considerations**: Explain when you might choose one data type over another for performance reasons + +### Submission Guidelines + +- Create a markdown document with clear headings for each data type +- Include working JavaScript code examples +- Use realistic e-commerce scenarios in your examples +- Explain your reasoning clearly for beginners to understand +- Test your code examples to ensure they work correctly ## Rubric -Criteria | Exemplary | Adequate | Needs Improvement ---- | --- | --- | --- | -Data Types | All six data types are listed, thoroughly explained, and accompanied by examples | Four data types are explained with some detail | Two data types are briefly mentioned with minimal explanation | +| Criteria | Exemplary (90-100%) | Proficient (80-89%) | Developing (70-79%) | Needs Improvement (Below 70%) | +|----------|---------------------|---------------------|---------------------|------------------------------| +| **Data Type Coverage** | All 7 primitive types and objects/arrays covered with detailed explanations | 6-7 data types covered with good explanations | 4-5 data types covered with basic explanations | Fewer than 4 data types or minimal explanations | +| **Code Examples** | All examples are realistic, working, and well-commented | Most examples work and are relevant to e-commerce | Some examples work but may be generic | Code examples are incomplete or non-functional | +| **Real-world Application** | Clearly connects each data type to practical shopping cart features | Good connection to e-commerce scenarios | Some connection to shopping cart context | Limited real-world application demonstrated | +| **Technical Accuracy** | All technical information is correct and demonstrates deep understanding | Most technical information is accurate | Generally accurate with minor errors | Contains significant technical errors | +| **Communication** | Explanations are clear, beginner-friendly, and well-organized | Good explanations that are mostly clear | Explanations are understandable but may lack clarity | Explanations are unclear or poorly organized | +| **Bonus Elements** | Includes multiple bonus challenges with excellent execution | Includes one or more bonus challenges well done | Attempts bonus challenges with mixed success | No bonus challenges attempted | + +### Learning Objectives + +By completing this assignment, you will: +- ✅ **Understand** the seven JavaScript primitive data types and their uses +- ✅ **Apply** data types to real-world programming scenarios +- ✅ **Analyze** when to choose specific data types for different purposes +- ✅ **Create** working code examples that demonstrate data type usage +- ✅ **Explain** technical concepts in beginner-friendly language +- ✅ **Connect** fundamental programming concepts to practical applications --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/2-js-basics/2-functions-methods/README.md b/translations/en/2-js-basics/2-functions-methods/README.md index 5018fdf2b..9ad50ba08 100644 --- a/translations/en/2-js-basics/2-functions-methods/README.md +++ b/translations/en/2-js-basics/2-functions-methods/README.md @@ -1,21 +1,32 @@ - # JavaScript Basics: Methods and Functions -![JavaScript Basics - Functions](../../../../translated_images/en/webdev101-js-functions.be049c4726e94f8b7605c36330ac42eeb5cd8ed02bcdd60fdac778174d6cb865.png) +![JavaScript Basics - Functions](../../../../translated_images/en/webdev101-js-functions.be049c4726e94f8b.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) +```mermaid +journey + title Your JavaScript Functions Adventure + section Foundation + Function Syntax: 5: You + Calling Functions: 4: You + Parameters & Arguments: 5: You + section Advanced Concepts + Return Values: 4: You + Default Parameters: 5: You + Function Composition: 4: You + section Modern JavaScript + Arrow Functions: 5: You + Anonymous Functions: 4: You + Higher-Order Functions: 5: You +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app) -When writing code, we always want to ensure it’s easy to read. While it might seem counterintuitive, code is read far more often than it’s written. One essential tool in a developer’s toolbox for creating maintainable code is the **function**. +Writing the same code repeatedly is one of programming's most common frustrations. Functions solve this problem by letting you package code into reusable blocks. Think of functions like the standardized parts that made Henry Ford's assembly line revolutionary – once you create a reliable component, you can use it wherever needed without rebuilding from scratch. + +Functions allow you to bundle pieces of code so you can reuse them throughout your program. Instead of copying and pasting the same logic everywhere, you can create a function once and call it whenever needed. This approach keeps your code organized and makes updates much easier. + +In this lesson, you'll learn how to create your own functions, pass information to them, and get useful results back. You'll discover the difference between functions and methods, learn modern syntax approaches, and see how functions can work with other functions. We'll build these concepts step by step. [![Methods and Functions](https://img.youtube.com/vi/XgKsD6Zwvlc/0.jpg)](https://youtube.com/watch?v=XgKsD6Zwvlc "Methods and Functions") @@ -23,15 +34,49 @@ When writing code, we always want to ensure it’s easy to read. While it might > You can take this lesson on [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon)! +```mermaid +mindmap + root((JavaScript Functions)) + Basic Concepts + Declaration + Traditional syntax + Arrow function syntax + Calling + Using parentheses + Parentheses required + Parameters + Input Values + Multiple parameters + Default values + Arguments + Values passed in + Can be any type + Return Values + Output Data + return statement + Exit function + Use Results + Store in variables + Chain functions + Advanced Patterns + Higher-Order + Functions as parameters + Callbacks + Anonymous + No name needed + Inline definition +``` ## Functions -At its core, a function is a block of code that can be executed whenever needed. This is especially useful when we need to perform the same task multiple times. Instead of duplicating the logic in several places (which would make updates difficult later), we can centralize it in one location and call it whenever necessary. You can even call functions from within other functions! +A function is a self-contained block of code that performs a specific task. It encapsulates logic that you can execute whenever needed. + +Instead of writing the same code multiple times throughout your program, you can package it in a function and call that function whenever you need it. This approach keeps your code clean and makes updates much easier. Consider the maintenance challenge if you needed to change logic that was scattered across 20 different locations in your codebase. -Equally important is the ability to name a function. While this might seem trivial, the name acts as a quick way to document what the code does. Think of it like a label on a button. If I see a button labeled "Cancel timer," I immediately know it will stop the clock. +Naming your functions descriptively is essential. A well-named function communicates its purpose clearly – when you see `cancelTimer()`, you immediately understand what it does, just as a clearly labeled button tells you exactly what will happen when you click it. ## Creating and calling a function -The syntax for a function looks like this: +Let's examine how to create a function. The syntax follows a consistent pattern: ```javascript function nameOfFunction() { // function definition @@ -39,7 +84,13 @@ function nameOfFunction() { // function definition } ``` -If I wanted to create a function to display a greeting, it might look like this: +Let's break this down: +- The `function` keyword tells JavaScript "Hey, I'm creating a function!" +- `nameOfFunction` is where you give your function a descriptive name +- The parentheses `()` are where you can add parameters (we'll get to that soon) +- The curly braces `{}` contain the actual code that runs when you call the function + +Let's create a simple greeting function to see this in action: ```javascript function displayGreeting() { @@ -47,28 +98,57 @@ function displayGreeting() { } ``` -To call (or invoke) the function, we use its name followed by `()`. It’s worth noting that the function can be defined either before or after it’s called; the JavaScript compiler will locate it for you. +This function prints "Hello, world!" to the console. Once you've defined it, you can use it as many times as needed. + +To execute (or "call") your function, write its name followed by parentheses. JavaScript allows you to define your function before or after you call it – the JavaScript engine will handle the execution order. ```javascript // calling our function displayGreeting(); ``` -> **NOTE:** There’s a special type of function called a **method**, which you’ve already been using! For example, in the demo above, we used `console.log`. What makes a method different from a function is that a method is attached to an object (like `console` in this case), whereas a function is independent. Developers often use these terms interchangeably. +When you run this line, it executes all the code inside your `displayGreeting` function, displaying "Hello, world!" in your browser's console. You can call this function repeatedly. + +### 🧠 **Function Fundamentals Check: Building Your First Functions** + +**Let's see how you're feeling about basic functions:** +- Can you explain why we use curly braces `{}` in function definitions? +- What happens if you write `displayGreeting` without the parentheses? +- Why might you want to call the same function multiple times? + +```mermaid +flowchart TD + A["✏️ Define Function"] --> B["📦 Package Code"] + B --> C["🏷️ Give it a Name"] + C --> D["📞 Call When Needed"] + D --> E["🔄 Reuse Anywhere"] + + F["💡 Benefits"] --> F1["No code repetition"] + F --> F2["Easy to maintain"] + F --> F3["Clear organization"] + F --> F4["Easier testing"] + + style A fill:#e3f2fd + style E fill:#e8f5e8 + style F fill:#fff3e0 +``` +> **Note:** You've been using **methods** throughout these lessons. `console.log()` is a method – essentially a function that belongs to the `console` object. The key difference is that methods are attached to objects, while functions stand independently. Many developers use these terms interchangeably in casual conversation. ### Function best practices -Here are some best practices to keep in mind when creating functions: +Here are a few tips to help you write great functions: -- Always use descriptive names so it’s clear what the function does. -- Use **camelCasing** to combine words. -- Keep your functions focused on a specific task. +- Give your functions clear, descriptive names – your future self will thank you! +- Use **camelCasing** for multi-word names (like `calculateTotal` instead of `calculate_total`) +- Keep each function focused on doing one thing well ## Passing information to a function -To make a function more reusable, you’ll often want to pass information into it. For example, our `displayGreeting` function above only displays **Hello, world!**, which isn’t very flexible. If we want to allow someone to specify the name of the person being greeted, we can add a **parameter**. A parameter (sometimes called an **argument**) is additional information passed to a function. +Our `displayGreeting` function is limited – it can only display "Hello, world!" for everyone. Parameters allow us to make functions more flexible and useful. -Parameters are listed in the function definition within parentheses and are separated by commas, like this: +**Parameters** act like placeholders where you can insert different values each time you use the function. This way, the same function can work with different information on each call. + +You list parameters inside the parentheses when you define your function, separating multiple parameters with commas: ```javascript function name(param, param2, param3) { @@ -76,7 +156,9 @@ function name(param, param2, param3) { } ``` -We can update our `displayGreeting` function to accept a name and display it. +Each parameter acts like a placeholder – when someone calls your function, they'll provide actual values that get plugged into these spots. + +Let's update our greeting function to accept someone's name: ```javascript function displayGreeting(name) { @@ -85,16 +167,44 @@ function displayGreeting(name) { } ``` -When calling the function, we pass the parameter value inside the parentheses. +Notice how we're using backticks (`` ` ``) and `${}` to insert the name directly into our message – this is called a template literal, and it's a really handy way to build strings with variables mixed in. + +Now when we call our function, we can pass in any name: ```javascript displayGreeting('Christopher'); // displays "Hello, Christopher!" when run ``` +JavaScript takes the string `'Christopher'`, assigns it to the `name` parameter, and creates the personalized message "Hello, Christopher!" + +```mermaid +flowchart LR + A["🎯 Function Call"] --> B["📥 Parameters"] + B --> C["⚙️ Function Body"] + C --> D["📤 Result"] + + A1["displayGreeting('Alice')"] --> A + B1["name = 'Alice'"] --> B + C1["Template literal\n\`Hello, \${name}!\`"] --> C + D1["'Hello, Alice!'"] --> D + + E["🔄 Parameter Types"] --> E1["Strings"] + E --> E2["Numbers"] + E --> E3["Booleans"] + E --> E4["Objects"] + E --> E5["Functions"] + + style A fill:#e3f2fd + style C fill:#e8f5e8 + style D fill:#fff3e0 + style E fill:#f3e5f5 +``` ## Default values -We can make our function even more flexible by adding additional parameters. But what if we don’t want to require every parameter to be specified? For example, in our greeting function, we might want the name to be required (since we need to know who we’re greeting), but allow the greeting itself to be optional. If no custom greeting is provided, we can use a default value instead. To set a default value for a parameter, we assign it a value in the function definition, like this: `parameterName = 'defaultValue'`. Here’s a full example: +What if we want to make some parameters optional? That's where default values come in handy! + +Let's say we want people to be able to customize the greeting word, but if they don't specify one, we'll just use "Hello" as a fallback. You can set up default values by using the equals sign, just like setting a variable: ```javascript function displayGreeting(name, salutation='Hello') { @@ -102,7 +212,9 @@ function displayGreeting(name, salutation='Hello') { } ``` -When calling the function, we can decide whether or not to provide a value for `salutation`. +Here, `name` is still required, but `salutation` has a backup value of `'Hello'` if no one provides a different greeting. + +Now we can call this function in two different ways: ```javascript displayGreeting('Christopher'); @@ -112,19 +224,51 @@ displayGreeting('Christopher', 'Hi'); // displays "Hi, Christopher" ``` +In the first call, JavaScript uses the default "Hello" since we didn't specify a salutation. In the second call, it uses our custom "Hi" instead. This flexibility makes functions adaptable to different scenarios. + +### 🎛️ **Parameters Mastery Check: Making Functions Flexible** + +**Test your parameter understanding:** +- What's the difference between a parameter and an argument? +- Why are default values useful in real-world programming? +- Can you predict what happens if you pass more arguments than parameters? + +```mermaid +stateDiagram-v2 + [*] --> NoParams: function greet() {} + [*] --> WithParams: function greet(name) {} + [*] --> WithDefaults: function greet(name, greeting='Hi') {} + + NoParams --> Static: Same output always + WithParams --> Dynamic: Changes with input + WithDefaults --> Flexible: Optional customization + + Static --> [*] + Dynamic --> [*] + Flexible --> [*] + + note right of WithDefaults + Most flexible approach + Backwards compatible + end note +``` +> **Pro tip**: Default parameters make your functions more user-friendly. Users can get started quickly with sensible defaults, but still customize when needed! + ## Return values -So far, the functions we’ve created always output to the [console](https://developer.mozilla.org/docs/Web/API/console). This is fine for some cases, especially when creating functions that interact with other services. But what if we want a function to perform a calculation and return the result so we can use it elsewhere? +Our functions so far have just been printing messages to the console, but what if you want a function to calculate something and give you back the result? -This is where **return values** come in. A return value is sent back by the function and can be stored in a variable, just like a string or number. +That's where **return values** come in. Instead of just displaying something, a function can hand you back a value that you can store in a variable or use in other parts of your code. -If a function returns something, the `return` keyword is used. The `return` keyword expects a value or reference to be returned, like this: +To send a value back, you use the `return` keyword followed by whatever you want to return: ```javascript return myVariable; -``` +``` + +Here's something important: when a function hits a `return` statement, it immediately stops running and sends that value back to whoever called it. -We could create a function to generate a greeting message and return the result to the caller: +Let's modify our greeting function to return the message instead of printing it: ```javascript function createGreetingMessage(name) { @@ -133,19 +277,63 @@ function createGreetingMessage(name) { } ``` -When calling this function, we store the result in a variable, just as we would with a static value (e.g., `const name = 'Christopher'`). +Now instead of printing the greeting, this function creates the message and hands it back to us. + +To use the returned value, we can store it in a variable just like any other value: ```javascript const greetingMessage = createGreetingMessage('Christopher'); ``` +Now `greetingMessage` contains "Hello, Christopher" and we can use it anywhere in our code – to display it on a webpage, include it in an email, or pass it to another function. + +```mermaid +flowchart TD + A["🔧 Function Processing"] --> B{"return statement?"} + B -->|Yes| C["📤 Return Value"] + B -->|No| D["📭 Return undefined"] + + C --> E["💾 Store in Variable"] + C --> F["🔗 Use in Expression"] + C --> G["📞 Pass to Function"] + + D --> H["⚠️ Usually not useful"] + + I["📋 Return Value Uses"] --> I1["Calculate results"] + I --> I2["Validate input"] + I --> I3["Transform data"] + I --> I4["Create objects"] + + style C fill:#e8f5e8 + style D fill:#ffebee + style I fill:#e3f2fd +``` +### 🔄 **Return Values Check: Getting Results Back** + +**Evaluate your return value understanding:** +- What happens to code after a `return` statement in a function? +- Why is returning values often better than just printing to console? +- Can a function return different types of values (string, number, boolean)? + +```mermaid +pie title "Common Return Value Types" + "Strings" : 30 + "Numbers" : 25 + "Objects" : 20 + "Booleans" : 15 + "Arrays" : 10 +``` +> **Key insight**: Functions that return values are more versatile because the caller decides what to do with the result. This makes your code more modular and reusable! + ## Functions as parameters for functions -As you advance in programming, you’ll encounter functions that accept other functions as parameters. This is a handy technique, especially when we don’t know exactly when something will happen, but we know we need to perform an action in response. +Functions can be passed as parameters to other functions. While this concept may seem complex initially, it's a powerful feature that enables flexible programming patterns. + +This pattern is super common when you want to say "when something happens, do this other thing." For example, "when the timer finishes, run this code" or "when the user clicks the button, call this function." -For example, consider [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), which starts a timer and executes code when the timer ends. We need to specify what code to execute, which is a perfect job for a function! +Let's look at `setTimeout`, which is a built-in function that waits a certain amount of time and then runs some code. We need to tell it what code to run – perfect use case for passing a function! -If you run the code below, you’ll see the message **3 seconds has elapsed** after 3 seconds. +Try this code – after 3 seconds, you'll see a message: ```javascript function displayDone() { @@ -155,13 +343,15 @@ function displayDone() { setTimeout(displayDone, 3000); ``` +Notice how we pass `displayDone` (without parentheses) to `setTimeout`. We're not calling the function ourselves – we're handing it over to `setTimeout` and saying "call this in 3 seconds." + ### Anonymous functions -Let’s revisit the example above. We’re creating a function with a name that will only be used once. As our applications grow more complex, we might end up creating many single-use functions, which isn’t ideal. Fortunately, we don’t always need to give functions a name! +Sometimes you need a function for just one thing and don't want to give it a name. Think about it – if you're only using a function once, why clutter up your code with an extra name? -When passing a function as a parameter, we can skip creating it in advance and define it directly as part of the parameter. We use the `function` keyword, but we don’t assign a name. +JavaScript lets you create **anonymous functions** – functions without names that you can define right where you need them. -Here’s the rewritten code using an anonymous function: +Here's how we can rewrite our timer example using an anonymous function: ```javascript setTimeout(function() { @@ -169,13 +359,15 @@ setTimeout(function() { }, 3000); ``` -If you run this code, you’ll get the same result. We’ve created a function without giving it a name! +This achieves the same result, but the function is defined directly within the `setTimeout` call, eliminating the need for a separate function declaration. ### Fat arrow functions -Many programming languages, including JavaScript, offer a shortcut for defining functions called **arrow functions** or **fat arrow functions**. These use the `=>` symbol, which looks like an arrow—hence the name. By using `=>`, we can skip the `function` keyword. +Modern JavaScript has an even shorter way to write functions called **arrow functions**. They use `=>` (which looks like an arrow – get it?) and are super popular with developers. + +Arrow functions let you skip the `function` keyword and write more concise code. -Let’s rewrite the code one more time using a fat arrow function: +Here's our timer example using an arrow function: ```javascript setTimeout(() => { @@ -183,22 +375,94 @@ setTimeout(() => { }, 3000); ``` +The `()` is where parameters would go (empty in this case), then comes the arrow `=>`, and finally the function body in curly braces. This provides the same functionality with more concise syntax. + +```mermaid +flowchart LR + A["📝 Function Styles"] --> B["Traditional"] + A --> C["Arrow"] + A --> D["Anonymous"] + + B --> B1["function name() {}"] + B --> B2["Hoisted"] + B --> B3["Named"] + + C --> C1["const name = () => {}"] + C --> C2["Concise syntax"] + C --> C3["Modern style"] + + D --> D1["function() {}"] + D --> D2["No name"] + D --> D3["One-time use"] + + E["⏰ When to Use"] --> E1["Traditional: Reusable functions"] + E --> E2["Arrow: Short callbacks"] + E --> E3["Anonymous: Event handlers"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 +``` ### When to use each strategy -Now that you’ve seen three ways to pass a function as a parameter, you might wonder when to use each. If you know the function will be reused, define it as a regular function. If it’s only needed in one place, an anonymous function is usually the best choice. Whether you use a fat arrow function or the traditional `function` syntax is up to you, but most modern developers prefer `=>`. +When should you use each approach? A practical guideline: if you'll use the function multiple times, give it a name and define it separately. If it's for one specific use, consider an anonymous function. Both arrow functions and traditional syntax are valid choices, though arrow functions are prevalent in modern JavaScript codebases. + +### 🎨 **Function Styles Mastery Check: Choosing the Right Syntax** + +**Test your syntax understanding:** +- When might you prefer arrow functions over traditional function syntax? +- What's the main advantage of anonymous functions? +- Can you think of a situation where a named function is better than an anonymous one? + +```mermaid +quadrantChart + title Function Choice Decision Matrix + x-axis Simple --> Complex + y-axis One-time use --> Reusable + quadrant-1 Arrow Functions + quadrant-2 Named Functions + quadrant-3 Anonymous Functions + quadrant-4 Traditional Functions + + Event Handlers: [0.3, 0.2] + Utility Functions: [0.7, 0.8] + Callbacks: [0.2, 0.3] + Class Methods: [0.8, 0.7] + Mathematical Operations: [0.4, 0.6] +``` +> **Modern trend**: Arrow functions are becoming the default choice for many developers because of their concise syntax, but traditional functions still have their place! --- + + ## 🚀 Challenge -Can you explain the difference between functions and methods in one sentence? Give it a try! +Can you articulate in one sentence the difference between functions and methods? Give it a try! + +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Create a utility library of mathematical functions that demonstrates different function concepts covered in this lesson, including parameters, default values, return values, and arrow functions. + +**Prompt:** Create a JavaScript file called `mathUtils.js` that contains the following functions: +1. A function `add` that takes two parameters and returns their sum +2. A function `multiply` with default parameter values (second parameter defaults to 1) +3. An arrow function `square` that takes a number and returns its square +4. A function `calculate` that accepts another function as a parameter and two numbers, then applies the function to those numbers +5. Demonstrate calling each function with appropriate test cases + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. ## Post-Lecture Quiz [Post-lecture quiz](https://ff-quizzes.netlify.app) ## Review & Self Study -It’s worth [reading more about arrow functions](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), as they are increasingly common in modern codebases. Practice writing a function and then rewriting it using this syntax. +It's worth [reading up a little more on arrow functions](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), as they are increasingly used in code bases. Practice writing a function, and then rewriting it with this syntax. ## Assignment @@ -206,5 +470,105 @@ It’s worth [reading more about arrow functions](https://developer.mozilla.org/ --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file +## 🧰 **Your JavaScript Functions Toolkit Summary** + +```mermaid +graph TD + A["🎯 JavaScript Functions"] --> B["📋 Function Declaration"] + A --> C["📥 Parameters"] + A --> D["📤 Return Values"] + A --> E["🎨 Modern Syntax"] + + B --> B1["function name() {}"] + B --> B2["Descriptive naming"] + B --> B3["Reusable code blocks"] + + C --> C1["Input data"] + C --> C2["Default values"] + C --> C3["Multiple parameters"] + + D --> D1["return statement"] + D --> D2["Exit function"] + D --> D3["Pass data back"] + + E --> E1["Arrow functions: () =>"] + E --> E2["Anonymous functions"] + E --> E3["Higher-order functions"] + + F["⚡ Key Benefits"] --> F1["Code reusability"] + F --> F2["Better organization"] + F --> F3["Easier testing"] + F --> F4["Modular design"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 + style F fill:#fce4ec +``` +--- + +## 🚀 Your JavaScript Functions Mastery Timeline + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Write a simple function that returns your favorite number +- [ ] Create a function with two parameters that adds them together +- [ ] Try converting a traditional function to arrow function syntax +- [ ] Practice the challenge: explain the difference between functions and methods + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and review any confusing concepts +- [ ] Build the math utilities library from the GitHub Copilot challenge +- [ ] Create a function that uses another function as a parameter +- [ ] Practice writing functions with default parameters +- [ ] Experiment with template literals in function return values + +### 📅 **Your Week-Long Function Mastery** +- [ ] Complete the "Fun with Functions" assignment with creativity +- [ ] Refactor some repetitive code you've written into reusable functions +- [ ] Build a small calculator using only functions (no global variables) +- [ ] Practice arrow functions with array methods like `map()` and `filter()` +- [ ] Create a collection of utility functions for common tasks +- [ ] Study higher-order functions and functional programming concepts + +### 🌟 **Your Month-Long Transformation** +- [ ] Master advanced function concepts like closures and scope +- [ ] Build a project that heavily uses function composition +- [ ] Contribute to open source by improving function documentation +- [ ] Teach someone else about functions and different syntax styles +- [ ] Explore functional programming paradigms in JavaScript +- [ ] Create a personal library of reusable functions for future projects + +### 🏆 **Final Functions Champion Check-in** + +**Celebrate your function mastery:** +- What's the most useful function you've created so far? +- How has learning about functions changed the way you think about code organization? +- Which function syntax do you prefer and why? +- What real-world problem would you solve by writing a function? + +```mermaid +journey + title Your Function Confidence Evolution + section Today + Confused by Syntax: 3: You + Understanding Basics: 4: You + Writing Simple Functions: 5: You + section This Week + Using Parameters: 4: You + Returning Values: 5: You + Modern Syntax: 5: You + section Next Month + Function Composition: 5: You + Advanced Patterns: 5: You + Teaching Others: 5: You +``` +> 🎉 **You've mastered one of programming's most powerful concepts!** Functions are the building blocks of larger programs. Every application you'll ever build will use functions to organize, reuse, and structure code. You now understand how to package logic into reusable components, making you a more efficient and effective programmer. Welcome to the world of modular programming! 🚀 + +--- + + +**Disclaimer**: +This document has been translated using AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/2-js-basics/2-functions-methods/assignment.md b/translations/en/2-js-basics/2-functions-methods/assignment.md index e80b69a16..30e6ae7de 100644 --- a/translations/en/2-js-basics/2-functions-methods/assignment.md +++ b/translations/en/2-js-basics/2-functions-methods/assignment.md @@ -1,27 +1,73 @@ - # Fun with Functions ## Instructions -Create various functions, including ones that return a value and ones that don't. +In this assignment, you'll practice creating different types of functions to reinforce the concepts you've learned about JavaScript functions, parameters, default values, and return statements. -Try to create a function that combines regular parameters with parameters that have default values. +Create a JavaScript file called `functions-practice.js` and implement the following functions: + +### Part 1: Basic Functions +1. **Create a function called `sayHello`** that doesn't take any parameters and simply logs "Hello!" to the console. + +2. **Create a function called `introduceYourself`** that takes a `name` parameter and logs a message like "Hi, my name is [name]" to the console. + +### Part 2: Functions with Default Parameters +3. **Create a function called `greetPerson`** that takes two parameters: `name` (required) and `greeting` (optional, defaults to "Hello"). The function should log a message like "[greeting], [name]!" to the console. + +### Part 3: Functions that Return Values +4. **Create a function called `addNumbers`** that takes two parameters (`num1` and `num2`) and returns their sum. + +5. **Create a function called `createFullName`** that takes `firstName` and `lastName` parameters and returns the full name as a single string. + +### Part 4: Mix It All Together +6. **Create a function called `calculateTip`** that takes two parameters: `billAmount` (required) and `tipPercentage` (optional, defaults to 15). The function should calculate and return the tip amount. + +### Part 5: Test Your Functions +Add function calls to test each of your functions and display the results using `console.log()`. + +**Example test calls:** +```javascript +// Test your functions here +sayHello(); +introduceYourself("Sarah"); +greetPerson("Alex"); +greetPerson("Maria", "Hi"); + +const sum = addNumbers(5, 3); +console.log(`The sum is: ${sum}`); + +const fullName = createFullName("John", "Doe"); +console.log(`Full name: ${fullName}`); + +const tip = calculateTip(50); +console.log(`Tip for $50 bill: $${tip}`); +``` ## Rubric -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------- | ----------------- | -| | Solution includes two or more well-designed functions with a variety of parameters | Solution includes one functional example with limited parameters | Solution contains errors | +| Criteria | Exemplary | Adequate | Needs Improvement | +| -------- | --------- | -------- | ----------------- | +| **Function Creation** | All 6 functions are correctly implemented with proper syntax and naming conventions | 4-5 functions are correctly implemented with minor syntax issues | 3 or fewer functions implemented or major syntax errors | +| **Parameters & Default Values** | Correctly uses required parameters, optional parameters, and default values as specified | Uses parameters correctly but may have issues with default values | Incorrect or missing parameter implementation | +| **Return Values** | Functions that should return values do so correctly, and functions that shouldn't return values only perform actions | Most return values are correct with minor issues | Significant problems with return statements | +| **Code Quality** | Clean, well-organized code with meaningful variable names and proper indentation | Code works but could be cleaner or better organized | Code is difficult to read or poorly structured | +| **Testing** | All functions are tested with appropriate function calls and results are displayed clearly | Most functions are tested adequately | Limited or incorrect testing of functions | + +## Bonus Challenges (Optional) + +If you want to challenge yourself further: + +1. **Create an arrow function version** of one of your functions +2. **Create a function that accepts another function as a parameter** (like the `setTimeout` examples from the lesson) +3. **Add input validation** to ensure your functions handle invalid inputs gracefully + +--- + +> 💡 **Tip**: Remember to open your browser's developer console (F12) to see the output of your `console.log()` statements! --- + **Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/2-js-basics/3-making-decisions/README.md b/translations/en/2-js-basics/3-making-decisions/README.md index 56ec92ad7..eea52ef9a 100644 --- a/translations/en/2-js-basics/3-making-decisions/README.md +++ b/translations/en/2-js-basics/3-making-decisions/README.md @@ -1,23 +1,36 @@ - # JavaScript Basics: Making Decisions -![JavaScript Basics - Making decisions](../../../../translated_images/en/webdev101-js-decisions.69e1b20f272dd1f0b1cb2f8adaff3ed2a77c4f91db96d8a0594132a353fa189a.png) +![JavaScript Basics - Making decisions](../../../../translated_images/en/webdev101-js-decisions.69e1b20f272dd1f0.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) +```mermaid +journey + title Your JavaScript Decision-Making Adventure + section Foundation + Boolean Values: 5: You + Comparison Operators: 4: You + Logical Thinking: 5: You + section Basic Decisions + If Statements: 4: You + If-Else Logic: 5: You + Switch Statements: 4: You + section Advanced Logic + Logical Operators: 5: You + Complex Conditions: 4: You + Ternary Expressions: 5: You +``` +Have you ever wondered how applications make smart decisions? Like how a navigation system chooses the fastest route, or how a thermostat decides when to turn on the heat? This is the fundamental concept of decision-making in programming. + +Just as Charles Babbage's Analytical Engine was designed to follow different sequences of operations based on conditions, modern JavaScript programs need to make choices based on varying circumstances. This ability to branch and make decisions is what transforms static code into responsive, intelligent applications. + +In this lesson, you'll learn how to implement conditional logic in your programs. We'll explore conditional statements, comparison operators, and logical expressions that allow your code to evaluate situations and respond appropriately. + ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/11) -Making decisions and controlling the flow of your code makes it reusable and reliable. This section explains the syntax for managing data flow in JavaScript and its importance when working with Boolean data types. +The ability to make decisions and control program flow is a fundamental aspect of programming. This section covers how to control the execution path of your JavaScript programs using Boolean values and conditional logic. [![Making Decisions](https://img.youtube.com/vi/SxTp8j-fMMY/0.jpg)](https://youtube.com/watch?v=SxTp8j-fMMY "Making Decisions") @@ -25,76 +38,226 @@ Making decisions and controlling the flow of your code makes it reusable and rel > You can take this lesson on [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-if-else/?WT.mc_id=academic-77807-sagibbon)! +```mermaid +mindmap + root((Decision Making)) + Boolean Logic + true/false + Comparison results + Logical expressions + Conditional Statements + if statements + Single condition + Code execution + if-else + Two paths + Alternative actions + switch + Multiple options + Clean structure + Operators + Comparison + === !== < > <= >= + Value relationships + Logical + && || ! + Combine conditions + Advanced Patterns + Ternary + ? : syntax + Inline decisions + Complex Logic + Nested conditions + Multiple criteria +``` ## A Brief Recap on Booleans -Booleans can only have two values: `true` or `false`. They are used to decide which lines of code should execute based on specific conditions. +Before exploring decision-making, let's revisit Boolean values from our previous lesson. Named after mathematician George Boole, these values represent binary states – either `true` or `false`. There's no ambiguity, no middle ground. -You can set a Boolean value like this: +These binary values form the foundation of all computational logic. Every decision your program makes ultimately reduces to a Boolean evaluation. -`let myTrueBool = true` -`let myFalseBool = false` +Creating Boolean variables is straightforward: -✅ Booleans are named after George Boole, an English mathematician, philosopher, and logician (1815–1864). +```javascript +let myTrueBool = true; +let myFalseBool = false; +``` + +This creates two variables with explicit Boolean values. + +✅ Booleans are named after the English mathematician, philosopher and logician George Boole (1815–1864). ## Comparison Operators and Booleans -Operators are used to evaluate conditions by comparing values, resulting in a Boolean value. Below is a list of commonly used operators: +In practice, you'll rarely set Boolean values manually. Instead, you'll generate them by evaluating conditions: "Is this number greater than that one?" or "Are these values equal?" + +Comparison operators enable these evaluations. They compare values and return Boolean results based on the relationship between the operands. | Symbol | Description | Example | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `<` | **Less than**: Compares two values and returns `true` if the value on the left is smaller than the value on the right | `5 < 6 // true` | -| `<=` | **Less than or equal to**: Compares two values and returns `true` if the value on the left is smaller than or equal to the value on the right | `5 <= 6 // true` | -| `>` | **Greater than**: Compares two values and returns `true` if the value on the left is larger than the value on the right | `5 > 6 // false` | -| `>=` | **Greater than or equal to**: Compares two values and returns `true` if the value on the left is larger than or equal to the value on the right | `5 >= 6 // false` | -| `===` | **Strict equality**: Compares two values and returns `true` if both values are equal and of the same data type | `5 === 6 // false` | +| `<` | **Less than**: Compares two values and returns the `true` Boolean data type if the value on the left side is less than the right | `5 < 6 // true` | +| `<=` | **Less than or equal to**: Compares two values and returns the `true` Boolean data type if the value on the left side is less than or equal to the right | `5 <= 6 // true` | +| `>` | **Greater than**: Compares two values and returns the `true` Boolean data type if the value on the left side is larger than the right | `5 > 6 // false` | +| `>=` | **Greater than or equal to**: Compares two values and returns the `true` Boolean data type if the value on the left side is larger than or equal to the right | `5 >= 6 // false` | +| `===` | **Strict equality**: Compares two values and returns the `true` Boolean data type if values on the right and left are equal AND are the same data type. | `5 === 6 // false` | | `!==` | **Inequality**: Compares two values and returns the opposite Boolean value of what a strict equality operator would return | `5 !== 6 // true` | -✅ Test your understanding by writing some comparisons in your browser's console. Were any results unexpected? +✅ Check your knowledge by writing some comparisons in your browser's console. Does any returned data surprise you? + +```mermaid +flowchart LR + A["🔢 Values"] --> B["⚖️ Comparison"] + B --> C["✅ Boolean Result"] + + D["5"] --> E["< 6"] + E --> F["true"] + + G["10"] --> H["=== '10'"] + H --> I["false"] + + J["'hello'"] --> K["!== 'world'"] + K --> L["true"] + + M["📋 Operator Types"] --> M1["Equality: === !=="] + M --> M2["Relational: < > <= >="] + M --> M3["Strict vs Loose"] + + style A fill:#e3f2fd + style C fill:#e8f5e8 + style M fill:#fff3e0 +``` +### 🧠 **Comparison Mastery Check: Understanding Boolean Logic** + +**Test your comparison understanding:** +- Why do you think `===` (strict equality) is generally preferred over `==` (loose equality)? +- Can you predict what `5 === '5'` returns? How about `5 == '5'`? +- What's the difference between `!==` and `!=`? + +```mermaid +stateDiagram-v2 + [*] --> Comparison: Two values + Comparison --> StrictEqual: === or !== + Comparison --> Relational: < > <= >= + + StrictEqual --> TypeCheck: Check type AND value + Relational --> NumberCompare: Convert to numbers + + TypeCheck --> BooleanResult: true or false + NumberCompare --> BooleanResult + + note right of StrictEqual + Preferred approach + No type conversion + end note + + note right of Relational + Useful for ranges + Numerical comparisons + end note +``` +> **Pro tip**: Always use `===` and `!==` for equality checks unless you specifically need type conversion. This prevents unexpected behavior! ## If Statement -The `if` statement executes the code within its block if the condition evaluates to `true`. +The `if` statement is like asking a question in your code. "If this condition is true, then do this thing." It's probably the most important tool you'll use for making decisions in JavaScript. + +Here's how it works: ```javascript if (condition) { - //Condition is true. Code in this block will run. + // Condition is true. Code in this block will run. } ``` -Logical operators are often used to create the condition. +The condition goes inside the parentheses, and if it's `true`, JavaScript runs the code inside the curly braces. If it's `false`, JavaScript just skips that whole block. + +You'll often use comparison operators to create these conditions. Let's see a practical example: ```javascript -let currentMoney; -let laptopPrice; +let currentMoney = 1000; +let laptopPrice = 800; if (currentMoney >= laptopPrice) { - //Condition is true. Code in this block will run. + // Condition is true. Code in this block will run. console.log("Getting a new laptop!"); } ``` +Since `1000 >= 800` evaluates to `true`, the code inside the block executes, displaying "Getting a new laptop!" in the console. + +```mermaid +flowchart TD + A["🚀 Program Start"] --> B{"💰 currentMoney >= laptopPrice?"} + B -->|true| C["🎉 'Getting a new laptop!'"] + B -->|false| D["⏭️ Skip code block"] + C --> E["📋 Continue program"] + D --> E + + F["📊 If Statement Structure"] --> F1["if (condition) {"] + F1 --> F2[" // code to run if true"] + F2 --> F3["}"] + + style B fill:#fff3e0 + style C fill:#e8f5e8 + style D fill:#ffebee + style F fill:#e3f2fd +``` ## If..Else Statement -The `else` statement executes the code within its block when the condition is `false`. It is optional when using an `if` statement. +But what if you want your program to do something different when the condition is false? That's where `else` comes in – it's like having a backup plan. + +The `else` statement gives you a way to say "if this condition isn't true, do this other thing instead." ```javascript -let currentMoney; -let laptopPrice; +let currentMoney = 500; +let laptopPrice = 800; if (currentMoney >= laptopPrice) { - //Condition is true. Code in this block will run. + // Condition is true. Code in this block will run. console.log("Getting a new laptop!"); } else { - //Condition is false. Code in this block will run. + // Condition is false. Code in this block will run. console.log("Can't afford a new laptop, yet!"); } ``` -✅ Test your understanding of this code and the following code by running it in a browser console. Modify the values of the `currentMoney` and `laptopPrice` variables to see how the `console.log()` output changes. +Now since `500 >= 800` is `false`, JavaScript skips the first block and runs the `else` block instead. You'll see "Can't afford a new laptop, yet!" in the console. + +✅ Test your understanding of this code and the following code by running it in a browser console. Change the values of the currentMoney and laptopPrice variables to change the returned `console.log()`. + +### 🎯 **If-Else Logic Check: Branching Paths** + +**Evaluate your conditional logic understanding:** +- What happens if `currentMoney` exactly equals `laptopPrice`? +- Can you think of a real-world scenario where if-else logic would be useful? +- How might you extend this to handle multiple price ranges? + +```mermaid +flowchart TD + A["🔍 Evaluate Condition"] --> B{"Condition True?"} + B -->|Yes| C["📤 Execute IF block"] + B -->|No| D["📥 Execute ELSE block"] + + C --> E["✅ One path taken"] + D --> E + + F["🌐 Real-world Examples"] --> F1["User login status"] + F --> F2["Age verification"] + F --> F3["Form validation"] + F --> F4["Game state changes"] + + style B fill:#fff3e0 + style C fill:#e8f5e8 + style D fill:#e3f2fd + style F fill:#f3e5f5 +``` +> **Key insight**: If-else ensures exactly one path is taken. This guarantees your program always has a response to any condition! ## Switch Statement -The `switch` statement allows you to perform different actions based on different conditions. Use it to select one of many code blocks to execute. +Sometimes you need to compare one value against multiple options. While you could chain several `if..else` statements, this approach becomes unwieldy. The `switch` statement provides a cleaner structure for handling multiple discrete values. + +The concept resembles the mechanical switching systems used in early telephone exchanges – one input value determines which specific path the execution follows. ```javascript switch (expression) { @@ -105,61 +268,179 @@ switch (expression) { // code block break; default: - // code block + // code block } ``` +Here's how it's structured: +- JavaScript evaluates the expression once +- It looks through each `case` to find a match +- When it finds a match, it runs that code block +- The `break` tells JavaScript to stop and exit the switch +- If no cases match, it runs the `default` block (if you have one) + ```javascript -// program using switch statement -let a = 2; +// Program using switch statement for day of week +let dayNumber = 2; +let dayName; -switch (a) { +switch (dayNumber) { case 1: - a = "one"; + dayName = "Monday"; break; case 2: - a = "two"; + dayName = "Tuesday"; + break; + case 3: + dayName = "Wednesday"; break; default: - a = "not found"; + dayName = "Unknown day"; break; } -console.log(`The value is ${a}`); +console.log(`Today is ${dayName}`); ``` -✅ Test your understanding of this code and the following code by running it in a browser console. Modify the value of the variable `a` to see how the `console.log()` output changes. +In this example, JavaScript sees that `dayNumber` is `2`, finds the matching `case 2`, sets `dayName` to "Tuesday", and then breaks out of the switch. The result? "Today is Tuesday" gets logged to the console. + +```mermaid +flowchart TD + A["📥 switch(expression)"] --> B["🔍 Evaluate once"] + B --> C{"Match case 1?"} + C -->|Yes| D["📋 Execute case 1"] + C -->|No| E{"Match case 2?"} + E -->|Yes| F["📋 Execute case 2"] + E -->|No| G{"Match case 3?"} + G -->|Yes| H["📋 Execute case 3"] + G -->|No| I["📋 Execute default"] + + D --> J["🛑 break"] + F --> K["🛑 break"] + H --> L["🛑 break"] + + J --> M["✅ Exit switch"] + K --> M + L --> M + I --> M + + style A fill:#e3f2fd + style B fill:#fff3e0 + style M fill:#e8f5e8 +``` +✅ Test your understanding of this code and the following code by running it in a browser console. Change the values of the variable a to change the returned `console.log()`. + +### 🔄 **Switch Statement Mastery: Multiple Options** + +**Test your switch understanding:** +- What happens if you forget a `break` statement? +- When would you use `switch` instead of multiple `if-else` statements? +- Why is the `default` case useful even if you think you've covered all possibilities? + +```mermaid +pie title "When to Use Each Decision Structure" + "Simple if-else" : 40 + "Complex if-else chains" : 25 + "Switch statements" : 20 + "Ternary operators" : 15 +``` +> **Best practice**: Use `switch` when comparing one variable against multiple specific values. Use `if-else` for range checks or complex conditions! ## Logical Operators and Booleans -Sometimes decisions require multiple comparisons, which can be combined using logical operators to produce a Boolean value. +Complex decisions often require evaluating multiple conditions simultaneously. Just as Boolean algebra allows mathematicians to combine logical expressions, programming provides logical operators to connect multiple Boolean conditions. + +These operators enable sophisticated conditional logic by combining simple true/false evaluations. | Symbol | Description | Example | | ------ | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | -| `&&` | **Logical AND**: Compares two Boolean expressions. Returns `true` **only** if both sides are true | `(5 > 6) && (5 < 6) // One side is false, the other is true. Returns false` | -| `\|\|` | **Logical OR**: Compares two Boolean expressions. Returns `true` if at least one side is true | `(5 > 6) \|\| (5 < 6) // One side is false, the other is true. Returns true` | -| `!` | **Logical NOT**: Returns the opposite value of a Boolean expression | `!(5 > 6) // 5 is not greater than 6, but "!" will return true` | - +| `&&` | **Logical AND**: Compares two Boolean expressions. Returns true **only** if both sides are true | `(5 > 3) && (5 < 10) // Both sides are true. Returns true` | +| `\|\|` | **Logical OR**: Compares two Boolean expressions. Returns true if at least one side is true | `(5 > 10) \|\| (5 < 10) // One side is false, other is true. Returns true` | +| `!` | **Logical NOT**: Returns the opposite value of a Boolean expression | `!(5 > 10) // 5 is not greater than 10, so "!" makes it true` | + +These operators let you combine conditions in useful ways: +- AND (`&&`) means both conditions must be true +- OR (`||`) means at least one condition must be true +- NOT (`!`) flips true to false (and vice versa) + +```mermaid +flowchart LR + A["🔗 Logical Operators"] --> B["&& AND"] + A --> C["|| OR"] + A --> D["! NOT"] + + B --> B1["Both must be true"] + B --> B2["true && true = true"] + B --> B3["true && false = false"] + + C --> C1["At least one true"] + C --> C2["true || false = true"] + C --> C3["false || false = false"] + + D --> D1["Flips the value"] + D --> D2["!true = false"] + D --> D3["!false = true"] + + E["🌍 Real Examples"] --> E1["Age >= 18 && hasLicense"] + E --> E2["isWeekend || isHoliday"] + E --> E3["!isLoggedIn"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 +``` ## Conditions and Decisions with Logical Operators -Logical operators can be used to create conditions in `if..else` statements. +Let's see these logical operators in action with a more realistic example: ```javascript -let currentMoney; -let laptopPrice; -let laptopDiscountPrice = laptopPrice - laptopPrice * 0.2; //Laptop price at 20 percent off +let currentMoney = 600; +let laptopPrice = 800; +let laptopDiscountPrice = laptopPrice - (laptopPrice * 0.2); // Laptop price at 20 percent off if (currentMoney >= laptopPrice || currentMoney >= laptopDiscountPrice) { - //Condition is true. Code in this block will run. + // Condition is true. Code in this block will run. console.log("Getting a new laptop!"); } else { - //Condition is true. Code in this block will run. + // Condition is false. Code in this block will run. console.log("Can't afford a new laptop, yet!"); } ``` +In this example: we calculate a 20% discount price (640), then evaluate whether our available funds cover either the full price OR the discounted price. Since 600 meets the discounted price threshold of 640, the condition evaluates to true. + +### 🧮 **Logical Operators Check: Combining Conditions** + +**Test your logical operator understanding:** +- In the expression `A && B`, what happens if A is false? Does B even get evaluated? +- Can you think of a situation where you'd need all three operators (&&, ||, !) together? +- What's the difference between `!user.isActive` and `user.isActive !== true`? + +```mermaid +stateDiagram-v2 + [*] --> EvaluateA: A && B + EvaluateA --> CheckB: A is true + EvaluateA --> ReturnFalse: A is false + CheckB --> ReturnTrue: B is true + CheckB --> ReturnFalse: B is false + + [*] --> EvaluateC: A || B + EvaluateC --> ReturnTrue: A is true + EvaluateC --> CheckD: A is false + CheckD --> ReturnTrue: B is true + CheckD --> ReturnFalse: B is false + + note right of EvaluateA + Short-circuit evaluation: + If A is false, B is never checked + end note +``` +> **Performance tip**: JavaScript uses "short-circuit evaluation" - in `A && B`, if A is false, B isn't even evaluated. Use this to your advantage! + ### Negation Operator -You've seen how `if...else` statements can be used to create conditional logic. Anything inside an `if` must evaluate to `true` or `false`. The `!` operator allows you to _negate_ an expression, like this: +Sometimes it's easier to think about when something is NOT true. Like instead of asking "Is the user logged in?", you might want to ask "Is the user NOT logged in?" The exclamation mark (`!`) operator flips the logic for you. ```javascript if (!condition) { @@ -169,15 +450,19 @@ if (!condition) { } ``` +The `!` operator is like saying "the opposite of..." – if something is `true`, `!` makes it `false`, and vice versa. + ### Ternary Expressions -`if...else` isn't the only way to express decision-making logic. You can also use a ternary operator, which has the following syntax: +For simple conditional assignments, JavaScript provides the **ternary operator**. This concise syntax allows you to write a conditional expression in a single line, useful when you need to assign one of two values based on a condition. ```javascript -let variable = condition ? : +let variable = condition ? returnThisIfTrue : returnThisIfFalse; ``` -Here's a more practical example: +It reads like a question: "Is this condition true? If yes, use this value. If no, use that value." + +Below is a more tangible example: ```javascript let firstNumber = 20; @@ -185,15 +470,11 @@ let secondNumber = 10; let biggestNumber = firstNumber > secondNumber ? firstNumber : secondNumber; ``` -✅ Take a moment to read this code carefully. Do you understand how these operators work? - -The example above states: +✅ Take a minute to read this code a few times. Do you understand how these operators are working? -- If `firstNumber` is greater than `secondNumber`, - assign `firstNumber` to `biggestNumber`. -- Otherwise, assign `secondNumber`. +Here's what this line is saying: "Is `firstNumber` greater than `secondNumber`? If yes, put `firstNumber` in `biggestNumber`. If no, put `secondNumber` in `biggestNumber`." -The ternary expression is simply a compact way of writing the following code: +The ternary operator is just a shorter way to write this traditional `if..else` statement: ```javascript let biggestNumber; @@ -204,29 +485,179 @@ if (firstNumber > secondNumber) { } ``` +Both approaches produce identical results. The ternary operator offers conciseness, while the traditional if-else structure may be more readable for complex conditions. + +```mermaid +flowchart LR + A["🤔 Ternary Operator"] --> B["condition ?"] + B --> C["valueIfTrue :"] + C --> D["valueIfFalse"] + + E["📝 Traditional If-Else"] --> F["if (condition) {"] + F --> G[" return valueIfTrue"] + G --> H["} else {"] + H --> I[" return valueIfFalse"] + I --> J["}"] + + K["⚡ When to Use"] --> K1["Simple assignments"] + K --> K2["Short conditions"] + K --> K3["Inline decisions"] + K --> K4["Return statements"] + + style A fill:#e3f2fd + style E fill:#fff3e0 + style K fill:#e8f5e8 +``` --- -## 🚀 Challenge - -Write a program using logical operators, then rewrite it using a ternary expression. Which syntax do you prefer? - ---- - -## Post-Lecture Quiz - -[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/12) -## Review & Self Study -Learn more about the various operators available to you [on MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators). +## 🚀 Challenge -Check out Josh Comeau's excellent [operator lookup](https://joshwcomeau.com/operator-lookup/)! +Create a program that is written first with logical operators, and then rewrite it using a ternary expression. What's your preferred syntax? -## Assignment +--- -[Operators](assignment.md) +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Create a comprehensive grade calculator that demonstrates multiple decision-making concepts from this lesson, including if-else statements, switch statements, logical operators, and ternary expressions. + +**Prompt:** Write a JavaScript program that takes a student's numerical score (0-100) and determines their letter grade using the following criteria: +- A: 90-100 +- B: 80-89 +- C: 70-79 +- D: 60-69 +- F: Below 60 + +Requirements: +1. Use an if-else statement to determine the letter grade +2. Use logical operators to check if the student passes (grade >= 60) AND has honors (grade >= 90) +3. Use a switch statement to provide specific feedback for each letter grade +4. Use a ternary operator to determine if the student is eligible for the next course (grade >= 70) +5. Include input validation to ensure the score is between 0 and 100 + +Test your program with various scores including edge cases like 59, 60, 89, 90, and invalid inputs. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + + +## Post-Lecture Quiz + +[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/12) + +## Review & Self Study + +Read more about the many operators available to the user [on MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators). + +Go through Josh Comeau's wonderful [operator lookup](https://joshwcomeau.com/operator-lookup/)! + +## Assignment + +[Operators](assignment.md) + +--- + +## 🧠 **Your Decision-Making Toolkit Summary** + +```mermaid +graph TD + A["🎯 JavaScript Decisions"] --> B["🔍 Boolean Logic"] + A --> C["📊 Conditional Statements"] + A --> D["🔗 Logical Operators"] + A --> E["⚡ Advanced Patterns"] + + B --> B1["true/false values"] + B --> B2["Comparison operators"] + B --> B3["Truthiness concepts"] + + C --> C1["if statements"] + C --> C2["if-else chains"] + C --> C3["switch statements"] + + D --> D1["&& (AND)"] + D --> D2["|| (OR)"] + D --> D3["! (NOT)"] + + E --> E1["Ternary operator"] + E --> E2["Short-circuit evaluation"] + E --> E3["Complex conditions"] + + F["💡 Key Principles"] --> F1["Clear readable conditions"] + F --> F2["Consistent comparison style"] + F --> F3["Proper operator precedence"] + F --> F4["Efficient evaluation order"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 + style F fill:#fce4ec +``` +--- + +## 🚀 Your JavaScript Decision-Making Mastery Timeline + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Practice comparison operators in your browser console +- [ ] Write a simple if-else statement that checks your age +- [ ] Try the challenge: rewrite an if-else using a ternary operator +- [ ] Test what happens with different "truthy" and "falsy" values + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and review any confusing concepts +- [ ] Build the comprehensive grade calculator from the GitHub Copilot challenge +- [ ] Create a simple decision tree for a real-world scenario (like choosing what to wear) +- [ ] Practice combining multiple conditions with logical operators +- [ ] Experiment with switch statements for different use cases + +### 📅 **Your Week-Long Logic Mastery** +- [ ] Complete the operators assignment with creative examples +- [ ] Build a mini quiz application using various conditional structures +- [ ] Create a form validator that checks multiple input conditions +- [ ] Practice Josh Comeau's [operator lookup](https://joshwcomeau.com/operator-lookup/) exercises +- [ ] Refactor existing code to use more appropriate conditional structures +- [ ] Study short-circuit evaluation and performance implications + +### 🌟 **Your Month-Long Transformation** +- [ ] Master complex nested conditions and maintain code readability +- [ ] Build an application with sophisticated decision-making logic +- [ ] Contribute to open source by improving conditional logic in existing projects +- [ ] Teach someone else about different conditional structures and when to use each +- [ ] Explore functional programming approaches to conditional logic +- [ ] Create a personal reference guide for conditional best practices + +### 🏆 **Final Decision-Making Champion Check-in** + +**Celebrate your logical thinking mastery:** +- What's the most complex decision logic you've successfully implemented? +- Which conditional structure feels most natural to you and why? +- How has learning about logical operators changed your problem-solving approach? +- What real-world application would benefit from sophisticated decision-making logic? + +```mermaid +journey + title Your Logical Thinking Evolution + section Today + Boolean Confusion: 3: You + If-Else Understanding: 4: You + Operator Recognition: 5: You + section This Week + Complex Conditions: 4: You + Switch Mastery: 5: You + Logical Combinations: 5: You + section Next Month + Advanced Patterns: 5: You + Performance Awareness: 5: You + Teaching Others: 5: You +``` +> 🧠 **You've mastered the art of digital decision-making!** Every interactive application relies on conditional logic to respond intelligently to user actions and changing conditions. You now understand how to make your programs think, evaluate, and choose appropriate responses. This logical foundation will power every dynamic application you build! 🎉 --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/2-js-basics/3-making-decisions/assignment.md b/translations/en/2-js-basics/3-making-decisions/assignment.md index e23e23fd8..2aaff633b 100644 --- a/translations/en/2-js-basics/3-making-decisions/assignment.md +++ b/translations/en/2-js-basics/3-making-decisions/assignment.md @@ -1,54 +1,111 @@ - -# Operators +# Making Decisions: Student Grade Processor -## Instructions +## Learning Objectives -Experiment with operators. Here's an idea for a program you can create: +In this assignment, you'll practice the decision-making concepts from this lesson by building a program that processes student grades from different grading systems. You'll use `if...else` statements, comparison operators, and logical operators to determine which students pass their courses. -You have a group of students from two different grading systems. +## The Challenge -### First grading system +You work for a school that recently merged with another institution. Now you need to process student grades from two completely different grading systems and determine which students are passing. This is a perfect opportunity to practice conditional logic! -One grading system uses grades ranging from 1 to 5, where a grade of 3 or higher means the student passes the course. +### Understanding the Grading Systems -### Second grading system +#### First Grading System (Numeric) +- Grades are given as numbers from 1-5 +- **Passing grade**: 3 and above (3, 4, or 5) +- **Failing grade**: Below 3 (1 or 2) -The other grading system uses the grades `A, A-, B, B-, C, C-`, where `A` is the highest grade and `C` is the lowest passing grade. +#### Second Grading System (Letter Grades) +- Grades use letters: `A`, `A-`, `B`, `B-`, `C`, `C-` +- **Passing grades**: `A`, `A-`, `B`, `B-`, `C`, `C-` (all listed grades are passing) +- **Note**: This system doesn't include failing grades like `D` or `F` -### The task +### Your Task -Using the array `allStudents`, which represents all students and their grades, create a new array `studentsWhoPass` that includes only the students who pass. - -> TIP: Use a for-loop, if...else statements, and comparison operators: +Given the following array `allStudents` representing all students and their grades, construct a new array `studentsWhoPass` containing all students who pass according to their respective grading systems. ```javascript let allStudents = [ - 'A', - 'B-', - 1, - 4, - 5, - 2 -] + 'A', // Letter grade - passing + 'B-', // Letter grade - passing + 1, // Numeric grade - failing + 4, // Numeric grade - passing + 5, // Numeric grade - passing + 2 // Numeric grade - failing +]; let studentsWhoPass = []; ``` +### Step-by-Step Approach + +1. **Set up a loop** to go through each grade in the `allStudents` array +2. **Check the grade type** (is it a number or a string?) +3. **Apply the appropriate grading system rules**: + - For numbers: check if grade >= 3 + - For strings: check if it's one of the valid passing letter grades +4. **Add passing grades** to the `studentsWhoPass` array + +### Helpful Code Techniques + +Use these JavaScript concepts from the lesson: + +- **typeof operator**: `typeof grade === 'number'` to check if it's a numeric grade +- **Comparison operators**: `>=` to compare numeric grades +- **Logical operators**: `||` to check multiple letter grade conditions +- **if...else statements**: to handle different grading systems +- **Array methods**: `.push()` to add passing grades to your new array + +### Expected Output + +When you run your program, `studentsWhoPass` should contain: `['A', 'B-', 4, 5]` + +**Why these grades pass:** +- `'A'` and `'B-'` are valid letter grades (all letter grades in this system are passing) +- `4` and `5` are numeric grades >= 3 +- `1` and `2` fail because they're numeric grades < 3 + +## Testing Your Solution + +Test your code with different scenarios: + +```javascript +// Test with different grade combinations +let testGrades1 = ['A-', 3, 'C', 1, 'B']; +let testGrades2 = [5, 'A', 2, 'C-', 4]; + +// Your solution should work with any combination of valid grades +``` + +## Bonus Challenges + +Once you complete the basic assignment, try these extensions: + +1. **Add validation**: Check for invalid grades (like negative numbers or invalid letters) +2. **Count statistics**: Calculate how many students pass vs. fail +3. **Grade conversion**: Convert all grades to a single numeric system (A=5, B=4, C=3, etc.) + ## Rubric -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | ----------------------------- | ----------------------------- | ------------------------------- | -| | A complete solution is provided | A partial solution is provided | A solution with errors is provided | +| Criteria | Exemplary (4) | Proficient (3) | Developing (2) | Beginning (1) | +|----------|---------------|----------------|----------------|---------------| +| **Functionality** | Program correctly identifies all passing grades from both systems | Program works with minor issues or edge cases | Program partially works but has logical errors | Program has significant errors or doesn't run | +| **Code Structure** | Clean, well-organized code with proper if...else logic | Good structure with appropriate conditional statements | Acceptable structure with some organizational issues | Poor structure, difficult to follow logic | +| **Use of Concepts** | Effectively uses comparison operators, logical operators, and conditional statements | Good use of lesson concepts with minor gaps | Some use of lesson concepts but missing key elements | Limited use of lesson concepts | +| **Problem Solving** | Shows clear understanding of the problem and elegant solution approach | Good problem-solving approach with solid logic | Adequate problem-solving with some confusion | Unclear approach, doesn't demonstrate understanding | + +## Submission Guidelines + +1. **Test your code** thoroughly with the provided examples +2. **Add comments** explaining your logic, especially for the conditional statements +3. **Verify output** matches expected results: `['A', 'B-', 4, 5]` +4. **Consider edge cases** like empty arrays or unexpected data types + +> 💡 **Pro Tip**: Start simple! Get the basic functionality working first, then add more sophisticated features. Remember, the goal is to practice decision-making logic with the tools you learned in this lesson. --- + **Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/2-js-basics/4-arrays-loops/README.md b/translations/en/2-js-basics/4-arrays-loops/README.md index 71af1d6fe..f51cde494 100644 --- a/translations/en/2-js-basics/4-arrays-loops/README.md +++ b/translations/en/2-js-basics/4-arrays-loops/README.md @@ -1,141 +1,631 @@ - # JavaScript Basics: Arrays and Loops -![JavaScript Basics - Arrays](../../../../translated_images/en/webdev101-js-arrays.439d7528b8a294558d0e4302e448d193f8ad7495cc407539cc81f1afe904b470.png) +![JavaScript Basics - Arrays](../../../../translated_images/en/webdev101-js-arrays.439d7528b8a29455.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) +```mermaid +journey + title Your Arrays & Loops Adventure + section Array Fundamentals + Creating Arrays: 5: You + Accessing Elements: 4: You + Array Methods: 5: You + section Loop Mastery + For Loops: 4: You + While Loops: 5: You + Modern Syntax: 4: You + section Data Processing + Array + Loops: 5: You + Real-world Applications: 4: You + Performance Optimization: 5: You +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/13) -This lesson introduces the fundamentals of JavaScript, the programming language that adds interactivity to websites. In this lesson, you'll explore arrays and loops, which are essential for working with and manipulating data. +Ever wondered how websites keep track of shopping cart items or display your friend list? That's where arrays and loops come in. Arrays are like digital containers that hold multiple pieces of information, while loops let you work with all that data efficiently without repetitive code. + +Together, these two concepts form the foundation for handling information in your programs. You'll learn to move from manually writing out every single step to creating smart, efficient code that can process hundreds or even thousands of items quickly. + +By the end of this lesson, you'll understand how to accomplish complex data tasks with just a few lines of code. Let's explore these essential programming concepts. [![Arrays](https://img.youtube.com/vi/1U4qTyq02Xw/0.jpg)](https://youtube.com/watch?v=1U4qTyq02Xw "Arrays") [![Loops](https://img.youtube.com/vi/Eeh7pxtTZ3k/0.jpg)](https://www.youtube.com/watch?v=Eeh7pxtTZ3k "Loops") -> 🎥 Click the images above to watch videos about arrays and loops. +> 🎥 Click the images above for videos about arrays and loops. + +> You can take this lesson on [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-arrays/?WT.mc_id=academic-77807-sagibbon)! + +```mermaid +mindmap + root((Data Processing)) + Arrays + Structure + Square brackets syntax + Zero-based indexing + Dynamic sizing + Operations + push/pop + shift/unshift + indexOf/includes + Types + Numbers array + Strings array + Mixed types + Loops + For Loops + Counting iterations + Array processing + Predictable flow + While Loops + Condition-based + Unknown iterations + User input + Modern Syntax + for...of + forEach + Functional methods + Applications + Data Analysis + Statistics + Filtering + Transformations + User Interfaces + Lists + Menus + Galleries +``` +## Arrays -> You can also take this lesson on [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-arrays/?WT.mc_id=academic-77807-sagibbon)! +Think of arrays as a digital filing cabinet - instead of storing one document per drawer, you can organize multiple related items in a single, structured container. In programming terms, arrays let you store multiple pieces of information in one organized package. -## Arrays +Whether you're building a photo gallery, managing a to-do list, or keeping track of high scores in a game, arrays provide the foundation for data organization. Let's see how they work. -Handling data is a common task in programming, and it becomes much easier when the data is organized in a structured format, like arrays. Arrays store data in a list-like structure. One key advantage of arrays is that they can hold different types of data within the same array. +✅ Arrays are all around us! Can you think of a real-life example of an array, such as a solar panel array? -✅ Arrays are everywhere! Can you think of a real-world example of an array, like a solar panel array? +### Creating Arrays -The syntax for creating an array involves square brackets. +Creating an array is super simple - just use square brackets! ```javascript -let myArray = []; +// Empty array - like an empty shopping cart waiting for items +const myArray = []; ``` -This is an empty array, but arrays can also be initialized with data already inside them. Multiple values in an array are separated by commas. +**What's happening here?** +You've just created an empty container using those square brackets `[]`. Think of it like an empty library shelf - it's ready to hold whatever books you want to organize there. + +You can also fill your array with initial values right from the start: ```javascript -let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; +// Your ice cream shop's flavor menu +const iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; + +// A user's profile info (mixing different types of data) +const userData = ["John", 25, true, "developer"]; + +// Test scores for your favorite class +const scores = [95, 87, 92, 78, 85]; ``` -Each value in an array is assigned a unique identifier called the **index**, which is a whole number based on its position in the array. In the example above, the string "Chocolate" has an index of 0, while "Rocky Road" has an index of 4. You can use the index with square brackets to access, modify, or add values to the array. +**Cool things to notice:** +- You can store text, numbers, or even true/false values in the same array +- Just separate each item with a comma - easy! +- Arrays are perfect for keeping related information together + +```mermaid +flowchart LR + A["📦 Arrays"] --> B["Create [ ]"] + A --> C["Store Multiple Items"] + A --> D["Access by Index"] + + B --> B1["const arr = []"] + B --> B2["const arr = [1,2,3]"] + + C --> C1["Numbers"] + C --> C2["Strings"] + C --> C3["Booleans"] + C --> C4["Mixed Types"] + + D --> D1["arr[0] = first"] + D --> D2["arr[1] = second"] + D --> D3["arr[2] = third"] + + E["📊 Array Index"] --> E1["Index 0: First"] + E --> E2["Index 1: Second"] + E --> E3["Index 2: Third"] + E --> E4["Index n-1: Last"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 +``` +### Array Indexing -✅ Did you know that arrays start at index 0? In some programming languages, indexes begin at 1. There's an interesting history behind this, which you can [read about on Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering). +Here's something that might seem unusual at first: arrays number their items starting from 0, not 1. This zero-based indexing has its roots in how computer memory works - it's been a programming convention since the early days of computing languages like C. Each spot in the array gets its own address number called an **index**. + +| Index | Value | Description | +|-------|-------|-------------| +| 0 | "Chocolate" | First element | +| 1 | "Strawberry" | Second element | +| 2 | "Vanilla" | Third element | +| 3 | "Pistachio" | Fourth element | +| 4 | "Rocky Road" | Fifth element | + +✅ Does it surprise you that arrays start at the zero index? In some programming languages, indexes start at 1. There's an interesting history around this, which you can [read on Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering). + +**Accessing Array Elements:** ```javascript -let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; -iceCreamFlavors[2]; //"Vanilla" +const iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; + +// Access individual elements using bracket notation +console.log(iceCreamFlavors[0]); // "Chocolate" - first element +console.log(iceCreamFlavors[2]); // "Vanilla" - third element +console.log(iceCreamFlavors[4]); // "Rocky Road" - last element ``` -You can use the index to update a value like this: +**Breaking down what happens here:** +- **Uses** square bracket notation with the index number to access elements +- **Returns** the value stored at that specific position in the array +- **Starts** counting from 0, making the first element index 0 + +**Modifying Array Elements:** ```javascript -iceCreamFlavors[4] = "Butter Pecan"; //Changed "Rocky Road" to "Butter Pecan" +// Change an existing value +iceCreamFlavors[4] = "Butter Pecan"; +console.log(iceCreamFlavors[4]); // "Butter Pecan" + +// Add a new element at the end +iceCreamFlavors[5] = "Cookie Dough"; +console.log(iceCreamFlavors[5]); // "Cookie Dough" ``` -And you can add a new value at a specific index like this: +**In the above, we've:** +- **Modified** the element at index 4 from "Rocky Road" to "Butter Pecan" +- **Added** a new element "Cookie Dough" at index 5 +- **Expanded** the array length automatically when adding beyond current bounds + +### Array Length and Common Methods + +Arrays come with built-in properties and methods that make working with data much easier. + +**Finding Array Length:** ```javascript -iceCreamFlavors[5] = "Cookie Dough"; //Added "Cookie Dough" +const iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; +console.log(iceCreamFlavors.length); // 5 + +// Length updates automatically as array changes +iceCreamFlavors.push("Mint Chip"); +console.log(iceCreamFlavors.length); // 6 ``` -✅ A more common way to add values to an array is by using array methods like `array.push()`. +**Key points to remember:** +- **Returns** the total number of elements in the array +- **Updates** automatically when elements are added or removed +- **Provides** a dynamic count useful for loops and validation -To find out how many items are in an array, use the `length` property. +**Essential Array Methods:** ```javascript -let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; -iceCreamFlavors.length; //5 +const fruits = ["apple", "banana", "orange"]; + +// Add elements +fruits.push("grape"); // Adds to end: ["apple", "banana", "orange", "grape"] +fruits.unshift("strawberry"); // Adds to beginning: ["strawberry", "apple", "banana", "orange", "grape"] + +// Remove elements +const lastFruit = fruits.pop(); // Removes and returns "grape" +const firstFruit = fruits.shift(); // Removes and returns "strawberry" + +// Find elements +const index = fruits.indexOf("banana"); // Returns 1 (position of "banana") +const hasApple = fruits.includes("apple"); // Returns true ``` -✅ Try it out! Open your browser's console and create an array of your own. Experiment with adding, modifying, and accessing its values. +**Understanding these methods:** +- **Adds** elements with `push()` (end) and `unshift()` (beginning) +- **Removes** elements with `pop()` (end) and `shift()` (beginning) +- **Locates** elements with `indexOf()` and checks existence with `includes()` +- **Returns** useful values like removed elements or position indexes + +✅ Try it yourself! Use your browser's console to create and manipulate an array of your own creation. + +### 🧠 **Array Fundamentals Check: Organizing Your Data** + +**Test your array understanding:** +- Why do you think arrays start counting from 0 instead of 1? +- What happens if you try to access an index that doesn't exist (like `arr[100]` in a 5-element array)? +- Can you think of three real-world scenarios where arrays would be useful? + +```mermaid +stateDiagram-v2 + [*] --> EmptyArray: const arr = [] + EmptyArray --> WithItems: Add elements + WithItems --> Accessing: Use indexes + Accessing --> Modifying: Change values + Modifying --> Processing: Use methods + + WithItems --> WithItems: push(), unshift() + Processing --> Processing: pop(), shift() + + note right of Accessing + Zero-based indexing + arr[0] = first element + end note + + note right of Processing + Built-in methods + Dynamic operations + end note +``` +> **Real-world insight**: Arrays are everywhere in programming! Social media feeds, shopping carts, photo galleries, playlist songs - they're all arrays behind the scenes! ## Loops -Loops allow you to perform repetitive or **iterative** tasks, saving time and reducing the amount of code you need to write. Each iteration can involve different variables, values, or conditions. JavaScript offers several types of loops, each with slight differences, but all serve the same purpose: iterating over data. - +Think of the famous punishment from Charles Dickens' novels where students had to write lines repeatedly on a slate. Imagine if you could simply instruct someone to "write this sentence 100 times" and have it done automatically. That's exactly what loops do for your code. + +Loops are like having a tireless assistant who can repeat tasks without error. Whether you need to check every item in a shopping cart or display all the photos in an album, loops handle the repetition efficiently. + +JavaScript provides several types of loops to choose from. Let's examine each one and understand when to use them. + +```mermaid +flowchart TD + A["🔄 Loop Types"] --> B["For Loop"] + A --> C["While Loop"] + A --> D["For...of Loop"] + A --> E["forEach Method"] + + B --> B1["Known iterations"] + B --> B2["Counter-based"] + B --> B3["for(init; condition; increment)"] + + C --> C1["Unknown iterations"] + C --> C2["Condition-based"] + C --> C3["while(condition)"] + + D --> D1["Modern ES6+"] + D --> D2["Array iteration"] + D --> D3["for(item of array)"] + + E --> E1["Functional style"] + E --> E2["Array method"] + E --> E3["array.forEach(callback)"] + + F["⏰ When to Use"] --> F1["For: Counting, indexes"] + F --> F2["While: User input, searching"] + F --> F3["For...of: Simple iteration"] + F --> F4["forEach: Functional programming"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 + style F fill:#fce4ec +``` ### For Loop -A `for` loop requires three components to work: -- `counter`: A variable, usually initialized with a number, that tracks the number of iterations. -- `condition`: An expression that uses comparison operators to stop the loop when it evaluates to `false`. -- `iteration-expression`: Executes at the end of each iteration, typically used to update the counter. +The `for` loop is like setting a timer - you know exactly how many times you want something to happen. It's super organized and predictable, which makes it perfect when you're working with arrays or need to count things. + +**For Loop Structure:** + +| Component | Purpose | Example | +|-----------|---------|----------| +| **Initialization** | Sets starting point | `let i = 0` | +| **Condition** | When to continue | `i < 10` | +| **Increment** | How to update | `i++` | ```javascript -// Counting up to 10 +// Counting from 0 to 9 for (let i = 0; i < 10; i++) { - console.log(i); + console.log(`Count: ${i}`); +} + +// More practical example: processing scores +const testScores = [85, 92, 78, 96, 88]; +for (let i = 0; i < testScores.length; i++) { + console.log(`Student ${i + 1}: ${testScores[i]}%`); } ``` -✅ Run this code in your browser's console. What happens if you tweak the counter, condition, or iteration expression? Can you make the loop run in reverse, like a countdown? +**Step by step, here's what's happening:** +- **Initializes** the counter variable `i` to 0 at the start +- **Checks** the condition `i < 10` before each iteration +- **Executes** the code block when the condition is true +- **Increments** `i` by 1 after each iteration with `i++` +- **Stops** when the condition becomes false (when `i` reaches 10) + +✅ Run this code in a browser console. What happens when you make small changes to the counter, condition, or iteration expression? Can you make it run backwards, creating a countdown? + +### 🗓️ **For Loop Mastery Check: Controlled Repetition** + +**Evaluate your for loop understanding:** +- What are the three parts of a for loop, and what does each one do? +- How would you loop through an array backwards? +- What happens if you forget the increment part (`i++`)? + +```mermaid +flowchart TD + A["🚀 Start For Loop"] --> B["Initialize: let i = 0"] + B --> C{"Condition: i < array.length?"} + C -->|true| D["Execute code block"] + D --> E["Increment: i++"] + E --> C + C -->|false| F["✅ Exit loop"] + + G["📋 Common Patterns"] --> G1["for(let i=0; i G2["for(let i=n-1; i>=0; i--)"] + G --> G3["for(let i=0; i **Loop wisdom**: For loops are perfect when you know exactly how many times you need to repeat something. They're the most common choice for array processing! ### While Loop -Unlike the `for` loop, a `while` loop only requires a condition to stop the loop when it evaluates to `false`. Conditions in loops often depend on other values, like counters, which must be managed during the loop. Initial values for counters must be set outside the loop, and any expressions needed to meet the condition, including updating the counter, must be handled inside the loop. +The `while` loop is like saying "keep doing this until..." - you might not know exactly how many times it'll run, but you know when to stop. It's perfect for things like asking a user for input until they give you what you need, or searching through data until you find what you're looking for. + +**While Loop Characteristics:** +- **Continues** executing as long as the condition is true +- **Requires** manual management of any counter variables +- **Checks** the condition before each iteration +- **Risks** infinite loops if the condition never becomes false ```javascript -//Counting up to 10 +// Basic counting example let i = 0; while (i < 10) { - console.log(i); - i++; + console.log(`While count: ${i}`); + i++; // Don't forget to increment! +} + +// More practical example: processing user input +let userInput = ""; +let attempts = 0; +const maxAttempts = 3; + +while (userInput !== "quit" && attempts < maxAttempts) { + userInput = prompt(`Enter 'quit' to exit (attempt ${attempts + 1}):`); + attempts++; +} + +if (attempts >= maxAttempts) { + console.log("Maximum attempts reached!"); +} +``` + +**Understanding these examples:** +- **Manages** the counter variable `i` manually inside the loop body +- **Increments** the counter to prevent infinite loops +- **Demonstrates** practical use case with user input and attempt limiting +- **Includes** safety mechanisms to prevent endless execution + +### ♾️ **While Loop Wisdom Check: Condition-Based Repetition** + +**Test your while loop comprehension:** +- What's the main danger when using while loops? +- When would you choose a while loop over a for loop? +- How can you prevent infinite loops? + +```mermaid +flowchart LR + A["🔄 While vs For"] --> B["While Loop"] + A --> C["For Loop"] + + B --> B1["Unknown iterations"] + B --> B2["Condition-driven"] + B --> B3["User input, searching"] + B --> B4["⚠️ Risk: infinite loops"] + + C --> C1["Known iterations"] + C --> C2["Counter-driven"] + C --> C3["Array processing"] + C --> C4["✅ Safe: predictable end"] + + D["🛡️ Safety Tips"] --> D1["Always modify condition variable"] + D --> D2["Include escape conditions"] + D --> D3["Set maximum iteration limits"] + + style A fill:#e3f2fd + style B fill:#fff3e0 + style C fill:#e8f5e8 + style D fill:#ffebee +``` +> **Safety first**: While loops are powerful but require careful condition management. Always ensure your loop condition will eventually become false! + +### Modern Loop Alternatives + +JavaScript offers modern loop syntax that can make your code more readable and less error-prone. + +**For...of Loop (ES6+):** + +```javascript +const colors = ["red", "green", "blue", "yellow"]; + +// Modern approach - cleaner and safer +for (const color of colors) { + console.log(`Color: ${color}`); +} + +// Compare with traditional for loop +for (let i = 0; i < colors.length; i++) { + console.log(`Color: ${colors[i]}`); } ``` -✅ Why would you choose a `for` loop over a `while` loop? This question has intrigued 17K viewers on StackOverflow, and you might find their [opinions interesting](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript). +**Key advantages of for...of:** +- **Eliminates** index management and potential off-by-one errors +- **Provides** direct access to array elements +- **Improves** code readability and reduces syntax complexity + +**forEach Method:** + +```javascript +const prices = [9.99, 15.50, 22.75, 8.25]; + +// Using forEach for functional programming style +prices.forEach((price, index) => { + console.log(`Item ${index + 1}: $${price.toFixed(2)}`); +}); + +// forEach with arrow functions for simple operations +prices.forEach(price => console.log(`Price: $${price}`)); +``` + +**What you need to know about forEach:** +- **Executes** a function for each array element +- **Provides** both element value and index as parameters +- **Cannot** be stopped early (unlike traditional loops) +- **Returns** undefined (doesn't create a new array) + +✅ Why would you choose a for loop vs. a while loop? 17K viewers had the same question on StackOverflow, and some of the opinions [might be interesting to you](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript). + +### 🎨 **Modern Loop Syntax Check: Embracing ES6+** + +**Assess your modern JavaScript understanding:** +- What are the advantages of `for...of` over traditional for loops? +- When might you still prefer traditional for loops? +- What's the difference between `forEach` and `map`? + +```mermaid +quadrantChart + title Loop Selection Guide + x-axis Traditional --> Modern + y-axis Simple --> Complex + quadrant-1 Modern Complex + quadrant-2 Traditional Complex + quadrant-3 Traditional Simple + quadrant-4 Modern Simple + + Traditional For: [0.2, 0.7] + While Loop: [0.3, 0.6] + For...of: [0.8, 0.3] + forEach: [0.9, 0.4] + Array Methods: [0.8, 0.8] +``` +> **Modern trend**: ES6+ syntax like `for...of` and `forEach` is becoming the preferred approach for array iteration because it's cleaner and less error-prone! ## Loops and Arrays -Loops are frequently used with arrays because the array's length often serves as the condition to stop the loop, and the index can act as the counter. +Combining arrays with loops creates powerful data processing capabilities. This pairing is fundamental to many programming tasks, from displaying lists to calculating statistics. + +**Traditional Array Processing:** ```javascript -let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; +const iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"]; +// Classic for loop approach for (let i = 0; i < iceCreamFlavors.length; i++) { - console.log(iceCreamFlavors[i]); -} //Ends when all flavors are printed + console.log(`Flavor ${i + 1}: ${iceCreamFlavors[i]}`); +} + +// Modern for...of approach +for (const flavor of iceCreamFlavors) { + console.log(`Available flavor: ${flavor}`); +} ``` -✅ Try looping over an array of your own creation in your browser's console. +**Let's understand each approach:** +- **Uses** array length property to determine loop boundary +- **Accesses** elements by index in traditional for loops +- **Provides** direct element access in for...of loops +- **Processes** each array element exactly once +**Practical Data Processing Example:** + +```javascript +const studentGrades = [85, 92, 78, 96, 88, 73, 89]; +let total = 0; +let highestGrade = studentGrades[0]; +let lowestGrade = studentGrades[0]; + +// Process all grades with a single loop +for (let i = 0; i < studentGrades.length; i++) { + const grade = studentGrades[i]; + total += grade; + + if (grade > highestGrade) { + highestGrade = grade; + } + + if (grade < lowestGrade) { + lowestGrade = grade; + } +} + +const average = total / studentGrades.length; +console.log(`Average: ${average.toFixed(1)}`); +console.log(`Highest: ${highestGrade}`); +console.log(`Lowest: ${lowestGrade}`); +``` + +**Here's how this code works:** +- **Initializes** tracking variables for sum and extremes +- **Processes** each grade with a single efficient loop +- **Accumulates** the total for average calculation +- **Tracks** highest and lowest values during iteration +- **Calculates** final statistics after loop completion + +✅ Experiment with looping over an array of your own making in your browser's console. + +```mermaid +flowchart TD + A["📦 Array Data"] --> B["🔄 Loop Processing"] + B --> C["📈 Results"] + + A1["[85, 92, 78, 96, 88]"] --> A + + B --> B1["Calculate total"] + B --> B2["Find min/max"] + B --> B3["Count conditions"] + B --> B4["Transform data"] + + C --> C1["Average: 87.8"] + C --> C2["Highest: 96"] + C --> C3["Passing: 5/5"] + C --> C4["Letter grades"] + + D["⚡ Processing Patterns"] --> D1["Accumulation (sum)"] + D --> D2["Comparison (min/max)"] + D --> D3["Filtering (conditions)"] + D --> D4["Mapping (transformation)"] + + style A fill:#e3f2fd + style B fill:#fff3e0 + style C fill:#e8f5e8 + style D fill:#f3e5f5 +``` --- +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Build a comprehensive data processing function that combines arrays and loops to analyze a dataset and generate meaningful insights. + +**Prompt:** Create a function called `analyzeGrades` that takes an array of student grade objects (each containing name and score properties) and returns an object with statistics including the highest score, lowest score, average score, count of students who passed (score >= 70), and an array of student names who scored above average. Use at least two different loop types in your solution. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + ## 🚀 Challenge +JavaScript offers several modern array methods that can replace traditional loops for specific tasks. Explore [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of), [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map), [filter](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), and [reduce](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce). -There are other ways to loop through arrays besides `for` and `while` loops. Explore [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of), and [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Rewrite your array loop using one of these methods. +**Your challenge:** Refactor the student grades example using at least three different array methods. Notice how much cleaner and more readable the code becomes with modern JavaScript syntax. ## Post-Lecture Quiz [Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/14) + ## Review & Self Study -JavaScript arrays come with many built-in methods that are incredibly useful for manipulating data. [Learn more about these methods](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) and try using some of them (like `push`, `pop`, `slice`, and `splice`) on an array you create. +Arrays in JavaScript have many methods attached to them, that are extremely useful for data manipulation. [Read up on these methods](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) and try some of them out (like push, pop, slice and splice) on an array of your creation. ## Assignment @@ -143,5 +633,109 @@ JavaScript arrays come with many built-in methods that are incredibly useful for --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file +## 📊 **Your Arrays & Loops Toolkit Summary** + +```mermaid +graph TD + A["🎯 Arrays & Loops Mastery"] --> B["📦 Array Fundamentals"] + A --> C["🔄 Loop Types"] + A --> D["🔗 Data Processing"] + A --> E["🎨 Modern Techniques"] + + B --> B1["Creation: [ ]"] + B --> B2["Indexing: arr[0]"] + B --> B3["Methods: push, pop"] + B --> B4["Properties: length"] + + C --> C1["For: Known iterations"] + C --> C2["While: Condition-based"] + C --> C3["For...of: Direct access"] + C --> C4["forEach: Functional"] + + D --> D1["Statistics calculation"] + D --> D2["Data transformation"] + D --> D3["Filtering & searching"] + D --> D4["Real-time processing"] + + E --> E1["Arrow functions"] + E --> E2["Method chaining"] + E --> E3["Destructuring"] + E --> E4["Template literals"] + + F["💡 Key Benefits"] --> F1["Efficient data handling"] + F --> F2["Reduced code repetition"] + F --> F3["Scalable solutions"] + F --> F4["Cleaner syntax"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 + style F fill:#fce4ec +``` +--- + +## 🚀 Your Arrays & Loops Mastery Timeline + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Create an array of your favorite movies and access specific elements +- [ ] Write a for loop that counts from 1 to 10 +- [ ] Try the modern array methods challenge from the lesson +- [ ] Practice array indexing in your browser console + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and review any challenging concepts +- [ ] Build the comprehensive grade analyzer from the GitHub Copilot challenge +- [ ] Create a simple shopping cart that adds and removes items +- [ ] Practice converting between different loop types +- [ ] Experiment with array methods like `push`, `pop`, `slice`, and `splice` + +### 📅 **Your Week-Long Data Processing Journey** +- [ ] Complete the "Loop an Array" assignment with creative enhancements +- [ ] Build a to-do list application using arrays and loops +- [ ] Create a simple statistics calculator for numerical data +- [ ] Practice with [MDN array methods](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) +- [ ] Build a photo gallery or music playlist interface +- [ ] Explore functional programming with `map`, `filter`, and `reduce` + +### 🌟 **Your Month-Long Transformation** +- [ ] Master advanced array operations and performance optimization +- [ ] Build a complete data visualization dashboard +- [ ] Contribute to open source projects involving data processing +- [ ] Teach someone else about arrays and loops with practical examples +- [ ] Create a personal library of reusable data processing functions +- [ ] Explore algorithms and data structures built on arrays + +### 🏆 **Final Data Processing Champion Check-in** + +**Celebrate your array and loop mastery:** +- What's the most useful array operation you've learned for real-world applications? +- Which loop type feels most natural to you and why? +- How has understanding arrays and loops changed your approach to organizing data? +- What complex data processing task would you like to tackle next? + +```mermaid +journey + title Your Data Processing Evolution + section Today + Array Confusion: 3: You + Loop Basics: 4: You + Index Understanding: 5: You + section This Week + Method Mastery: 4: You + Efficient Processing: 5: You + Modern Syntax: 5: You + section Next Month + Complex Algorithms: 5: You + Performance Optimization: 5: You + Teaching Others: 5: You +``` +> 📦 **You've unlocked the power of data organization and processing!** Arrays and loops are the foundation of almost every application you'll ever build. From simple lists to complex data analysis, you now have the tools to handle information efficiently and elegantly. Every dynamic website, mobile app, and data-driven application relies on these fundamental concepts. Welcome to the world of scalable data processing! 🎉 + +--- + + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/2-js-basics/4-arrays-loops/assignment.md b/translations/en/2-js-basics/4-arrays-loops/assignment.md index aea3c84be..d4bb8429c 100644 --- a/translations/en/2-js-basics/4-arrays-loops/assignment.md +++ b/translations/en/2-js-basics/4-arrays-loops/assignment.md @@ -1,27 +1,115 @@ - -# Loop an Array +# Arrays and Loops Assignment ## Instructions -Create a program that lists every 3rd number between 1 and 20 and displays it in the console. +Complete the following exercises to practice working with arrays and loops. Each exercise builds on concepts from the lesson and encourages you to apply different loop types and array methods. -> TIP: Use a for-loop and adjust the iteration expression. +### Exercise 1: Number Pattern Generator +Create a program that lists every 3rd number between 1-20 and prints it to the console. + +**Requirements:** +- Use a `for` loop with a custom increment +- Display numbers in a user-friendly format +- Add descriptive comments explaining your logic + +**Expected Output:** +``` +3, 6, 9, 12, 15, 18 +``` + +> **Tip:** Modify the iteration-expression in your for loop to skip numbers. + +### Exercise 2: Array Analysis +Create an array of at least 8 different numbers and write functions to analyze the data. + +**Requirements:** +- Create an array called `numbers` with at least 8 values +- Write a function `findMaximum()` that returns the highest number +- Write a function `findMinimum()` that returns the lowest number +- Write a function `calculateSum()` that returns the total of all numbers +- Test each function and display the results + +**Bonus Challenge:** Create a function that finds the second highest number in the array. + +### Exercise 3: String Array Processing +Create an array of your favorite movies/books/songs and practice different loop types. + +**Requirements:** +- Create an array with at least 5 string values +- Use a traditional `for` loop to display items with numbers (1. Item Name) +- Use a `for...of` loop to display items in uppercase +- Use `forEach()` method to count and display the total characters + +**Example Output:** +``` +Traditional for loop: +1. The Matrix +2. Inception +3. Interstellar + +For...of loop (uppercase): +THE MATRIX +INCEPTION +INTERSTELLAR + +Character count: +Total characters across all titles: 42 +``` + +### Exercise 4: Data Filtering (Advanced) +Create a program that processes an array of objects representing students. + +**Requirements:** +- Create an array of at least 5 student objects with properties: `name`, `age`, `grade` +- Use loops to find students who are 18 or older +- Calculate the average grade of all students +- Create a new array containing only students with grades above 85 + +**Example Structure:** +```javascript +const students = [ + { name: "Alice", age: 17, grade: 92 }, + { name: "Bob", age: 18, grade: 84 }, + // Add more students... +]; +``` + +## Testing Your Code + +Test your programs by: +1. Running each exercise in your browser's console +2. Verifying outputs match expected results +3. Testing with different data sets +4. Checking that your code handles edge cases (empty arrays, single elements) + +## Submission Guidelines + +Include the following in your submission: +- Well-commented JavaScript code for each exercise +- Screenshots or text output showing your programs running +- Brief explanation of which loop type you chose for each task and why ## Rubric -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | --------------------------------------- | ------------------------ | ------------------------------ | -| | Program works correctly and includes comments | Program lacks comments | Program is incomplete or contains errors | +| Criteria | Exemplary (3 points) | Adequate (2 points) | Needs Improvement (1 point) | +| -------- | -------------------- | ------------------- | --------------------------- | +| **Functionality** | All exercises completed correctly with bonus challenges | All required exercises work correctly | Some exercises incomplete or contain errors | +| **Code Quality** | Clean, well-organized code with descriptive variable names | Code works but could be cleaner | Code is messy or hard to understand | +| **Comments** | Comprehensive comments explaining logic and decisions | Basic comments present | Minimal or no comments | +| **Loop Usage** | Demonstrates understanding of different loop types appropriately | Uses loops correctly but limited variety | Incorrect or inefficient loop usage | +| **Testing** | Evidence of thorough testing with multiple scenarios | Basic testing demonstrated | Little evidence of testing | + +## Reflection Questions + +After completing the exercises, consider: +1. Which type of loop felt most natural to use and why? +2. What challenges did you encounter when working with arrays? +3. How could these skills apply to real-world web development projects? +4. What would you do differently if you had to optimize your code for performance? --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/2-js-basics/README.md b/translations/en/2-js-basics/README.md index 54bc1dbfe..5491259d2 100644 --- a/translations/en/2-js-basics/README.md +++ b/translations/en/2-js-basics/README.md @@ -1,12 +1,3 @@ - # Introduction to JavaScript JavaScript is the language of the web. In these four lessons, you'll learn the basics. diff --git a/translations/en/3-terrarium/1-intro-to-html/README.md b/translations/en/3-terrarium/1-intro-to-html/README.md index 7cbb9c667..bfba4ed1b 100644 --- a/translations/en/3-terrarium/1-intro-to-html/README.md +++ b/translations/en/3-terrarium/1-intro-to-html/README.md @@ -1,83 +1,159 @@ - # Terrarium Project Part 1: Introduction to HTML -![Introduction to HTML](../../../../translated_images/en/webdev101-html.4389c2067af68e98280c1bde52b6c6269f399eaae3659b7c846018d8a7b0bbd9.png) +```mermaid +journey + title Your HTML Learning Journey + section Foundation + Create HTML file: 3: Student + Add DOCTYPE: 4: Student + Structure document: 5: Student + section Content + Add metadata: 4: Student + Include images: 5: Student + Organize layout: 5: Student + section Semantics + Use proper tags: 4: Student + Enhance accessibility: 5: Student + Build terrarium: 5: Student +``` +![Introduction to HTML](../../../../translated_images/en/webdev101-html.4389c2067af68e98.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) +HTML, or HyperText Markup Language, is the foundation of every website you've ever visited. Think of HTML as the skeleton that gives structure to web pages – it defines where content goes, how it's organized, and what each piece represents. While CSS will later "dress up" your HTML with colors and layouts, and JavaScript will bring it to life with interactivity, HTML provides the essential structure that makes everything else possible. + +In this lesson, you'll create the HTML structure for a virtual terrarium interface. This hands-on project will teach you fundamental HTML concepts while building something visually engaging. You'll learn how to organize content using semantic elements, work with images, and create the foundation for an interactive web application. + +By the end of this lesson, you'll have a working HTML page displaying plant images in organized columns, ready for styling in the next lesson. Don't worry if it looks basic at first – that's exactly what HTML should do before CSS adds the visual polish. + +```mermaid +mindmap + root((HTML Fundamentals)) + Structure + DOCTYPE Declaration + HTML Element + Head Section + Body Content + Elements + Tags & Attributes + Self-closing Tags + Nested Elements + Block vs Inline + Content + Text Elements + Images + Containers (div) + Lists + Semantics + Meaningful Tags + Accessibility + Screen Readers + SEO Benefits + Best Practices + Proper Nesting + Valid Markup + Descriptive Alt Text + Organized Structure +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/15) - -> Check out video - +> 📺 **Watch and Learn**: Check out this helpful video overview > -> [![Git and GitHub basics video](https://img.youtube.com/vi/1TvxJKBzhyQ/0.jpg)](https://www.youtube.com/watch?v=1TvxJKBzhyQ) - -### Introduction - -HTML, or HyperText Markup Language, is the 'framework' of the web. If CSS 'styles' your HTML and JavaScript adds functionality, HTML is the foundation of your web application. HTML's syntax even reflects this concept, with tags like "head", "body", and "footer". +> [![HTML Fundamentals Video](https://img.youtube.com/vi/1TvxJKBzhyQ/0.jpg)](https://www.youtube.com/watch?v=1TvxJKBzhyQ) -In this lesson, we'll use HTML to structure the 'framework' of our virtual terrarium's interface. It will include a title and three columns: a left and right column for draggable plants, and a center area that will represent the terrarium itself. By the end of this lesson, you'll see the plants in the columns, but the interface will look a bit plain. Don't worry—next, you'll use CSS to enhance its appearance. +## Setting Up Your Project -### Task +Before we dive into HTML code, let's set up a proper workspace for your terrarium project. Creating an organized file structure from the beginning is a crucial habit that will serve you well throughout your web development journey. -On your computer, create a folder named 'terrarium' and inside it, a file called 'index.html'. You can do this in Visual Studio Code by opening a new VS Code window, clicking 'open folder', and navigating to your new folder. Then, click the small 'file' button in the Explorer pane to create the new file: +### Task: Create Your Project Structure -![explorer in VS Code](../../../../translated_images/en/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.png) +You'll create a dedicated folder for your terrarium project and add your first HTML file. Here are two approaches you can use: -Alternatively, you can use these commands in Git Bash: -* `mkdir terrarium` -* `cd terrarium` -* `touch index.html` -* `code index.html` or `nano index.html` +**Option 1: Using Visual Studio Code** +1. Open Visual Studio Code +2. Click "File" → "Open Folder" or use `Ctrl+K, Ctrl+O` (Windows/Linux) or `Cmd+K, Cmd+O` (Mac) +3. Create a new folder called `terrarium` and select it +4. In the Explorer pane, click the "New File" icon +5. Name your file `index.html` -> The `index.html` file tells the browser it's the default file in a folder. URLs like `https://anysite.com/test` might correspond to a folder named `test` containing an `index.html` file. The `index.html` file doesn't need to appear in the URL. +![VS Code Explorer showing new file creation](../../../../translated_images/en/vs-code-index.e2986cf919471eb9.webp) ---- - -## The DocType and html tags - -The first line of an HTML file is its doctype declaration. While it might seem odd to include this line at the very top, it informs older browsers to render the page in standard mode, adhering to the current HTML specification. - -> Tip: In VS Code, you can hover over a tag to access information about its usage from the MDN Reference guides. +**Option 2: Using Terminal Commands** +```bash +mkdir terrarium +cd terrarium +touch index.html +code index.html +``` -The second line should be the opening `` tag, followed by its closing tag ``. These tags serve as the root elements of your interface. +**Here's what these commands accomplish:** +- **Creates** a new directory called `terrarium` for your project +- **Navigates** into the terrarium directory +- **Creates** an empty `index.html` file +- **Opens** the file in Visual Studio Code for editing + +> 💡 **Pro Tip**: The filename `index.html` is special in web development. When someone visits a website, browsers automatically look for `index.html` as the default page to display. This means a URL like `https://mysite.com/projects/` will automatically serve the `index.html` file from the `projects` folder without needing to specify the filename in the URL. + +## Understanding HTML Document Structure + +Every HTML document follows a specific structure that browsers need to understand and display correctly. Think of this structure like a formal letter – it has required elements in a particular order that help the recipient (in this case, the browser) process the content properly. + +```mermaid +flowchart TD + A[""] --> B[""] + B --> C[""] + C --> D[""] + C --> E["<meta charset>"] + C --> F["<meta viewport>"] + B --> G["<body>"] + G --> H["<h1> Heading"] + G --> I["<div> Containers"] + G --> J["<img> Images"] + + style A fill:#e1f5fe + style B fill:#f3e5f5 + style C fill:#fff3e0 + style G fill:#e8f5e8 +``` +Let's start by adding the essential foundation that every HTML document needs. -### Task +### The DOCTYPE Declaration and Root Element -Add these lines at the top of your `index.html` file: +The first two lines of any HTML file serve as the document's "introduction" to the browser: -```HTML +```html <!DOCTYPE html> <html></html> ``` -✅ There are different modes that can be set using the DocType declaration, such as [Quirks Mode and Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). These modes were designed to support very old browsers (like Netscape Navigator 4 and Internet Explorer 5), which are rarely used today. Stick to the standard doctype declaration. +**Understanding what this code does:** +- **Declares** the document type as HTML5 using `<!DOCTYPE html>` +- **Creates** the root `<html>` element that will contain all page content +- **Establishes** modern web standards for proper browser rendering +- **Ensures** consistent display across different browsers and devices ---- +> 💡 **VS Code Tip**: Hover over any HTML tag in VS Code to see helpful information from MDN Web Docs, including usage examples and browser compatibility details. + +> 📚 **Learn More**: The DOCTYPE declaration prevents browsers from entering "quirks mode," which was used to support very old websites. Modern web development uses the simple `<!DOCTYPE html>` declaration to ensure [standards-compliant rendering](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). -## The document's 'head' +### 🔄 **Pedagogical Check-in** +**Pause and Reflect**: Before continuing, make sure you understand: +- ✅ Why every HTML document needs a DOCTYPE declaration +- ✅ What the `<html>` root element contains +- ✅ How this structure helps browsers render pages correctly -The 'head' section of an HTML document contains essential information about your web page, known as [metadata](https://developer.mozilla.org/docs/Web/HTML/Element/meta). In this case, it provides the web server with the following details: +**Quick Self-Test**: Can you explain in your own words what "standards-compliant rendering" means? -- The page's title -- Metadata, including: - - The 'character set', specifying the character encoding used on the page - - Browser compatibility information, such as `x-ua-compatible` indicating support for IE=edge - - Instructions for how the viewport should behave when loaded, such as setting the initial scale to 1 to control the zoom level. +## Adding Essential Document Metadata -### Task +The `<head>` section of an HTML document contains crucial information that browsers and search engines need, but that visitors don't see directly on the page. Think of it as the "behind-the-scenes" information that helps your webpage work properly and appear correctly across different devices and platforms. -Add a 'head' section to your document between the opening and closing `<html>` tags. +This metadata tells browsers how to display your page, what character encoding to use, and how to handle different screen sizes – all essential for creating professional, accessible web pages. + +### Task: Add the Document Head + +Insert this `<head>` section between your opening and closing `<html>` tags: ```html <head> @@ -88,17 +164,28 @@ Add a 'head' section to your document between the opening and closing `<html>` t </head> ``` -✅ What happens if you set a viewport meta tag like this: `<meta name="viewport" content="width=600">`? Learn more about the [viewport](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag). +**Breaking down what each element accomplishes:** +- **Sets** the page title that appears in browser tabs and search results +- **Specifies** UTF-8 character encoding for proper text display worldwide +- **Ensures** compatibility with modern versions of Internet Explorer +- **Configures** responsive design by setting the viewport to match device width +- **Controls** initial zoom level to display content at natural size ---- +> 🤔 **Think About This**: What would happen if you set a viewport meta tag like this: `<meta name="viewport" content="width=600">`? This would force the page to always be 600 pixels wide, breaking responsive design! Learn more about [proper viewport configuration](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag). -## The document's `body` +## Building the Document Body -### HTML Tags +The `<body>` element contains all the visible content of your webpage – everything users will see and interact with. While the `<head>` section provided instructions to the browser, the `<body>` section contains the actual content: text, images, buttons, and other elements that create your user interface. -In HTML, you use tags in your `.html` file to create elements on a web page. Most tags have an opening and closing tag, like `<p>hello</p>` for a paragraph. Create the body of your interface by adding `<body>` tags inside the `<html>` tag pair. Your markup should now look like this: +Let's add the body structure and understand how HTML tags work together to create meaningful content. -### Task +### Understanding HTML Tag Structure + +HTML uses paired tags to define elements. Most tags have an opening tag like `<p>` and a closing tag like `</p>`, with content in between: `<p>Hello, world!</p>`. This creates a paragraph element containing the text "Hello, world!". + +### Task: Add the Body Element + +Update your HTML file to include the `<body>` element: ```html <!DOCTYPE html> @@ -113,100 +200,179 @@ In HTML, you use tags in your `.html` file to create elements on a web page. Mos </html> ``` -Now, you can start building your page. Typically, `<div>` tags are used to create separate elements on a page. We'll use a series of `<div>` elements to contain images. +**Here's what this complete structure provides:** +- **Establishes** the basic HTML5 document framework +- **Includes** essential metadata for proper browser rendering +- **Creates** an empty body ready for your visible content +- **Follows** modern web development best practices -### Images +Now you're ready to add the visible elements of your terrarium. We'll use `<div>` elements as containers to organize different sections of content, and `<img>` elements to display the plant images. -The `<img>` tag is unique because it doesn't require a closing tag. It includes a `src` attribute that provides all the information needed to render the image. +### Working with Images and Layout Containers -Create a folder in your app called `images` and add all the images from the [source code folder](../../../../3-terrarium/solution/images) into it. (There are 14 plant images.) +Images are special in HTML because they use "self-closing" tags. Unlike elements like `<p></p>` that wrap around content, the `<img>` tag contains all the information it needs within the tag itself using attributes like `src` for the image file path and `alt` for accessibility. -### Task +Before adding images to your HTML, you'll need to organize your project files properly by creating an images folder and adding the plant graphics. -Add these plant images into two columns between the `<body></body>` tags: +**First, set up your images:** +1. Create a folder called `images` inside your terrarium project folder +2. Download the plant images from the [solution folder](../../../../3-terrarium/solution/images) (14 plant images total) +3. Copy all plant images into your new `images` folder + +### Task: Create the Plant Display Layout + +Now add the plant images organized in two columns between your `<body></body>` tags: ```html <div id="page"> <div id="left-container" class="container"> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant1" src="./images/plant1.png" /> + <img class="plant" alt="plant" id="plant1" src="../../../../translated_images/en/plant1.d87946a2ca70cc43.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant2" src="./images/plant2.png" /> + <img class="plant" alt="plant" id="plant2" src="../../../../translated_images/en/plant2.8daa1606c9c1ad89.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant3" src="./images/plant3.png" /> + <img class="plant" alt="plant" id="plant3" src="../../../../translated_images/en/plant3.8b0d484381a2a2a7.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant4" src="./images/plant4.png" /> + <img class="plant" alt="plant" id="plant4" src="../../../../translated_images/en/plant4.656e16ae1df37be2.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant5" src="./images/plant5.png" /> + <img class="plant" alt="plant" id="plant5" src="../../../../translated_images/en/plant5.2b41b9355f11ebcc.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant6" src="./images/plant6.png" /> + <img class="plant" alt="plant" id="plant6" src="../../../../translated_images/en/plant6.3d1827d03b656994.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant7" src="./images/plant7.png" /> + <img class="plant" alt="plant" id="plant7" src="../../../../translated_images/en/plant7.8152c302ac97f621.webp" /> </div> </div> <div id="right-container" class="container"> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant8" src="./images/plant8.png" /> + <img class="plant" alt="plant" id="plant8" src="../../../../translated_images/en/plant8.38d6428174ffa850.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant9" src="./images/plant9.png" /> + <img class="plant" alt="plant" id="plant9" src="../../../../translated_images/en/plant9.f0e38d3327c37fc2.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant10" src="./images/plant10.png" /> + <img class="plant" alt="plant" id="plant10" src="../../../../translated_images/en/plant10.b159d6d6e985595f.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant11" src="./images/plant11.png" /> + <img class="plant" alt="plant" id="plant11" src="../../../../translated_images/en/plant11.2a03a1c2ec8ea84e.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant12" src="./images/plant12.png" /> + <img class="plant" alt="plant" id="plant12" src="../../../../translated_images/en/plant12.60e9b53e538fbaf3.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant13" src="./images/plant13.png" /> + <img class="plant" alt="plant" id="plant13" src="../../../../translated_images/en/plant13.07a51543c820bcf5.webp" /> </div> <div class="plant-holder"> - <img class="plant" alt="plant" id="plant14" src="./images/plant14.png" /> + <img class="plant" alt="plant" id="plant14" src="../../../../translated_images/en/plant14.6e486371ba7d36ba.webp" /> </div> </div> </div> ``` -> Note: Divs vs. Spans. Divs are 'block' elements, while Spans are 'inline'. What happens if you change these divs to spans? - -With this markup, the plants will now appear on the screen. It won't look great yet because the CSS styling hasn't been applied. We'll address that in the next lesson. - -Each image includes alt text, which appears if the image can't be displayed. This is an important attribute for accessibility. You'll learn more about accessibility in future lessons, but for now, remember that the alt attribute provides alternative information for an image if a user can't view it (due to a slow connection, an error in the `src` attribute, or if the user relies on a screen reader). - -✅ Did you notice that each image has the same alt tag? Is this good practice? Why or why not? Can you improve this code? - ---- - -## Semantic markup +**Step by step, here's what's happening in this code:** +- **Creates** a main page container with `id="page"` to hold all content +- **Establishes** two column containers: `left-container` and `right-container` +- **Organizes** 7 plants in the left column and 7 plants in the right column +- **Wraps** each plant image in a `plant-holder` div for individual positioning +- **Applies** consistent class names for CSS styling in the next lesson +- **Assigns** unique IDs to each plant image for JavaScript interaction later +- **Includes** proper file paths pointing to the images folder + +> 🤔 **Consider This**: Notice that all images currently have the same alt text "plant". This isn't ideal for accessibility. Screen reader users would hear "plant" repeated 14 times without knowing which specific plant each image shows. Can you think of better, more descriptive alt text for each image? + +> 📝 **HTML Element Types**: `<div>` elements are "block-level" and take up full width, while `<span>` elements are "inline" and only take up necessary width. What do you think would happen if you changed all these `<div>` tags to `<span>` tags? + +### 🔄 **Pedagogical Check-in** +**Structure Understanding**: Take a moment to review your HTML structure: +- ✅ Can you identify the main containers in your layout? +- ✅ Do you understand why each image has a unique ID? +- ✅ How would you describe the purpose of the `plant-holder` divs? + +**Visual Inspection**: Open your HTML file in a browser. You should see: +- A basic list of plant images +- Images organized in two columns +- Simple, unstyled layout + +**Remember**: This plain appearance is exactly what HTML should look like before CSS styling! + +With this markup added, the plants will appear on screen, though they won't look polished yet – that's what CSS is for in the next lesson! For now, you have a solid HTML foundation that properly organizes your content and follows accessibility best practices. + +## Using Semantic HTML for Accessibility + +Semantic HTML means choosing HTML elements based on their meaning and purpose, not just their appearance. When you use semantic markup, you're communicating the structure and meaning of your content to browsers, search engines, and assistive technologies like screen readers. + +```mermaid +flowchart TD + A[Need to add content?] --> B{What type?} + B -->|Main heading| C["<h1>"] + B -->|Subheading| D["<h2>, <h3>, etc."] + B -->|Paragraph| E["<p>"] + B -->|List| F["<ul>, <ol>"] + B -->|Navigation| G["<nav>"] + B -->|Article| H["<article>"] + B -->|Section| I["<section>"] + B -->|Generic container| J["<div>"] + + C --> K[Screen readers announce as main title] + D --> L[Creates proper heading hierarchy] + E --> M[Provides proper text spacing] + F --> N[Enables list navigation shortcuts] + G --> O[Identifies navigation landmarks] + H --> P[Marks standalone content] + I --> Q[Groups related content] + J --> R[Use only when no semantic tag fits] + + style C fill:#4caf50 + style D fill:#4caf50 + style E fill:#4caf50 + style F fill:#4caf50 + style G fill:#2196f3 + style H fill:#2196f3 + style I fill:#2196f3 + style J fill:#ff9800 +``` +This approach makes your websites more accessible to users with disabilities and helps search engines better understand your content. It's a fundamental principle of modern web development that creates better experiences for everyone. -Using meaningful 'semantics' in HTML means employing tags that represent the type of data or interaction they were designed for. For example, the main title text on a page should use an `<h1>` tag. +### Adding a Semantic Page Title -Add the following line right below your opening `<body>` tag: +Let's add a proper heading to your terrarium page. Insert this line right after your opening `<body>` tag: ```html <h1>My Terrarium</h1> ``` -Using semantic markup, such as headers with `<h1>` and unordered lists with `<ul>`, helps screen readers navigate a page. Buttons should be written as `<button>` and lists as `<li>`. While you can use styled `<span>` elements with click handlers to mimic buttons, it's better for accessibility to use actual button elements. This allows assistive technologies to identify and interact with buttons more effectively. +**Why semantic markup matters:** +- **Helps** screen readers navigate and understand page structure +- **Improves** search engine optimization (SEO) by clarifying content hierarchy +- **Enhances** accessibility for users with visual impairments or cognitive differences +- **Creates** better user experiences across all devices and platforms +- **Follows** web standards and best practices for professional development -✅ Watch a screen reader in action and [see how it interacts with a web page](https://www.youtube.com/watch?v=OUDV1gqs9GA). Can you understand why non-semantic markup might frustrate users? +**Examples of semantic vs. non-semantic choices:** -## The terrarium +| Purpose | ✅ Semantic Choice | ❌ Non-Semantic Choice | +|---------|-------------------|------------------------| +| Main heading | `<h1>Title</h1>` | `<div class="big-text">Title</div>` | +| Navigation | `<nav><ul><li></li></ul></nav>` | `<div class="menu"><div></div></div>` | +| Button | `<button>Click me</button>` | `<span onclick="...">Click me</span>` | +| Article content | `<article><p></p></article>` | `<div class="content"><div></div></div>` | -The final part of this interface involves adding markup that will later be styled to create a terrarium. +> 🎥 **See It in Action**: Watch [how screen readers interact with web pages](https://www.youtube.com/watch?v=OUDV1gqs9GA) to understand why semantic markup is crucial for accessibility. Notice how proper HTML structure helps users navigate efficiently. -### Task: +## Creating the Terrarium Container -Add this markup above the last `</div>` tag: +Now let's add the HTML structure for the terrarium itself – the glass container where plants will eventually be placed. This section demonstrates an important concept: HTML provides structure, but without CSS styling, these elements won't be visible yet. + +The terrarium markup uses descriptive class names that will make CSS styling intuitive and maintainable in the next lesson. + +### Task: Add the Terrarium Structure + +Insert this markup above the last `</div>` tag (before the closing tag of the page container): ```html <div id="terrarium"> @@ -220,13 +386,73 @@ Add this markup above the last `</div>` tag: </div> ``` -✅ Even though you've added this markup, nothing appears on the screen yet. Why? +**Understanding this terrarium structure:** +- **Creates** a main terrarium container with a unique ID for styling +- **Defines** separate elements for each visual component (top, walls, dirt, bottom) +- **Includes** nested elements for glass reflection effects (glossy elements) +- **Uses** descriptive class names that clearly indicate each element's purpose +- **Prepares** the structure for CSS styling that will create the glass terrarium appearance + +> 🤔 **Notice Something?**: Even though you added this markup, you don't see anything new on the page! This perfectly illustrates how HTML provides structure while CSS provides appearance. These `<div>` elements exist but have no visual styling yet – that's coming in the next lesson! + +```mermaid +flowchart TD + A[HTML Document] --> B[Document Head] + A --> C[Document Body] + B --> D[Title Element] + B --> E[Meta Charset] + B --> F[Meta Viewport] + C --> G[Main Heading] + C --> H[Page Container] + H --> I[Left Container with 7 plants] + H --> J[Right Container with 7 plants] + H --> K[Terrarium Structure] + + style A fill:#e1f5fe + style B fill:#fff3e0 + style C fill:#e8f5e8 + style H fill:#f3e5f5 +``` +### 🔄 **Pedagogical Check-in** +**HTML Structure Mastery**: Before moving forward, ensure you can: +- ✅ Explain the difference between HTML structure and visual appearance +- ✅ Identify semantic vs. non-semantic HTML elements +- ✅ Describe how proper markup benefits accessibility +- ✅ Recognize the complete document tree structure + +**Testing Your Understanding**: Try opening your HTML file in a browser with JavaScript disabled and CSS removed. This shows you the pure semantic structure you've created! --- -## 🚀Challenge +## GitHub Copilot Agent Challenge + +Use the Agent mode to complete the following challenge: + +**Description:** Create a semantic HTML structure for a plant care guide section that could be added to the terrarium project. + +**Prompt:** Create a semantic HTML section that includes a main heading "Plant Care Guide", three subsections with headings "Watering", "Light Requirements", and "Soil Care", each containing a paragraph of plant care information. Use proper semantic HTML tags like `<section>`, `<h2>`, `<h3>`, and `<p>` to structure the content appropriately. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + +## Explore HTML History Challenge + +**Learning About Web Evolution** + +HTML has evolved significantly since Tim Berners-Lee created the first web browser at CERN in 1990. Some older tags like `<marquee>` are now deprecated because they don't work well with modern accessibility standards and responsive design principles. + +**Try This Experiment:** +1. Temporarily wrap your `<h1>` title in a `<marquee>` tag: `<marquee><h1>My Terrarium</h1></marquee>` +2. Open your page in a browser and observe the scrolling effect +3. Consider why this tag was deprecated (hint: think about user experience and accessibility) +4. Remove the `<marquee>` tag and return to semantic markup + +**Reflection Questions:** +- How might a scrolling title affect users with visual impairments or motion sensitivity? +- What modern CSS techniques could achieve similar visual effects more accessibly? +- Why is it important to use current web standards instead of deprecated elements? + +Explore more about [obsolete and deprecated HTML elements](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) to understand how web standards evolve to improve user experience. -HTML includes some quirky 'older' tags that are fun to experiment with, even though you shouldn't use deprecated tags like [these tags](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) in your markup. Can you use the old `<marquee>` tag to make the `<h1>` title scroll horizontally? (Remember to remove it afterward!) ## Post-Lecture Quiz @@ -234,9 +460,119 @@ HTML includes some quirky 'older' tags that are fun to experiment with, even tho ## Review & Self Study -HTML is the foundational system that has shaped the web into what it is today. Explore its history by studying old and new tags. Can you figure out why some tags were deprecated and others introduced? What tags might be added in the future? +**Deepen Your HTML Knowledge** + +HTML has been the foundation of the web for over 30 years, evolving from a simple document markup language to a sophisticated platform for building interactive applications. Understanding this evolution helps you appreciate modern web standards and make better development decisions. + +**Recommended Learning Paths:** + +1. **HTML History and Evolution** + - Research the timeline from HTML 1.0 to HTML5 + - Explore why certain tags were deprecated (accessibility, mobile-friendliness, maintainability) + - Investigate emerging HTML features and proposals + +2. **Semantic HTML Deep Dive** + - Study the complete list of [HTML5 semantic elements](https://developer.mozilla.org/docs/Web/HTML/Element) + - Practice identifying when to use `<article>`, `<section>`, `<aside>`, and `<main>` + - Learn about ARIA attributes for enhanced accessibility + +3. **Modern Web Development** + - Explore [building responsive websites](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon) on Microsoft Learn + - Understand how HTML integrates with CSS and JavaScript + - Learn about web performance and SEO best practices + +**Reflection Questions:** +- Which deprecated HTML tags did you discover, and why were they removed? +- What new HTML features are being proposed for future versions? +- How does semantic HTML contribute to web accessibility and SEO? + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open DevTools (F12) and inspect the HTML structure of your favorite website +- [ ] Create a simple HTML file with basic tags: `<h1>`, `<p>`, and `<img>` +- [ ] Validate your HTML using the W3C HTML Validator online +- [ ] Try adding a comment to your HTML using `<!-- comment -->` + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and review semantic HTML concepts +- [ ] Build a simple webpage about yourself using proper HTML structure +- [ ] Experiment with different heading levels and text formatting tags +- [ ] Add images and links to practice multimedia integration +- [ ] Research HTML5 features you haven't tried yet + +### 📅 **Your Week-Long HTML Journey** +- [ ] Complete the terrarium project assignment with semantic markup +- [ ] Create an accessible webpage using ARIA labels and roles +- [ ] Practice form creation with various input types +- [ ] Explore HTML5 APIs like localStorage or geolocation +- [ ] Study responsive HTML patterns and mobile-first design +- [ ] Review other developers' HTML code for best practices + +### 🌟 **Your Month-Long Web Foundation** +- [ ] Build a portfolio website showcasing your HTML mastery +- [ ] Learn HTML templating with a framework like Handlebars +- [ ] Contribute to open source projects by improving HTML documentation +- [ ] Master advanced HTML concepts like custom elements +- [ ] Integrate HTML with CSS frameworks and JavaScript libraries +- [ ] Mentor others learning HTML fundamentals + +## 🎯 Your HTML Mastery Timeline + +```mermaid +timeline + title HTML Learning Progression + + section Foundation (5 minutes) + Document Structure: DOCTYPE declaration + : HTML root element + : Head vs Body understanding + + section Metadata (10 minutes) + Essential Meta Tags: Character encoding + : Viewport configuration + : Browser compatibility + + section Content Creation (15 minutes) + Image Integration: Proper file paths + : Alt text importance + : Self-closing tags + + section Layout Organization (20 minutes) + Container Strategy: Div elements for structure + : Class and ID naming + : Nested element hierarchy + + section Semantic Mastery (30 minutes) + Meaningful Markup: Heading hierarchy + : Screen reader navigation + : Accessibility best practices + + section Advanced Concepts (1 hour) + HTML5 Features: Modern semantic elements + : ARIA attributes + : Performance considerations + + section Professional Skills (1 week) + Code Organization: File structure patterns + : Maintainable markup + : Team collaboration + + section Expert Level (1 month) + Modern Web Standards: Progressive enhancement + : Cross-browser compatibility + : HTML specification updates +``` +### 🛠️ Your HTML Toolkit Summary + +After completing this lesson, you now have: +- **Document Structure**: Complete HTML5 foundation with proper DOCTYPE +- **Semantic Markup**: Meaningful tags that enhance accessibility and SEO +- **Image Integration**: Proper file organization and alt text practices +- **Layout Containers**: Strategic use of divs with descriptive class names +- **Accessibility Awareness**: Understanding of screen reader navigation +- **Modern Standards**: Current HTML5 practices and deprecated tag knowledge +- **Project Foundation**: Solid base for CSS styling and JavaScript interactivity -Learn more about building websites for the web and mobile devices at [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon). +**Next Steps**: Your HTML structure is ready for CSS styling! The semantic foundation you've built will make the next lesson much easier to understand. ## Assignment @@ -245,5 +581,7 @@ Learn more about building websites for the web and mobile devices at [Microsoft --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file +<!-- CO-OP TRANSLATOR DISCLAIMER START --> +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. +<!-- CO-OP TRANSLATOR DISCLAIMER END --> \ No newline at end of file diff --git a/translations/en/3-terrarium/1-intro-to-html/assignment.md b/translations/en/3-terrarium/1-intro-to-html/assignment.md index 1cc53d61e..ba6259104 100644 --- a/translations/en/3-terrarium/1-intro-to-html/assignment.md +++ b/translations/en/3-terrarium/1-intro-to-html/assignment.md @@ -1,53 +1,145 @@ -<!-- -CO_OP_TRANSLATOR_METADATA: -{ - "original_hash": "5a764667bbe82aa72ac0a67f4c97ff4a", - "translation_date": "2025-10-03T08:22:44+00:00", - "source_file": "3-terrarium/1-intro-to-html/assignment.md", - "language_code": "en" -} ---> # HTML Practice Assignment: Build a Blog Mockup -## Objective +## Learning Objectives -Create and hand-code the HTML structure for a personal blog homepage. This task will help you practice using semantic HTML, planning layouts, and organizing your code. +Apply your HTML knowledge by designing and coding a complete blog homepage structure. This hands-on assignment will reinforce semantic HTML concepts, accessibility best practices, and professional code organization skills that you'll use throughout your web development journey. -## Instructions +**By completing this assignment, you will:** +- Practice planning website layouts before coding +- Apply semantic HTML elements appropriately +- Create accessible, well-structured markup +- Develop professional coding habits with comments and organization -1. **Design Your Blog Mockup** - - Draw a visual representation of your blog homepage. Include essential sections like the header, navigation, main content, sidebar, and footer. - - You can sketch it on paper and scan it, or use digital tools (e.g., Figma, Adobe XD, Canva, or even PowerPoint). +## Project Requirements -2. **Identify HTML Elements** - - Make a list of the HTML elements you intend to use for each section (e.g., `<header>`, `<nav>`, `<main>`, `<article>`, `<aside>`, `<footer>`, `<section>`, `<h1>`–`<h6>`, `<p>`, `<img>`, `<ul>`, `<li>`, `<a>`, etc.). +### Part 1: Design Planning (Visual Mockup) -3. **Write the HTML Markup** - - Hand-code the HTML for your mockup, focusing on semantic structure and best practices. - - Use at least 10 different HTML elements. - - Add comments to explain your choices and structure. +**Create a visual mockup of your blog homepage that includes:** +- Header with site title and navigation +- Main content area with at least 2-3 blog post previews +- Sidebar with additional information (about section, recent posts, categories) +- Footer with contact information or links -4. **Submit Your Work** - - Upload your sketch/mockup along with your HTML file. - - Optionally, write a short reflection (2–3 sentences) about your design decisions. +**Mockup Creation Options:** +- **Hand-drawn sketch**: Use paper and pencil, then photograph or scan your design +- **Digital tools**: Figma, Adobe XD, Canva, PowerPoint, or any drawing application +- **Wireframe tools**: Balsamiq, MockFlow, or similar wireframing software -## Rubric +**Label your mockup sections** with the HTML elements you plan to use (e.g., "Header - `<header>`", "Blog Posts - `<article>`"). -| Criteria | Outstanding | Satisfactory | Needs Improvement | -|------------------|-------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|---------------------------------------------------------------------------------| -| Visual Mockup | Detailed and clear mockup with labeled sections and a thoughtful layout | Basic mockup with some labeled sections | Incomplete or unclear mockup; missing section labels | -| HTML Elements | Includes 10+ semantic HTML elements; shows understanding of structure and best practices | Includes 5–9 HTML elements; some semantic structure | Includes fewer than 5 elements; lacks semantic structure | -| Code Quality | Code is well-organized, readable, and includes comments; adheres to HTML standards | Code is mostly organized; few comments | Code is disorganized; lacks comments | -| Reflection | Provides meaningful insights into design choices and challenges | Offers a basic reflection | No reflection or lacks relevance | +### Part 2: HTML Element Planning -## Tips +**Create a list mapping each section of your mockup to specific HTML elements:** -- Use semantic HTML tags to improve accessibility and SEO. -- Organize your code with proper indentation and comments. -- Refer to [MDN HTML Elements Reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) for guidance. -- Consider how your layout could be expanded or styled in future assignments. +``` +Example: +- Site Header → <header> +- Main Navigation → <nav> with <ul> and <li> +- Blog Post → <article> with <h2>, <p>, <time> +- Sidebar → <aside> with <section> elements +- Page Footer → <footer> +``` + +**Required Elements to Include:** +Your HTML must contain at least 10 different semantic elements from this list: +- `<header>`, `<nav>`, `<main>`, `<article>`, `<section>`, `<aside>`, `<footer>` +- `<h1>`, `<h2>`, `<h3>`, `<p>`, `<ul>`, `<li>`, `<a>` +- `<img>`, `<time>`, `<blockquote>`, `<strong>`, `<em>` + +### Part 3: HTML Implementation + +**Code your blog homepage following these standards:** + +1. **Document Structure**: Include proper DOCTYPE, html, head, and body elements +2. **Semantic Markup**: Use HTML elements for their intended purpose +3. **Accessibility**: Include proper alt text for images and meaningful link text +4. **Code Quality**: Use consistent indentation and meaningful comments +5. **Content**: Include realistic blog content (you can use placeholder text) + +**Sample HTML Structure:** +```html +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>My Personal Blog + + + +
+

My Blog Title

+ +
+ + +
+ +
+ + + + + +
+ +
+ + +``` + +### Part 4: Reflection + +**Write a brief reflection (3-5 sentences) addressing:** +- Which HTML elements were you most confident using? +- What challenges did you encounter while planning or coding? +- How did semantic HTML help organize your content? +- What would you do differently in your next HTML project? + +## Submission Checklist + +**Before submitting, ensure you have:** +- [ ] Visual mockup with labeled HTML elements +- [ ] Complete HTML file with proper document structure +- [ ] At least 10 different semantic HTML elements used appropriately +- [ ] Meaningful comments explaining your code structure +- [ ] Valid HTML syntax (test in a browser) +- [ ] Written reflection addressing the prompt questions + +## Assessment Rubric + +| Criteria | Exemplary (4) | Proficient (3) | Developing (2) | Beginning (1) | +|----------|---------------|----------------|----------------|---------------| +| **Planning & Design** | Detailed, well-labeled mockup showing clear understanding of layout and HTML semantic structure | Clear mockup with most sections labeled appropriately | Basic mockup with some labeling, shows general understanding | Minimal or unclear mockup, lacks proper section identification | +| **Semantic HTML Usage** | Uses 10+ semantic elements appropriately, demonstrates deep understanding of HTML structure and accessibility | Uses 8-9 semantic elements correctly, shows good understanding of semantic markup | Uses 6-7 semantic elements, some confusion about appropriate usage | Uses fewer than 6 elements or misuses semantic elements | +| **Code Quality & Organization** | Exceptionally well-organized, properly indented code with comprehensive comments and perfect HTML syntax | Well-organized code with good indentation, helpful comments, and valid syntax | Mostly organized code with some comments, minor syntax issues | Poor organization, minimal comments, multiple syntax errors | +| **Accessibility & Best Practices** | Excellent accessibility considerations, meaningful alt text, proper heading hierarchy, follows all modern HTML best practices | Good accessibility features, appropriate use of headings and alt text, follows most best practices | Some accessibility considerations, basic alt text and heading structure | Limited accessibility features, poor heading structure, doesn't follow best practices | +| **Reflection & Learning** | Insightful reflection demonstrating deep understanding of HTML concepts and thoughtful analysis of the learning process | Good reflection showing understanding of key concepts and some self-awareness of learning | Basic reflection with limited insight into HTML concepts or learning process | Minimal or missing reflection, shows little understanding of concepts learned | + +## Learning Resources + +**Essential References:** +- [MDN HTML Elements Reference](https://developer.mozilla.org/docs/Web/HTML/Element) - Complete guide to all HTML elements +- [HTML5 Semantic Elements](https://developer.mozilla.org/docs/Web/HTML/Element#content_sectioning) - Understanding semantic markup +- [Web Accessibility Guidelines](https://www.w3.org/WAI/WCAG21/quickref/) - Creating accessible web content +- [HTML Validator](https://validator.w3.org/) - Check your HTML syntax + +**Pro Tips for Success:** +- Start with your mockup before writing any code +- Use the browser's developer tools to inspect your HTML structure +- Test your page with different screen sizes (even without CSS) +- Read your HTML aloud to check if the structure makes logical sense +- Consider how a screen reader would interpret your page structure + +> 💡 **Remember**: This assignment focuses on HTML structure and semantics. Don't worry about visual styling – that's what CSS is for! Your page might look plain, but it should be well-structured and meaningful. --- + **Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/3-terrarium/2-intro-to-css/README.md b/translations/en/3-terrarium/2-intro-to-css/README.md index 328518e8d..87bf3098e 100644 --- a/translations/en/3-terrarium/2-intro-to-css/README.md +++ b/translations/en/3-terrarium/2-intro-to-css/README.md @@ -1,275 +1,718 @@ - # Terrarium Project Part 2: Introduction to CSS -![Introduction to CSS](../../../../translated_images/en/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.png) +```mermaid +journey + title Your CSS Styling Journey + section Foundation + Link CSS file: 3: Student + Understand cascade: 4: Student + Learn inheritance: 4: Student + section Selectors + Element targeting: 4: Student + Class patterns: 5: Student + ID specificity: 5: Student + section Layout + Position elements: 4: Student + Create containers: 5: Student + Build terrarium: 5: Student + section Polish + Add visual effects: 5: Student + Responsive design: 5: Student + Glass reflections: 5: Student +``` +![Introduction to CSS](../../../../translated_images/en/webdev101-css.3f7af5991bf53a20.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) +Remember how your HTML terrarium looked quite basic? CSS is where we transform that plain structure into something visually appealing. + +If HTML is like building the frame of a house, then CSS is everything that makes it feel like home - the paint colors, the furniture arrangement, the lighting, and how the rooms flow together. Think of how the Palace of Versailles started as a simple hunting lodge, but careful attention to decoration and layout transformed it into one of the world's most magnificent buildings. + +Today, we'll transform your terrarium from functional to polished. You'll learn how to position elements precisely, make layouts respond to different screen sizes, and create the visual appeal that makes websites engaging. + +By the end of this lesson, you'll see how strategic CSS styling can dramatically improve your project. Let's add some style to your terrarium. + +```mermaid +mindmap + root((CSS Fundamentals)) + Cascade + Specificity Rules + Inheritance + Priority Order + Conflict Resolution + Selectors + Element Tags + Classes (.class) + IDs (#id) + Combinators + Box Model + Margin + Border + Padding + Content + Layout + Positioning + Display Types + Flexbox + Grid + Visual Effects + Colors + Shadows + Transitions + Animations + Responsive Design + Media Queries + Flexible Units + Viewport Meta + Mobile First +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/17) -### Introduction +## Getting Started with CSS + +CSS is often thought of as just "making things pretty," but it serves a much broader purpose. CSS is like being the director of a movie - you control not just how everything looks, but how it moves, responds to interaction, and adapts to different situations. -CSS, or Cascading Style Sheets, addresses a key challenge in web development: making your website visually appealing. Styling your apps not only enhances their usability and aesthetics but also enables Responsive Web Design (RWD), ensuring your apps look great on any screen size. CSS goes beyond just making things look good; its specifications include animations and transformations that allow for advanced interactions in your apps. The CSS Working Group maintains the current CSS specifications, and you can follow their work on the [World Wide Web Consortium's site](https://www.w3.org/Style/CSS/members). +Modern CSS is remarkably capable. You can write code that automatically adjusts layouts for phones, tablets, and desktop computers. You can create smooth animations that guide users' attention where needed. The results can be quite impressive when everything works together. -> Note: CSS is an evolving language, like everything on the web, and not all browsers support the latest specifications. Always verify your implementations using [CanIUse.com](https://caniuse.com). +> 💡 **Pro Tip**: CSS is constantly evolving with new features and capabilities. Always check [CanIUse.com](https://caniuse.com) to verify browser support for newer CSS features before using them in production projects. -In this lesson, we’ll add styles to our online terrarium and explore key CSS concepts: the cascade, inheritance, selectors, positioning, and using CSS for layouts. By the end, we’ll have styled the terrarium and created the actual terrarium itself. +**Here's what we'll accomplish in this lesson:** +- **Creates** a complete visual design for your terrarium using modern CSS techniques +- **Explores** fundamental concepts like the cascade, inheritance, and CSS selectors +- **Implements** responsive positioning and layout strategies +- **Builds** the terrarium container using CSS shapes and styling ### Prerequisite -You should already have the HTML for your terrarium prepared and ready for styling. +You should have completed the HTML structure for your terrarium from the previous lesson and have it ready to be styled. -> Watch the video +> 📺 **Video Resource**: Check out this helpful video walkthrough +> +> [![CSS Basics Tutorial](https://img.youtube.com/vi/6yIdOIV9p1I/0.jpg)](https://www.youtube.com/watch?v=6yIdOIV9p1I) -> -> [![Git and GitHub basics video](https://img.youtube.com/vi/6yIdOIV9p1I/0.jpg)](https://www.youtube.com/watch?v=6yIdOIV9p1I) +### Setting Up Your CSS File -### Task +Before we can start styling, we need to connect CSS to our HTML. This connection tells the browser where to find the styling instructions for our terrarium. -In your terrarium folder, create a new file called `style.css`. Link this file in the `` section of your HTML: +In your terrarium folder, create a new file called `style.css`, then link it in your HTML document's `` section: ```html ``` ---- +**Here's what this code does:** +- **Creates** a connection between your HTML and CSS files +- **Tells** the browser to load and apply the styles from `style.css` +- **Uses** the `rel="stylesheet"` attribute to specify this is a CSS file +- **References** the file path with `href="./style.css"` + +## Understanding the CSS Cascade -## The Cascade +Ever wondered why CSS is called "Cascading" Style Sheets? Styles cascade down like a waterfall, and sometimes they conflict with each other. -Cascading Style Sheets are based on the concept of "cascading," meaning that the application of styles is determined by their priority. Styles defined by the website author take precedence over browser defaults. Inline styles have the highest priority, followed by styles in external stylesheets. +Consider how military command structures work - a general order might say "all troops wear green," but a specific order to your unit might say "wear dress blues for the ceremony." The more specific instruction takes precedence. CSS follows similar logic, and understanding this hierarchy makes debugging much more manageable. -### Task +### Experimenting with Cascade Priority -Add the inline style "color: red" to your `

` tag: +Let's see the cascade in action by creating a style conflict. First, add an inline style to your `

` tag: -```HTML +```html

My Terrarium

``` -Next, add the following code to your `style.css` file: +**What this code does:** +- **Applies** a red color directly to the `

` element using inline styling +- **Uses** the `style` attribute to embed CSS directly in the HTML +- **Creates** the highest priority style rule for this specific element + +Next, add this rule to your `style.css` file: -```CSS +```css h1 { - color: blue; + color: blue; } ``` -✅ Which color appears in your web app? Why? Can you find a way to override styles? When might you want to do this, or why not? +**In the above, we've:** +- **Defined** a CSS rule that targets all `

` elements +- **Set** the text color to blue using an external stylesheet +- **Created** a lower priority rule compared to inline styles + +✅ **Knowledge Check**: Which color displays in your web app? Why does that color win? Can you think of scenarios where you might want to override styles? + +```mermaid +flowchart TD + A["Browser encounters h1 element"] --> B{"Check for inline styles"} + B -->|Found| C["style='color: red'"] + B -->|None| D{"Check for ID rules"} + C --> E["Apply red color (1000 points)"] + D -->|Found| F["#heading { color: green }"] + D -->|None| G{"Check for class rules"} + F --> H["Apply green color (100 points)"] + G -->|Found| I[".title { color: blue }"] + G -->|None| J{"Check element rules"} + I --> K["Apply blue color (10 points)"] + J -->|Found| L["h1 { color: purple }"] + J -->|None| M["Use browser default"] + L --> N["Apply purple color (1 point)"] + + style C fill:#ff6b6b + style F fill:#51cf66 + style I fill:#339af0 + style L fill:#9775fa +``` +> 💡 **CSS Priority Order (highest to lowest):** +> 1. **Inline styles** (style attribute) +> 2. **IDs** (#myId) +> 3. **Classes** (.myClass) and attributes +> 4. **Element selectors** (h1, div, p) +> 5. **Browser defaults** ---- +## CSS Inheritance in Action -## Inheritance +CSS inheritance works like genetics - elements inherit certain properties from their parent elements. If you set the font family on the body element, all text inside automatically uses that same font. It's similar to how the Habsburg family's distinctive jawline appeared across generations without being specified for each individual. -Styles are passed down from parent elements to their child elements, meaning nested elements inherit the styles of their parent. +However, not everything gets inherited. Text styles like fonts and colors do inherit, but layout properties like margins and borders do not. Just as children might inherit physical traits but not their parents' fashion choices. -### Task +### Observing Font Inheritance -Set the font for the body and check if a nested element inherits it: +Let's see inheritance in action by setting a font family on the `` element: -```CSS +```css body { - font-family: helvetica, arial, sans-serif; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } ``` -Open your browser's console and inspect the 'Elements' tab. Observe the font of the `

` tag. You’ll see that it inherits the font from the body, as indicated by the browser: +**Breaking down what happens here:** +- **Sets** the font family for the entire page by targeting the `` element +- **Uses** a font stack with fallback options for better browser compatibility +- **Applies** modern system fonts that look great across different operating systems +- **Ensures** all child elements inherit this font unless specifically overridden -![inherited font](../../../../translated_images/en/1.cc07a5cbe114ad1d4728c35134584ac1b87db688eff83cf75985cf31fe0ed95c.png) +Open your browser's developer tools (F12), navigate to the Elements tab, and inspect your `

` element. You'll see that it inherits the font family from the body: -✅ Can you make a nested style inherit a different property? +![inherited font](../../../../translated_images/en/1.cc07a5cbe114ad1d.webp) ---- +✅ **Experiment Time**: Try setting other inheritable properties on the `` like `color`, `line-height`, or `text-align`. What happens to your heading and other elements? + +> 📝 **Inheritable Properties Include**: `color`, `font-family`, `font-size`, `line-height`, `text-align`, `visibility` +> +> **Non-Inheritable Properties Include**: `margin`, `padding`, `border`, `width`, `height`, `position` + +### 🔄 **Pedagogical Check-in** +**CSS Foundation Understanding**: Before moving to selectors, ensure you can: +- ✅ Explain the difference between cascade and inheritance +- ✅ Predict which style will win in a specificity conflict +- ✅ Identify which properties inherit from parent elements +- ✅ Connect CSS files to HTML properly + +**Quick Test**: If you have these styles, what color will an `

` inside a `
` be? +```css +div { color: blue; } +.special { color: green; } +h1 { color: red; } +``` +*Answer: Red (element selector directly targets h1)* + +## Mastering CSS Selectors -## CSS Selectors +CSS selectors are your way of targeting specific elements for styling. They work like giving precise directions - instead of saying "the house," you might say "the blue house with the red door on Maple Street." -### Tags +CSS provides different ways to be specific, and choosing the right selector is like choosing the appropriate tool for the task. Sometimes you need to style every door in the neighborhood, and sometimes just one specific door. -So far, your `style.css` file has only a few tags styled, and the app looks a bit odd: +### Element Selectors (Tags) -```CSS +Element selectors target HTML elements by their tag name. They're perfect for setting base styles that apply broadly across your page: + +```css body { - font-family: helvetica, arial, sans-serif; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + margin: 0; + padding: 0; } h1 { - color: #3a241d; - text-align: center; + color: #3a241d; + text-align: center; + font-size: 2.5rem; + margin-bottom: 1rem; } ``` -This method of styling tags allows you to control individual elements, but to style multiple plants in your terrarium, you’ll need to use CSS selectors. +**Understanding these styles:** +- **Sets** consistent typography across the entire page with the `body` selector +- **Removes** default browser margins and padding for better control +- **Styles** all heading elements with color, alignment, and spacing +- **Uses** `rem` units for scalable, accessible font sizing + +While element selectors work well for general styling, you'll need more specific selectors to style individual components like the plants in your terrarium. -### Ids +### ID Selectors for Unique Elements -Add styles to position the left and right containers. Since there’s only one left container and one right container, they are assigned ids in the HTML. Use `#` to style them: +ID selectors use the `#` symbol and target elements with specific `id` attributes. Since IDs must be unique on a page, they're perfect for styling individual, special elements like our left and right plant containers. -```CSS +Let's create the styling for our terrarium's side containers where the plants will live: + +```css #left-container { - background-color: #eee; - width: 15%; - left: 0px; - top: 0px; - position: absolute; - height: 100%; - padding: 10px; + background-color: #f5f5f5; + width: 15%; + left: 0; + top: 0; + position: absolute; + height: 100vh; + padding: 1rem; + box-sizing: border-box; } #right-container { - background-color: #eee; - width: 15%; - right: 0px; - top: 0px; - position: absolute; - height: 100%; - padding: 10px; + background-color: #f5f5f5; + width: 15%; + right: 0; + top: 0; + position: absolute; + height: 100vh; + padding: 1rem; + box-sizing: border-box; } ``` -Here, the containers are positioned absolutely on the far left and right of the screen, with their widths set as percentages to ensure they scale on smaller mobile screens. +**Here's what this code accomplishes:** +- **Positions** containers at the far left and right edges using `absolute` positioning +- **Uses** `vh` (viewport height) units for responsive height that adapts to screen size +- **Applies** `box-sizing: border-box` so padding is included in the total width +- **Removes** unnecessary `px` units from zero values for cleaner code +- **Sets** a subtle background color that's easier on the eyes than stark gray -✅ This code is repetitive and not "DRY" (Don’t Repeat Yourself). Can you find a better way to style these ids, perhaps by combining an id and a class? You’ll need to update the HTML and refactor the CSS: +✅ **Code Quality Challenge**: Notice how this CSS violates the DRY (Don't Repeat Yourself) principle. Can you refactor it using both an ID and a class? +**Improved approach:** ```html
+
``` -### Classes +```css +.container { + background-color: #f5f5f5; + width: 15%; + top: 0; + position: absolute; + height: 100vh; + padding: 1rem; + box-sizing: border-box; +} -In the example above, you styled two unique elements. To apply styles to multiple elements, use CSS classes. Style the plants in the left and right containers as follows. +#left-container { + left: 0; +} -Notice that each plant in the HTML has both ids and classes. The ids are used by JavaScript (added later) to manipulate the placement of plants in the terrarium. The classes, however, define the styles for all plants. +#right-container { + right: 0; +} +``` + +### Class Selectors for Reusable Styles + +Class selectors use the `.` symbol and are perfect when you want to apply the same styles to multiple elements. Unlike IDs, classes can be reused throughout your HTML, making them ideal for consistent styling patterns. + +In our terrarium, each plant needs similar styling but also needs individual positioning. We'll use a combination of classes for shared styles and IDs for unique positioning. +**Here's the HTML structure for each plant:** ```html
- plant + Decorative plant for terrarium
``` -Add the following to your `style.css` file: +**Key elements explained:** +- **Uses** `class="plant-holder"` for consistent container styling across all plants +- **Applies** `class="plant"` for shared image styling and behavior +- **Includes** unique `id="plant1"` for individual positioning and JavaScript interaction +- **Provides** descriptive alt text for screen reader accessibility -```CSS +Now add these styles to your `style.css` file: + +```css .plant-holder { - position: relative; - height: 13%; - left: -10px; + position: relative; + height: 13%; + left: -0.6rem; } .plant { - position: absolute; - max-width: 150%; - max-height: 150%; - z-index: 2; + position: absolute; + max-width: 150%; + max-height: 150%; + z-index: 2; + transition: transform 0.3s ease; } -``` - -Key points in this snippet include the combination of relative and absolute positioning, which we’ll discuss in the next section. Pay attention to how heights are managed using percentages: -- The plant holder’s height is set to 13%, ensuring all plants fit vertically within their containers without scrolling. -- The plant holder is shifted left to center the plants within their containers. The plant images have a lot of transparent space to make them draggable, so they need to be adjusted for better alignment. -- The plant’s max-width is set to 150%, allowing it to scale down as the browser window shrinks. Resize your browser to see how the plants stay within their containers while scaling down. - -Also noteworthy is the use of `z-index`, which controls the stacking order of elements (ensuring the plants appear on top of the container and look like they’re inside the terrarium). - -✅ Why do you need both a plant holder and a plant CSS selector? - -## CSS Positioning - -Mixing position properties (static, relative, fixed, absolute, and sticky) can be tricky, but when done correctly, it provides precise control over your page elements. - -- Absolutely positioned elements are placed relative to their nearest positioned ancestor. If none exists, they are positioned relative to the document body. -- Relatively positioned elements are offset from their original position based on the CSS instructions. - -In our example, the `plant-holder` is relatively positioned within an absolutely positioned container. This setup ensures the side containers are pinned to the left and right, while the `plant-holder` adjusts itself within the side containers, creating space for the plants to align vertically. +.plant:hover { + transform: scale(1.05); +} +``` -> The `plant` itself is absolutely positioned, which is necessary for making it draggable, as you’ll learn in the next lesson. +**Breaking down these styles:** +- **Creates** relative positioning for the plant holder to establish a positioning context +- **Sets** each plant holder to 13% height, ensuring all plants fit vertically without scrolling +- **Shifts** holders slightly left to better center plants within their containers +- **Allows** plants to scale responsively with `max-width` and `max-height` properties +- **Uses** `z-index` to layer plants above other elements in the terrarium +- **Adds** a subtle hover effect with CSS transitions for better user interaction + +✅ **Critical Thinking**: Why do we need both `.plant-holder` and `.plant` selectors? What would happen if we tried to use just one? + +> 💡 **Design Pattern**: The container (`.plant-holder`) controls layout and positioning, while the content (`.plant`) controls appearance and scaling. This separation makes the code more maintainable and flexible. + +## Understanding CSS Positioning + +CSS positioning is like being the stage director for a play - you direct where every actor stands and how they move around the stage. Some actors follow the standard formation, while others need specific positioning for dramatic effect. + +Once you understand positioning, many layout challenges become manageable. Need a navigation bar that stays at the top while users scroll? Positioning handles that. Want a tooltip that appears at a specific location? That's positioning too. + +### The Five Position Values + +```mermaid +quadrantChart + title CSS Positioning Strategy + x-axis Document Flow --> Removed from Flow + y-axis Static Position --> Precise Control + quadrant-1 Absolute + quadrant-2 Fixed + quadrant-3 Static + quadrant-4 Sticky + + Static: [0.2, 0.2] + Relative: [0.3, 0.6] + Absolute: [0.8, 0.8] + Fixed: [0.9, 0.7] + Sticky: [0.5, 0.9] +``` +| Position Value | Behavior | Use Case | +|----------------|----------|----------| +| `static` | Default flow, ignores top/left/right/bottom | Normal document layout | +| `relative` | Positioned relative to its normal position | Small adjustments, creating positioning context | +| `absolute` | Positioned relative to nearest positioned ancestor | Precise placement, overlays | +| `fixed` | Positioned relative to viewport | Navigation bars, floating elements | +| `sticky` | Switches between relative and fixed based on scroll | Headers that stick when scrolling | + +### Positioning in Our Terrarium + +Our terrarium uses a strategic combination of positioning types to create the desired layout: + +```css +/* Container positioning */ +.container { + position: absolute; /* Removes from normal flow */ + /* ... other styles ... */ +} -✅ Experiment with changing the positioning of the side containers and the `plant-holder`. What happens? +/* Plant holder positioning */ +.plant-holder { + position: relative; /* Creates positioning context */ + /* ... other styles ... */ +} -## CSS Layouts +/* Plant positioning */ +.plant { + position: absolute; /* Allows precise placement within holder */ + /* ... other styles ... */ +} +``` -Now, use what you’ve learned to build the terrarium itself using only CSS! +**Understanding the positioning strategy:** +- **Absolute containers** are removed from normal document flow and pinned to screen edges +- **Relative plant holders** create a positioning context while staying in document flow +- **Absolute plants** can be positioned precisely within their relative containers +- **This combination** allows plants to stack vertically while being individually positionable + +> 🎯 **Why This Matters**: The `plant` elements need absolute positioning to become draggable in the next lesson. Absolute positioning removes them from the normal layout flow, making drag-and-drop interactions possible. + +✅ **Experiment Time**: Try changing the positioning values and observe the results: +- What happens if you change `.container` from `absolute` to `relative`? +- How does the layout change if `.plant-holder` uses `absolute` instead of `relative`? +- What occurs when you switch `.plant` to `relative` positioning? + +### 🔄 **Pedagogical Check-in** +**CSS Positioning Mastery**: Pause to verify your understanding: +- ✅ Can you explain why plants need absolute positioning for drag-and-drop? +- ✅ Do you understand how relative containers create positioning context? +- ✅ Why do the side containers use absolute positioning? +- ✅ What would happen if you removed position declarations entirely? + +**Real-World Connection**: Think about how CSS positioning mirrors real-world layout: +- **Static**: Books on a shelf (natural order) +- **Relative**: Moving a book slightly but keeping its spot +- **Absolute**: Placing a bookmark at an exact page number +- **Fixed**: A sticky note that stays visible as you flip pages + +## Building the Terrarium with CSS + +Now we'll build a glass jar using only CSS - no images or graphics software required. + +Creating realistic-looking glass, shadows, and depth effects using positioning and transparency demonstrates CSS's visual capabilities. This technique mirrors how architects in the Bauhaus movement used simple geometric forms to create complex, beautiful structures. Once you understand these principles, you'll recognize the CSS techniques behind many web designs. + +```mermaid +flowchart LR + A[Jar Top] --> E[Complete Terrarium] + B[Jar Walls] --> E + C[Dirt Layer] --> E + D[Jar Bottom] --> E + F[Glass Effects] --> E + + A1["50% width
5% height
Top position"] --> A + B1["60% width
80% height
Rounded corners
0.5 opacity"] --> B + C1["60% width
5% height
Dark brown
Bottom layer"] --> C + D1["50% width
1% height
Bottom position"] --> D + F1["Subtle shadows
Transparency
Z-index layering"] --> F + + style E fill:#d1e1df,stroke:#3a241d + style A fill:#e8f5e8 + style B fill:#e8f5e8 + style C fill:#8B4513 + style D fill:#e8f5e8 +``` +### Creating the Glass Jar Components -First, style the `.terrarium` div children as a rounded rectangle: +Let's build the terrarium jar piece by piece. Each part uses absolute positioning and percentage-based sizing for responsive design: -```CSS +```css .jar-walls { - height: 80%; - width: 60%; - background: #d1e1df; - border-radius: 1rem; - position: absolute; - bottom: 0.5%; - left: 20%; - opacity: 0.5; - z-index: 1; + height: 80%; + width: 60%; + background: #d1e1df; + border-radius: 1rem; + position: absolute; + bottom: 0.5%; + left: 20%; + opacity: 0.5; + z-index: 1; + box-shadow: inset 0 0 2rem rgba(0, 0, 0, 0.1); } .jar-top { - width: 50%; - height: 5%; - background: #d1e1df; - position: absolute; - bottom: 80.5%; - left: 25%; - opacity: 0.7; - z-index: 1; + width: 50%; + height: 5%; + background: #d1e1df; + position: absolute; + bottom: 80.5%; + left: 25%; + opacity: 0.7; + z-index: 1; + border-radius: 0.5rem 0.5rem 0 0; } .jar-bottom { - width: 50%; - height: 1%; - background: #d1e1df; - position: absolute; - bottom: 0%; - left: 25%; - opacity: 0.7; + width: 50%; + height: 1%; + background: #d1e1df; + position: absolute; + bottom: 0; + left: 25%; + opacity: 0.7; + border-radius: 0 0 0.5rem 0.5rem; } .dirt { - width: 60%; - height: 5%; - background: #3a241d; - position: absolute; - border-radius: 0 0 1rem 1rem; - bottom: 1%; - left: 20%; - opacity: 0.7; - z-index: -1; + width: 60%; + height: 5%; + background: #3a241d; + position: absolute; + border-radius: 0 0 1rem 1rem; + bottom: 1%; + left: 20%; + opacity: 0.7; + z-index: -1; } ``` -Notice the use of percentages. If you resize your browser, the jar scales accordingly. Pay attention to the width and height percentages for the jar elements and how each is absolutely positioned in the center, pinned to the bottom of the viewport. +**Understanding the terrarium construction:** +- **Uses** percentage-based dimensions for responsive scaling across all screen sizes +- **Positions** elements absolutely to stack and align them precisely +- **Applies** different opacity values to create the glass transparency effect +- **Implements** `z-index` layering so plants appear inside the jar +- **Adds** subtle box-shadow and refined border-radius for more realistic appearance + +### Responsive Design with Percentages + +Notice how all dimensions use percentages rather than fixed pixel values: + +**Why this matters:** +- **Ensures** the terrarium scales proportionally on any screen size +- **Maintains** the visual relationships between jar components +- **Provides** a consistent experience from mobile phones to large desktop monitors +- **Allows** the design to adapt without breaking the visual layout -We’re also using `rem` for the border-radius, a font-relative unit. Learn more about this relative measurement in the [CSS spec](https://www.w3.org/TR/css-values-3/#font-relative-lengths). +### CSS Units in Action -✅ Try changing the jar’s colors and opacity compared to the dirt. What happens? Why? +We're using `rem` units for border-radius, which scale relative to the root font size. This creates more accessible designs that respect user font preferences. Learn more about [CSS relative units](https://www.w3.org/TR/css-values-3/#font-relative-lengths) in the official specification. + +✅ **Visual Experimentation**: Try modifying these values and observe the effects: +- Change the jar opacity from 0.5 to 0.8 – how does this affect the glass appearance? +- Adjust the dirt color from `#3a241d` to `#8B4513` – what visual impact does this have? +- Modify the `z-index` of the dirt to 2 – what happens to the layering? + +### 🔄 **Pedagogical Check-in** +**CSS Visual Design Understanding**: Confirm your grasp of visual CSS: +- ✅ How do percentage-based dimensions create responsive design? +- ✅ Why does opacity create the glass transparency effect? +- ✅ What role does z-index play in layering elements? +- ✅ How do border-radius values create the jar shape? + +**Design Principle**: Notice how we're building complex visuals from simple shapes: +1. **Rectangles** → **Rounded rectangles** → **Jar components** +2. **Flat colors** → **Opacity** → **Glass effect** +3. **Individual elements** → **Layered composition** → **3D appearance** --- -## 🚀Challenge +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: -Add a "bubble" shine to the bottom-left area of the jar to make it look more like glass. Style the `.jar-glossy-long` and `.jar-glossy-short` to create a reflective shine. Here’s the final result: +**Description:** Create a CSS animation that makes the terrarium plants gently sway back and forth, simulating a natural breeze effect. This will help you practice CSS animations, transforms, and keyframes while enhancing the visual appeal of your terrarium. -![finished terrarium](../../../../translated_images/en/terrarium-final.2f07047ffc597d0a06b06cab28a77801a10dd12fdb6c7fc630e9c40665491c53.png) +**Prompt:** Add CSS keyframe animations to make the plants in the terrarium sway gently from side to side. Create a swaying animation that rotates each plant slightly (2-3 degrees) left and right with a duration of 3-4 seconds, and apply it to the `.plant` class. Make sure the animation loops infinitely and has an easing function for natural movement. -To complete the post-lecture quiz, explore this Learn module: [Style your HTML app with CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon) +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + +## 🚀 Challenge: Adding Glass Reflections + +Ready to enhance your terrarium with realistic glass reflections? This technique will add depth and realism to the design. + +You'll create subtle highlights that simulate how light reflects off glass surfaces. This approach is similar to how Renaissance painters like Jan van Eyck used light and reflection to make painted glass appear three-dimensional. Here's what you're aiming for: + +![finished terrarium](../../../../translated_images/en/terrarium-final.2f07047ffc597d0a.webp) + +**Your challenge:** +- **Create** subtle white or light-colored oval shapes for the glass reflections +- **Position** them strategically on the left side of the jar +- **Apply** appropriate opacity and blur effects for realistic light reflection +- **Use** `border-radius` to create organic, bubble-like shapes +- **Experiment** with gradients or box-shadows for enhanced realism ## Post-Lecture Quiz [Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/18) -## Review & Self Study +## Expand Your CSS Knowledge + +CSS can feel complex initially, but understanding these core concepts provides a solid foundation for more advanced techniques. + +**Your next CSS learning areas:** +- **Flexbox** - simplifies alignment and distribution of elements +- **CSS Grid** - provides powerful tools for creating complex layouts +- **CSS Variables** - reduces repetition and improves maintainability +- **Responsive design** - ensures sites work well across different screen sizes + +### Interactive Learning Resources + +Practice these concepts with these engaging, hands-on games: +- 🐸 [Flexbox Froggy](https://flexboxfroggy.com/) - Master Flexbox through fun challenges +- 🌱 [Grid Garden](https://codepip.com/games/grid-garden/) - Learn CSS Grid by growing virtual carrots +- 🎯 [CSS Battle](https://cssbattle.dev/) - Test your CSS skills with coding challenges + +### Additional Learning + +For comprehensive CSS fundamentals, complete this Microsoft Learn module: [Style your HTML app with CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon) + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open DevTools and inspect CSS styles on any website using the Elements panel +- [ ] Create a simple CSS file and link it to an HTML page +- [ ] Try changing colors using different methods: hex, RGB, and named colors +- [ ] Practice the box model by adding padding and margin to a div + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and review CSS fundamentals +- [ ] Style your HTML page with fonts, colors, and spacing +- [ ] Create a simple layout using flexbox or grid +- [ ] Experiment with CSS transitions for smooth effects +- [ ] Practice responsive design with media queries + +### 📅 **Your Week-Long CSS Adventure** +- [ ] Complete the terrarium styling assignment with creative flair +- [ ] Master CSS Grid by building a photo gallery layout +- [ ] Learn CSS animations to bring your designs to life +- [ ] Explore CSS preprocessors like Sass or Less +- [ ] Study design principles and apply them to your CSS +- [ ] Analyze and recreate interesting designs you find online + +### 🌟 **Your Month-Long Design Mastery** +- [ ] Build a complete responsive website design system +- [ ] Learn CSS-in-JS or utility-first frameworks like Tailwind +- [ ] Contribute to open source projects with CSS improvements +- [ ] Master advanced CSS concepts like CSS custom properties and containment +- [ ] Create reusable component libraries with modular CSS +- [ ] Mentor others learning CSS and share design knowledge + +## 🎯 Your CSS Mastery Timeline + +```mermaid +timeline + title CSS Learning Progression + + section Foundation (10 minutes) + File Connection: Link CSS to HTML + : Understand cascade rules + : Learn inheritance basics + + section Selectors (15 minutes) + Targeting Elements: Element selectors + : Class patterns + : ID specificity + : Combinators + + section Box Model (20 minutes) + Layout Fundamentals: Margin and padding + : Border properties + : Content sizing + : Box-sizing behavior + + section Positioning (25 minutes) + Element Placement: Static vs relative + : Absolute positioning + : Z-index layering + : Responsive units + + section Visual Design (30 minutes) + Styling Mastery: Colors and opacity + : Shadows and effects + : Transitions + : Transform properties + + section Responsive Design (45 minutes) + Multi-Device Support: Media queries + : Flexible layouts + : Mobile-first approach + : Viewport optimization + + section Advanced Techniques (1 week) + Modern CSS: Flexbox layouts + : CSS Grid systems + : Custom properties + : Animation keyframes + + section Professional Skills (1 month) + CSS Architecture: Component patterns + : Maintainable code + : Performance optimization + : Cross-browser compatibility +``` +### 🛠️ Your CSS Toolkit Summary + +After completing this lesson, you now have: +- **Cascade Understanding**: How styles inherit and override each other +- **Selector Mastery**: Precise targeting with elements, classes, and IDs +- **Positioning Skills**: Strategic element placement and layering +- **Visual Design**: Creating glass effects, shadows, and transparency +- **Responsive Techniques**: Percentage-based layouts that adapt to any screen +- **Code Organization**: Clean, maintainable CSS structure +- **Modern Practices**: Using relative units and accessible design patterns -CSS may seem simple, but styling an app perfectly for all browsers and screen sizes can be challenging. Tools like CSS Grid and Flexbox make this process more structured and reliable. Learn about these tools by playing [Flexbox Froggy](https://flexboxfroggy.com/) and [Grid Garden](https://codepip.com/games/grid-garden/). +**Next Steps**: Your terrarium now has both structure (HTML) and style (CSS). The final lesson will add interactivity with JavaScript! ## Assignment @@ -277,5 +720,7 @@ CSS may seem simple, but styling an app perfectly for all browsers and screen si --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, a professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. + \ No newline at end of file diff --git a/translations/en/3-terrarium/2-intro-to-css/assignment.md b/translations/en/3-terrarium/2-intro-to-css/assignment.md index 15295f595..70f930c4d 100644 --- a/translations/en/3-terrarium/2-intro-to-css/assignment.md +++ b/translations/en/3-terrarium/2-intro-to-css/assignment.md @@ -1,41 +1,127 @@ - # CSS Refactoring Assignment ## Objective -Refactor the terrarium project to use **Flexbox** or **CSS Grid** for layout. Update the HTML and CSS as needed to achieve a modern, responsive design. You do not need to implement draggable elements—focus solely on layout and styling. +Transform your terrarium project to use modern CSS layout techniques! Refactor the current absolute positioning approach to implement **Flexbox** or **CSS Grid** for a more maintainable, responsive design. This assignment challenges you to apply modern CSS standards while maintaining the visual appeal of your terrarium. + +Understanding when and how to use different layout methods is a crucial skill for modern web development. This exercise bridges traditional positioning techniques with contemporary CSS layout systems. + +## Assignment Instructions + +### Phase 1: Analysis and Planning +1. **Review your current terrarium code** - Identify which elements are currently using absolute positioning +2. **Choose your layout method** - Decide whether Flexbox or CSS Grid better suits your design goals +3. **Sketch your new layout structure** - Plan how containers and plant elements will be organized + +### Phase 2: Implementation +1. **Create a new version** of your terrarium project in a separate folder +2. **Update the HTML structure** as needed to support your chosen layout method +3. **Refactor the CSS** to use Flexbox or CSS Grid instead of absolute positioning +4. **Maintain visual consistency** - Ensure your plants and terrarium jar appear in the same positions +5. **Implement responsive behavior** - Your layout should adapt gracefully to different screen sizes + +### Phase 3: Testing and Documentation +1. **Cross-browser testing** - Verify your design works in Chrome, Firefox, Edge, and Safari +2. **Responsive testing** - Check your layout on mobile, tablet, and desktop screen sizes +3. **Documentation** - Add comments to your CSS explaining your layout choices +4. **Screenshots** - Capture your terrarium in different browsers and screen sizes + +## Technical Requirements + +### Layout Implementation +- **Choose ONE**: Implement either Flexbox OR CSS Grid (not both for the same elements) +- **Responsive Design**: Use relative units (`rem`, `em`, `%`, `vw`, `vh`) instead of fixed pixels +- **Accessibility**: Maintain proper semantic HTML structure and alt text +- **Code Quality**: Use consistent naming conventions and organize CSS logically + +### Modern CSS Features to Include +```css +/* Example Flexbox approach */ +.terrarium-container { + display: flex; + flex-direction: column; + min-height: 100vh; + align-items: center; + justify-content: center; +} + +.plant-containers { + display: flex; + justify-content: space-between; + width: 100%; + max-width: 1200px; +} + +/* Example Grid approach */ +.terrarium-layout { + display: grid; + grid-template-columns: 1fr 3fr 1fr; + grid-template-rows: auto 1fr; + min-height: 100vh; + gap: 1rem; +} +``` + +### Browser Support Requirements +- **Chrome/Edge**: Latest 2 versions +- **Firefox**: Latest 2 versions +- **Safari**: Latest 2 versions +- **Mobile browsers**: iOS Safari, Chrome Mobile + +## Deliverables + +1. **Updated HTML file** with improved semantic structure +2. **Refactored CSS file** using modern layout techniques +3. **Screenshot collection** showing cross-browser compatibility: + - Desktop view (1920x1080) + - Tablet view (768x1024) + - Mobile view (375x667) + - At least 2 different browsers +4. **README.md file** documenting: + - Your layout choice (Flexbox vs Grid) and reasoning + - Challenges faced during refactoring + - Browser compatibility notes + - Instructions for running your code + +## Assessment Rubric + +| Criteria | Exemplary (4) | Proficient (3) | Developing (2) | Beginning (1) | +|----------|---------------|----------------|---------------|---------------| +| **Layout Implementation** | Masterful use of Flexbox/Grid with advanced features; fully responsive | Correct implementation with good responsive behavior | Basic implementation with minor responsive issues | Incomplete or incorrect layout implementation | +| **Code Quality** | Clean, well-organized CSS with meaningful comments and consistent naming | Good organization with some comments | Adequate organization with minimal comments | Poor organization; difficult to understand | +| **Cross-Browser Compatibility** | Perfect consistency across all required browsers with screenshots | Good compatibility with minor differences documented | Some compatibility issues that don't break functionality | Major compatibility problems or missing testing | +| **Responsive Design** | Exceptional mobile-first approach with smooth breakpoints | Good responsive behavior with appropriate breakpoints | Basic responsive features with some layout issues | Limited or broken responsive behavior | +| **Documentation** | Comprehensive README with detailed explanations and insights | Good documentation covering all required elements | Basic documentation with minimal explanations | Incomplete or missing documentation | + +## Helpful Resources -## Instructions +### Layout Method Guides +- 📖 [A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) +- 📖 [A Complete Guide to CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) +- 📖 [Flexbox vs Grid - Choose the Right Tool](https://blog.webdevsimplified.com/2022-11/flexbox-vs-grid/) -1. **Create a new version** of the terrarium app. Modify the HTML and CSS to utilize Flexbox or CSS Grid for layout. -2. **Ensure all artwork and elements are properly displayed** as in the original version. -3. **Test your design** in at least two different browsers (e.g., Chrome, Firefox, Edge). -4. **Take screenshots** of your terrarium in each browser to showcase cross-browser compatibility. -5. **Submit** your updated code along with the screenshots. +### Browser Testing Tools +- 🛠️ [Browser DevTools Responsive Mode](https://developer.chrome.com/docs/devtools/device-mode/) +- 🛠️ [Can I Use - Feature Support](https://caniuse.com/) +- 🛠️ [BrowserStack - Cross-browser Testing](https://www.browserstack.com/) -## Rubric +### Code Quality Tools +- ✅ [CSS Validator](https://jigsaw.w3.org/css-validator/) +- ✅ [HTML Validator](https://validator.w3.org/) +- ✅ [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/) -| Criteria | Outstanding | Satisfactory | Needs Improvement | -|------------|--------------------------------------------------------------------------|---------------------------------------|----------------------------------------| -| Layout | Fully refactored using Flexbox or CSS Grid; visually appealing and responsive | Partial refactoring; some use of Flexbox or Grid | Minimal or no use of Flexbox or Grid; layout unchanged | -| Cross-Browser | Screenshots provided for multiple browsers; consistent appearance | Screenshots for one browser; minor inconsistencies | No screenshots or major inconsistencies | -| Code Quality | Clean, well-structured HTML/CSS; clear comments | Some structure; few comments | Disorganized code; lacks comments | +## Bonus Challenges -## Tips +🌟 **Advanced Layouts**: Implement both Flexbox AND Grid in different parts of your design +🌟 **Animation Integration**: Add CSS transitions or animations that work with your new layout +🌟 **Dark Mode**: Implement a CSS custom properties-based theme switcher +🌟 **Container Queries**: Use modern container query techniques for component-level responsiveness -- Refer to [Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) and [CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) guides. -- Use browser developer tools to check responsiveness. -- Add comments to your code for better clarity. +> 💡 **Remember**: The goal isn't just to make it work, but to understand WHY your chosen layout method is the best solution for this particular design challenge! --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/3-terrarium/3-intro-to-DOM-and-closures/README.md b/translations/en/3-terrarium/3-intro-to-DOM-and-closures/README.md index 5823242f4..395aa0d4c 100644 --- a/translations/en/3-terrarium/3-intro-to-DOM-and-closures/README.md +++ b/translations/en/3-terrarium/3-intro-to-DOM-and-closures/README.md @@ -1,62 +1,196 @@ - -# Terrarium Project Part 3: DOM Manipulation and a Closure - -![DOM and a closure](../../../../translated_images/en/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.png) +# Terrarium Project Part 3: DOM Manipulation and JavaScript Closures + +```mermaid +journey + title Your JavaScript DOM Journey + section Foundation + Understand DOM: 3: Student + Learn closures: 4: Student + Connect elements: 4: Student + section Interaction + Setup drag events: 4: Student + Track coordinates: 5: Student + Handle movement: 5: Student + section Polish + Add cleanup: 4: Student + Test functionality: 5: Student + Complete terrarium: 5: Student +``` +![DOM and a closure](../../../../translated_images/en/webdev101-js.10280393044d7eaa.webp) > Sketchnote by [Tomomi Imura](https://twitter.com/girlie_mac) +Welcome to one of the most engaging aspects of web development - making things interactive! The Document Object Model (DOM) is like a bridge between your HTML and JavaScript, and today we'll use it to bring your terrarium to life. When Tim Berners-Lee created the first web browser, he envisioned a web where documents could be dynamic and interactive - the DOM makes that vision possible. + +We'll also explore JavaScript closures, which might sound intimidating initially. Think of closures as creating "memory pockets" where your functions can remember important information. It's like each plant in your terrarium having its own data record to track its position. By the end of this lesson, you'll understand how natural and useful they are. + +Here's what we're building: a terrarium where users can drag and drop plants anywhere they want. You'll learn the DOM manipulation techniques that power everything from drag-and-drop file uploads to interactive games. Let's make your terrarium come alive. + +```mermaid +mindmap + root((DOM & JavaScript)) + DOM Tree + Element Selection + Property Access + Event Handling + Dynamic Updates + Events + Pointer Events + Mouse Events + Touch Events + Event Listeners + Closures + Private Variables + Function Scope + Memory Persistence + State Management + Drag & Drop + Position Tracking + Coordinate Math + Event Lifecycle + User Interaction + Modern Patterns + Event Delegation + Performance + Cross-Device + Accessibility +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/19) -### Introduction +## Understanding the DOM: Your Gateway to Interactive Web Pages + +The Document Object Model (DOM) is how JavaScript communicates with your HTML elements. When your browser loads an HTML page, it creates a structured representation of that page in memory - that's the DOM. Think of it as a family tree where every HTML element is a family member that JavaScript can access, modify, or rearrange. + +DOM manipulation transforms static pages into interactive websites. Every time you see a button change color on hover, content update without page refresh, or elements you can drag around, that's DOM manipulation at work. + +```mermaid +flowchart TD + A["Document"] --> B["HTML"] + B --> C["Head"] + B --> D["Body"] + C --> E["Title"] + C --> F["Meta Tags"] + D --> G["H1: My Terrarium"] + D --> H["Div: Page Container"] + H --> I["Div: Left Container"] + H --> J["Div: Right Container"] + H --> K["Div: Terrarium"] + I --> L["Plant Elements 1-7"] + J --> M["Plant Elements 8-14"] + + L --> N["img#plant1"] + L --> O["img#plant2"] + M --> P["img#plant8"] + M --> Q["img#plant9"] + + style A fill:#e1f5fe + style B fill:#f3e5f5 + style D fill:#e8f5e8 + style H fill:#fff3e0 + style N fill:#ffebee + style O fill:#ffebee + style P fill:#ffebee + style Q fill:#ffebee +``` +![DOM tree representation](../../../../translated_images/en/dom-tree.7daf0e763cbbba92.webp) + +> A representation of the DOM and the HTML markup that references it. From [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites) + +**Here's what makes the DOM powerful:** +- **Provides** a structured way to access any element on your page +- **Enables** dynamic content updates without page refreshes +- **Allows** real-time response to user interactions like clicks and drags +- **Creates** the foundation for modern interactive web applications + +## JavaScript Closures: Creating Organized, Powerful Code + +A [JavaScript closure](https://developer.mozilla.org/docs/Web/JavaScript/Closures) is like giving a function its own private workspace with persistent memory. Consider how Darwin's finches on the Galápagos Islands each developed specialized beaks based on their specific environment - closures work similarly, creating specialized functions that "remember" their specific context even after their parent function has finished. + +In our terrarium, closures help each plant remember its own position independently. This pattern appears throughout professional JavaScript development, making it a valuable concept to understand. + +```mermaid +flowchart LR + A["dragElement(plant1)"] --> B["Creates Closure"] + A2["dragElement(plant2)"] --> B2["Creates Closure"] + + B --> C["Private Variables"] + B2 --> C2["Private Variables"] + + C --> D["pos1, pos2, pos3, pos4"] + C --> E["pointerDrag function"] + C --> F["elementDrag function"] + C --> G["stopElementDrag function"] + + C2 --> D2["pos1, pos2, pos3, pos4"] + C2 --> E2["pointerDrag function"] + C2 --> F2["elementDrag function"] + C2 --> G2["stopElementDrag function"] + + H["Plant 1 remembers its position"] --> B + H2["Plant 2 remembers its position"] --> B2 + + style B fill:#e8f5e8 + style B2 fill:#e8f5e8 + style C fill:#fff3e0 + style C2 fill:#fff3e0 +``` +> 💡 **Understanding Closures**: Closures are a significant topic in JavaScript, and many developers use them for years before fully grasping all the theoretical aspects. Today, we're focusing on practical application - you'll see closures naturally emerge as we build our interactive features. Understanding will develop as you see how they solve real problems. -Manipulating the DOM, or the "Document Object Model," is a fundamental part of web development. According to [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "The Document Object Model (DOM) is the data representation of the objects that comprise the structure and content of a document on the web." The challenges of DOM manipulation have often led developers to use JavaScript frameworks instead of plain JavaScript to manage the DOM, but we’ll tackle it ourselves! +![DOM tree representation](../../../../translated_images/en/dom-tree.7daf0e763cbbba92.webp) -Additionally, this lesson introduces the concept of a [JavaScript closure](https://developer.mozilla.org/docs/Web/JavaScript/Closures), which you can think of as a function wrapped inside another function, allowing the inner function to access the outer function's scope. +> A representation of the DOM and the HTML markup that references it. From [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites) -> JavaScript closures are a broad and complex topic. This lesson covers the basic idea that in the terrarium's code, you’ll encounter a closure: an inner function and an outer function structured in a way that lets the inner function access the outer function's scope. For more details, check out the [comprehensive documentation](https://developer.mozilla.org/docs/Web/JavaScript/Closures). +In this lesson, we will complete our interactive terrarium project by creating the JavaScript that will allow a user to manipulate the plants on the page. -We’ll use a closure to manipulate the DOM. +## Before We Begin: Setting Up for Success -Think of the DOM as a tree that represents all the ways a web page document can be manipulated. Various APIs (Application Program Interfaces) have been created to allow developers to access, edit, rearrange, and manage the DOM using their preferred programming language. +You'll need your HTML and CSS files from the previous terrarium lessons - we're about to make that static design interactive. If you're joining for the first time, completing those lessons first will provide important context. -![DOM tree representation](../../../../translated_images/en/dom-tree.7daf0e763cbbba9273f9a66fe04c98276d7d23932309b195cb273a9cf1819b42.png) +Here's what we'll build: +- **Smooth drag-and-drop** for all terrarium plants +- **Coordinate tracking** so plants remember their positions +- **A complete interactive interface** using vanilla JavaScript +- **Clean, organized code** using closure patterns -> A representation of the DOM and the HTML markup that references it. From [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites) +## Setting Up Your JavaScript File -In this lesson, we’ll complete our interactive terrarium project by writing JavaScript that lets users move plants around the page. +Let's create the JavaScript file that will make your terrarium interactive. -### Prerequisite +**Step 1: Create your script file** -You should already have the HTML and CSS for your terrarium set up. By the end of this lesson, you’ll be able to drag plants into and out of the terrarium. +In your terrarium folder, create a new file called `script.js`. -### Task +**Step 2: Link the JavaScript to your HTML** -In your terrarium folder, create a new file called `script.js`. Import this file in the `` section: +Add this script tag to the `` section of your `index.html` file: ```html - + ``` -> Note: Use `defer` when importing an external JavaScript file into the HTML file to ensure the JavaScript runs only after the HTML file has fully loaded. Alternatively, you could use the `async` attribute, which allows the script to execute while the HTML file is still being parsed. However, in our case, it’s important for the HTML elements to be fully loaded before the drag script runs. +**Why the `defer` attribute is important:** +- **Ensures** your JavaScript waits until all HTML is loaded +- **Prevents** errors where JavaScript looks for elements that aren't ready yet +- **Guarantees** all your plant elements are available for interaction +- **Provides** better performance than placing scripts at the page bottom + +> ⚠️ **Important Note**: The `defer` attribute prevents common timing issues. Without it, JavaScript may try to access HTML elements before they're loaded, causing errors. --- -## The DOM elements +## Connecting JavaScript to Your HTML Elements -The first step is to create references to the elements you want to manipulate in the DOM. In this case, these are the 14 plants currently located in the sidebars. +Before we can make elements draggable, JavaScript needs to locate them in the DOM. Think of this like a library cataloging system - once you have the catalog number, you can find exactly the book you need and access all its contents. -### Task +We'll use the `document.getElementById()` method to make these connections. It's like having a precise filing system - you provide an ID, and it locates exactly the element you need in your HTML. -```html +### Enabling Drag Functionality for All Plants + +Add this code to your `script.js` file: + +```javascript +// Enable drag functionality for all 14 plants dragElement(document.getElementById('plant1')); dragElement(document.getElementById('plant2')); dragElement(document.getElementById('plant3')); @@ -73,157 +207,549 @@ dragElement(document.getElementById('plant13')); dragElement(document.getElementById('plant14')); ``` -What’s happening here? You’re referencing the document and searching its DOM for an element with a specific Id. Recall from the first HTML lesson that you assigned unique Ids to each plant image (`id="plant1"`). Now, you’ll use those Ids. After identifying each element, you pass it to a function called `dragElement`, which you’ll build shortly. This makes the HTML element draggable—or it will soon. +**Here's what this code accomplishes:** +- **Locates** each plant element in the DOM using its unique ID +- **Retrieves** a JavaScript reference to each HTML element +- **Passes** each element to a `dragElement` function (which we'll create next) +- **Prepares** every plant for drag-and-drop interaction +- **Connects** your HTML structure to JavaScript functionality -✅ Why do we reference elements by Id instead of their CSS class? Refer back to the CSS lesson for the answer. +> 🎯 **Why Use IDs Instead of Classes?** IDs provide unique identifiers for specific elements, while CSS classes are designed for styling groups of elements. When JavaScript needs to manipulate individual elements, IDs offer the precision and performance we need. + +> 💡 **Pro Tip**: Notice how we're calling `dragElement()` for each plant individually. This approach ensures that each plant gets its own independent dragging behavior, which is essential for smooth user interaction. + +### 🔄 **Pedagogical Check-in** +**DOM Connection Understanding**: Before moving to drag functionality, verify you can: +- ✅ Explain how `document.getElementById()` locates HTML elements +- ✅ Understand why we use unique IDs for each plant +- ✅ Describe the purpose of the `defer` attribute in script tags +- ✅ Recognize how JavaScript and HTML connect through the DOM + +**Quick Self-Test**: What would happen if two elements had the same ID? Why does `getElementById()` return only one element? +*Answer: IDs should be unique; if duplicated, only the first element is returned* --- -## The Closure +## Building the Drag Element Closure + +Now we'll create the heart of our dragging functionality: a closure that manages the dragging behavior for each plant. This closure will contain multiple inner functions that work together to track mouse movements and update element positions. -Now it’s time to create the `dragElement` closure, which is an outer function that wraps around inner functions (in this case, three). +Closures are perfect for this task because they allow us to create "private" variables that persist between function calls, giving each plant its own independent coordinate tracking system. -Closures are useful when one or more functions need access to the outer function's scope. Here’s an example: +### Understanding Closures with a Simple Example + +Let me demonstrate closures with a simple example that illustrates the concept: ```javascript -function displayCandy(){ - let candy = ['jellybeans']; - function addCandy(candyType) { - candy.push(candyType) - } - addCandy('gumdrops'); +function createCounter() { + let count = 0; // This is like a private variable + + function increment() { + count++; // The inner function remembers the outer variable + return count; + } + + return increment; // We're giving back the inner function } -displayCandy(); -console.log(candy) -``` -In this example, the `displayCandy` function wraps around a function that adds a new candy type to an array already defined in the outer function. If you run this code, the `candy` array will be undefined because it’s a local variable (local to the closure). - -✅ How can you make the `candy` array accessible? Try moving it outside the closure. This way, the array becomes global instead of being limited to the closure’s local scope. +const myCounter = createCounter(); +console.log(myCounter()); // 1 +console.log(myCounter()); // 2 +``` -### Task +**Here's what's happening in this closure pattern:** +- **Creates** a private `count` variable that only exists within this closure +- **The inner function** can access and modify that outer variable (the closure mechanism) +- **When we return** the inner function, it maintains its connection to that private data +- **Even after** `createCounter()` finishes execution, `count` persists and remembers its value + +### Why Closures Are Perfect for Drag Functionality + +For our terrarium, each plant needs to remember its current position coordinates. Closures provide the perfect solution: + +**Key benefits for our project:** +- **Maintains** private position variables for each plant independently +- **Preserves** coordinate data between drag events +- **Prevents** variable conflicts between different draggable elements +- **Creates** clean, organized code structure + +> 🎯 **Learning Goal**: You don't need to master every aspect of closures right now. Focus on seeing how they help us organize code and maintain state for our dragging functionality. + +```mermaid +stateDiagram-v2 + [*] --> Ready: Page loads + Ready --> DragStart: User presses down (pointerdown) + DragStart --> Dragging: Mouse/finger moves (pointermove) + Dragging --> Dragging: Continue moving + Dragging --> DragEnd: User releases (pointerup) + DragEnd --> Ready: Reset for next drag + + state DragStart { + [*] --> CapturePosition + CapturePosition --> SetupListeners + SetupListeners --> [*] + } + + state Dragging { + [*] --> CalculateMovement + CalculateMovement --> UpdatePosition + UpdatePosition --> [*] + } + + state DragEnd { + [*] --> RemoveListeners + RemoveListeners --> CleanupState + CleanupState --> [*] + } +``` +### Creating the dragElement Function -Under the element declarations in `script.js`, create a function: +Now let's build the main function that will handle all the dragging logic. Add this function below your plant element declarations: ```javascript function dragElement(terrariumElement) { - //set 4 positions for positioning on the screen - let pos1 = 0, - pos2 = 0, - pos3 = 0, - pos4 = 0; - terrariumElement.onpointerdown = pointerDrag; + // Initialize position tracking variables + let pos1 = 0, // Previous mouse X position + pos2 = 0, // Previous mouse Y position + pos3 = 0, // Current mouse X position + pos4 = 0; // Current mouse Y position + + // Set up the initial drag event listener + terrariumElement.onpointerdown = pointerDrag; } ``` -`dragElement` receives its `terrariumElement` object from the declarations at the top of the script. Then, you set some local positions to `0` for the object passed into the function. These local variables will be used to track each element’s position as you add drag-and-drop functionality within the closure. The terrarium will be populated with these draggable elements, so the app needs to keep track of their placement. - -Additionally, the `terrariumElement` passed to this function is assigned a `pointerdown` event, which is part of the [web APIs](https://developer.mozilla.org/docs/Web/API) designed for DOM manipulation. `onpointerdown` triggers when a button is pressed or, in this case, when a draggable element is touched. This event handler works on both [web and mobile browsers](https://caniuse.com/?search=onpointerdown), with a few exceptions. - -✅ The [event handler `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) has broader browser support. Why wouldn’t you use it here? Consider the specific type of interaction you’re trying to create. +**Understanding the position tracking system:** +- **`pos1` and `pos2`**: Store the difference between old and new mouse positions +- **`pos3` and `pos4`**: Track the current mouse coordinates +- **`terrariumElement`**: The specific plant element we're making draggable +- **`onpointerdown`**: The event that triggers when the user starts dragging + +**Here's how the closure pattern works:** +- **Creates** private position variables for each plant element +- **Maintains** these variables throughout the dragging lifecycle +- **Ensures** each plant tracks its own coordinates independently +- **Provides** a clean interface through the `dragElement` function + +### Why Use Pointer Events? + +You might wonder why we use `onpointerdown` instead of the more familiar `onclick`. Here's the reasoning: + +| Event Type | Best For | The Catch | +|------------|----------|-------------| +| `onclick` | Simple button clicks | Can't handle dragging (just clicks and releases) | +| `onpointerdown` | Both mouse and touch | Newer, but well-supported these days | +| `onmousedown` | Desktop mouse only | Leaves mobile users out in the cold | + +**Why pointer events are perfect for what we're building:** +- **Works great** whether someone's using a mouse, finger, or even a stylus +- **Feels the same** on a laptop, tablet, or phone +- **Handles** the actual dragging motion (not just click-and-done) +- **Creates** a smooth experience that users expect from modern web apps + +> 💡 **Future-Proofing**: Pointer events are the modern way to handle user interactions. Instead of writing separate code for mouse and touch, you get both for free. Pretty neat, right? + +### 🔄 **Pedagogical Check-in** +**Event Handling Understanding**: Pause to confirm your grasp of events: +- ✅ Why do we use pointer events instead of mouse events? +- ✅ How do closure variables persist between function calls? +- ✅ What role does `preventDefault()` play in smooth dragging? +- ✅ Why do we attach listeners to the document instead of individual elements? + +**Real-World Connection**: Think about drag-and-drop interfaces you use daily: +- **File uploads**: Dragging files into a browser window +- **Kanban boards**: Moving tasks between columns +- **Image galleries**: Rearranging photo order +- **Mobile interfaces**: Swiping and dragging on touchscreens --- -## The Pointerdrag function +## The pointerDrag Function: Capturing the Start of a Drag -The `terrariumElement` is now ready to be dragged. When the `onpointerdown` event is triggered, the `pointerDrag` function is called. Add this function right below the line: `terrariumElement.onpointerdown = pointerDrag;`: +When a user presses down on a plant (whether with a mouse click or finger touch), the `pointerDrag` function springs into action. This function captures the initial coordinates and sets up the dragging system. -### Task +Add this function inside your `dragElement` closure, right after the line `terrariumElement.onpointerdown = pointerDrag;`: ```javascript function pointerDrag(e) { - e.preventDefault(); - console.log(e); - pos3 = e.clientX; - pos4 = e.clientY; + // Prevent default browser behavior (like text selection) + e.preventDefault(); + + // Capture the initial mouse/touch position + pos3 = e.clientX; // X coordinate where drag started + pos4 = e.clientY; // Y coordinate where drag started + + // Set up event listeners for the dragging process + document.onpointermove = elementDrag; + document.onpointerup = stopElementDrag; } ``` -Several things happen here. First, you prevent the default events that typically occur on pointerdown by using `e.preventDefault();`. This gives you more control over the interface’s behavior. +**Step by step, here's what's happening:** +- **Prevents** default browser behaviors that could interfere with dragging +- **Records** the exact coordinates where the user started the drag gesture +- **Establishes** event listeners for the ongoing drag movement +- **Prepares** the system to track mouse/finger movement across the entire document -> After completing the script file, revisit this line and try removing `e.preventDefault()`—what changes? +### Understanding Event Prevention -Next, open `index.html` in a browser and inspect the interface. When you click a plant, you’ll see how the 'e' event is captured. Explore the event to see the wealth of information gathered from a single pointerdown event! +The `e.preventDefault()` line is crucial for smooth dragging: -Then, note how the local variables `pos3` and `pos4` are set to `e.clientX`. You can find the `e` values in the inspection pane. These values capture the x and y coordinates of the plant at the moment you click or touch it. You’ll need precise control over the plants’ behavior as you drag them, so you track their coordinates. +**Without prevention, browsers might:** +- **Select** text when dragging across the page +- **Trigger** context menus on right-click drag +- **Interfere** with our custom dragging behavior +- **Create** visual artifacts during the drag operation -✅ Is it becoming clearer why this app is built with one large closure? Without it, how would you maintain scope for each of the 14 draggable plants? +> 🔍 **Experiment**: After completing this lesson, try removing `e.preventDefault()` and see how it affects the dragging experience. You'll quickly understand why this line is essential! -Complete the initial function by adding two more pointer event manipulations under `pos4 = e.clientY`: +### Coordinate Tracking System -```html +The `e.clientX` and `e.clientY` properties give us precise mouse/touch coordinates: + +| Property | What It Measures | Use Case | +|----------|------------------|----------| +| `clientX` | Horizontal position relative to the viewport | Tracking left-right movement | +| `clientY` | Vertical position relative to the viewport | Tracking up-down movement | + +**Understanding these coordinates:** +- **Provides** pixel-perfect positioning information +- **Updates** in real-time as the user moves their pointer +- **Remains** consistent across different screen sizes and zoom levels +- **Enables** smooth, responsive drag interactions + +### Setting Up Document-Level Event Listeners + +Notice how we attach the move and stop events to the entire `document`, not just the plant element: + +```javascript document.onpointermove = elementDrag; document.onpointerup = stopElementDrag; ``` -Here, you specify that the plant should move with the pointer as you drag it and stop moving when you release it. `onpointermove` and `onpointerup` are part of the same API as `onpointerdown`. The interface will throw errors now because the `elementDrag` and `stopElementDrag` functions haven’t been defined yet, so let’s build those next. +**Why attach to the document:** +- **Continues** tracking even when the mouse leaves the plant element +- **Prevents** drag interruption if the user moves quickly +- **Provides** smooth dragging across the entire screen +- **Handles** edge cases where the cursor moves outside the browser window ---- +> ⚡ **Performance Note**: We'll clean up these document-level listeners when dragging stops to avoid memory leaks and performance issues. -## The elementDrag and stopElementDrag functions +## Completing the Drag System: Movement and Cleanup -Complete the closure by adding two more internal functions to handle what happens when you drag a plant and when you stop dragging it. The goal is to allow you to drag any plant at any time and place it anywhere on the screen. This interface is intentionally flexible (there’s no drop zone, for example) so you can design your terrarium however you like by adding, removing, and repositioning plants. +Now we'll add the two remaining functions that handle the actual dragging movement and the cleanup when dragging stops. These functions work together to create smooth, responsive plant movement across your terrarium. -### Task +### The elementDrag Function: Tracking Movement Add the `elementDrag` function right after the closing curly bracket of `pointerDrag`: ```javascript function elementDrag(e) { - pos1 = pos3 - e.clientX; - pos2 = pos4 - e.clientY; - pos3 = e.clientX; - pos4 = e.clientY; - console.log(pos1, pos2, pos3, pos4); - terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px'; - terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px'; + // Calculate the distance moved since the last event + pos1 = pos3 - e.clientX; // Horizontal distance moved + pos2 = pos4 - e.clientY; // Vertical distance moved + + // Update the current position tracking + pos3 = e.clientX; // New current X position + pos4 = e.clientY; // New current Y position + + // Apply the movement to the element's position + terrariumElement.style.top = (terrariumElement.offsetTop - pos2) + 'px'; + terrariumElement.style.left = (terrariumElement.offsetLeft - pos1) + 'px'; } ``` -In this function, you make several adjustments to the initial positions (`pos1`–`pos4`) set as local variables in the outer function. What’s happening here? - -As you drag, you update `pos1` by setting it equal to `pos3` (previously set as `e.clientX`) minus the current `e.clientX` value. You do something similar for `pos2`. Then, you update `pos3` and `pos4` to the new x and y coordinates of the element. You can observe these changes in the console as you drag. Finally, you modify the plant’s CSS style to set its new position based on the updated values of `pos1` and `pos2`, calculating the plant’s top and left coordinates relative to its offset. - -> `offsetTop` and `offsetLeft` are CSS properties that position an element relative to its parent, as long as the parent isn’t positioned as `static`. - -This recalculation ensures precise control over the terrarium and its plants. - -### Task +**Understanding the coordinate mathematics:** +- **`pos1` and `pos2`**: Calculate how far the mouse has moved since the last update +- **`pos3` and `pos4`**: Store the current mouse position for the next calculation +- **`offsetTop` and `offsetLeft`**: Get the element's current position on the page +- **Subtraction logic**: Moves the element by the same amount the mouse moved + +```mermaid +sequenceDiagram + participant User + participant Mouse + participant JavaScript + participant Plant + + User->>Mouse: Start drag at (100, 50) + Mouse->>JavaScript: pointerdown event + JavaScript->>JavaScript: Store initial position (pos3=100, pos4=50) + JavaScript->>JavaScript: Setup move/up listeners + + User->>Mouse: Move to (110, 60) + Mouse->>JavaScript: pointermove event + JavaScript->>JavaScript: Calculate: pos1=10, pos2=10 + JavaScript->>Plant: Update: left += 10px, top += 10px + Plant->>Plant: Render at new position + + User->>Mouse: Release at (120, 65) + Mouse->>JavaScript: pointerup event + JavaScript->>JavaScript: Remove listeners + JavaScript->>JavaScript: Reset for next drag +``` +**Here's the movement calculation breakdown:** +1. **Measures** the difference between old and new mouse positions +2. **Calculates** how much to move the element based on mouse movement +3. **Updates** the element's CSS position properties in real-time +4. **Stores** the new position as the baseline for the next movement calculation + +### Visual Representation of the Math + +```mermaid +sequenceDiagram + participant Mouse + participant JavaScript + participant Plant + + Mouse->>JavaScript: Move from (100,50) to (110,60) + JavaScript->>JavaScript: Calculate: moved 10px right, 10px down + JavaScript->>Plant: Update position by +10px right, +10px down + Plant->>Plant: Render at new position +``` +### The stopElementDrag Function: Cleaning Up -Finally, add the `stopElementDrag` function after the closing curly bracket of `elementDrag`: +Add the cleanup function after the closing curly bracket of `elementDrag`: ```javascript function stopElementDrag() { - document.onpointerup = null; - document.onpointermove = null; + // Remove the document-level event listeners + document.onpointerup = null; + document.onpointermove = null; } ``` -This small function resets the `onpointerup` and `onpointermove` events, allowing you to either restart dragging the same plant or begin dragging a new one. +**Why cleanup is essential:** +- **Prevents** memory leaks from lingering event listeners +- **Stops** the dragging behavior when the user releases the plant +- **Allows** other elements to be dragged independently +- **Resets** the system for the next drag operation + +**What happens without cleanup:** +- Event listeners continue running even after dragging stops +- Performance degrades as unused listeners accumulate +- Unexpected behavior when interacting with other elements +- Browser resources are wasted on unnecessary event handling + +### Understanding CSS Position Properties + +Our dragging system manipulates two key CSS properties: + +| Property | What It Controls | How We Use It | +|----------|------------------|---------------| +| `top` | Distance from the top edge | Vertical positioning during drag | +| `left` | Distance from the left edge | Horizontal positioning during drag | + +**Key insights about offset properties:** +- **`offsetTop`**: Current distance from the top of the positioned parent element +- **`offsetLeft`**: Current distance from the left of the positioned parent element +- **Positioning context**: These values are relative to the nearest positioned ancestor +- **Real-time updates**: Changes immediately when we modify the CSS properties + +> 🎯 **Design Philosophy**: This drag system is intentionally flexible – there are no "drop zones" or restrictions. Users can place plants anywhere, giving them complete creative control over their terrarium design. -✅ What happens if you don’t set these events to null? +## Bringing It All Together: Your Complete Drag System -Now your project is complete! +Congratulations! You've just built a sophisticated drag-and-drop system using vanilla JavaScript. Your complete `dragElement` function now contains a powerful closure that manages: -🥇Congratulations! You’ve finished your beautiful terrarium! ![finished terrarium](../../../../translated_images/en/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.png) +**What your closure accomplishes:** +- **Maintains** private position variables for each plant independently +- **Handles** the complete drag lifecycle from start to finish +- **Provides** smooth, responsive movement across the entire screen +- **Cleans** up resources properly to prevent memory leaks +- **Creates** an intuitive, creative interface for terrarium design + +### Testing Your Interactive Terrarium + +Now test your interactive terrarium! Open your `index.html` file in a web browser and try the functionality: + +1. **Click and hold** any plant to start dragging +2. **Move your mouse or finger** and watch the plant follow smoothly +3. **Release** to drop the plant in its new position +4. **Experiment** with different arrangements to explore the interface + +🥇 **Achievement**: You've created a fully interactive web application using core concepts that professional developers use daily. That drag-and-drop functionality uses the same principles behind file uploads, kanban boards, and many other interactive interfaces. + +### 🔄 **Pedagogical Check-in** +**Complete System Understanding**: Verify your mastery of the full drag system: +- ✅ How do closures maintain independent state for each plant? +- ✅ Why is the coordinate calculation math necessary for smooth movement? +- ✅ What would happen if we forgot to clean up event listeners? +- ✅ How does this pattern scale to more complex interactions? + +**Code Quality Reflection**: Review your complete solution: +- **Modular design**: Each plant gets its own closure instance +- **Event efficiency**: Proper setup and cleanup of listeners +- **Cross-device support**: Works on desktop and mobile +- **Performance conscious**: No memory leaks or redundant calculations + +![finished terrarium](../../../../translated_images/en/terrarium-final.0920f16e87c13a84.webp) --- -## 🚀Challenge +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: -Add a new event handler to your closure to add more functionality to the plants—for example, double-clicking a plant to bring it to the front. Get creative! +**Description:** Enhance the terrarium project by adding a reset functionality that returns all plants to their original positions with smooth animations. + +**Prompt:** Create a reset button that, when clicked, animates all plants back to their original sidebar positions using CSS transitions. The function should store the original positions when the page loads and smoothly transition plants back to those positions over 1 second when the reset button is pressed. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + +## 🚀 Additional Challenge: Expand Your Skills + +Ready to take your terrarium to the next level? Try implementing these enhancements: + +**Creative Extensions:** +- **Double-click** a plant to bring it to the front (z-index manipulation) +- **Add visual feedback** like a subtle glow when hovering over plants +- **Implement boundaries** to prevent plants from being dragged outside the terrarium +- **Create a save function** that remembers plant positions using localStorage +- **Add sound effects** for picking up and placing plants + +> 💡 **Learning Opportunity**: Each of these challenges will teach you new aspects of DOM manipulation, event handling, and user experience design. ## Post-Lecture Quiz [Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/20) -## Review & Self Study +## Review & Self Study: Deepening Your Understanding + +You've mastered the fundamentals of DOM manipulation and closures, but there's always more to explore! Here are some pathways to expand your knowledge and skills. + +### Alternative Drag and Drop Approaches + +We used pointer events for maximum flexibility, but web development offers multiple approaches: + +| Approach | Best For | Learning Value | +|----------|----------|----------------| +| [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) | File uploads, formal drag zones | Understanding native browser capabilities | +| [Touch Events](https://developer.mozilla.org/docs/Web/API/Touch_events) | Mobile-specific interactions | Mobile-first development patterns | +| CSS `transform` properties | Smooth animations | Performance optimization techniques | + +### Advanced DOM Manipulation Topics + +**Next steps in your learning journey:** +- **Event delegation**: Handling events efficiently for multiple elements +- **Intersection Observer**: Detecting when elements enter/leave the viewport +- **Mutation Observer**: Watching for changes in the DOM structure +- **Web Components**: Creating reusable, encapsulated UI elements +- **Virtual DOM concepts**: Understanding how frameworks optimize DOM updates + +### Essential Resources for Continued Learning + +**Technical Documentation:** +- [MDN Pointer Events Guide](https://developer.mozilla.org/docs/Web/API/Pointer_events) - Comprehensive pointer event reference +- [W3C Pointer Events Specification](https://www.w3.org/TR/pointerevents1/) - Official standards documentation +- [JavaScript Closures Deep Dive](https://developer.mozilla.org/docs/Web/JavaScript/Closures) - Advanced closure patterns + +**Browser Compatibility:** +- [CanIUse.com](https://caniuse.com/) - Check feature support across browsers +- [MDN Browser Compatibility Data](https://github.com/mdn/browser-compat-data) - Detailed compatibility information + +**Practice Opportunities:** +- **Build** a puzzle game using similar drag mechanics +- **Create** a kanban board with drag-and-drop task management +- **Design** an image gallery with draggable photo arrangements +- **Experiment** with touch gestures for mobile interfaces + +> 🎯 **Learning Strategy**: The best way to solidify these concepts is through practice. Try building variations of draggable interfaces – each project will teach you something new about user interaction and DOM manipulation. + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open browser DevTools and type `document.querySelector('body')` in the console +- [ ] Try changing a webpage's text using `innerHTML` or `textContent` +- [ ] Add a click event listener to any button or link on a webpage +- [ ] Inspect the DOM tree structure using the Elements panel + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and review DOM manipulation concepts +- [ ] Create an interactive webpage that responds to user clicks +- [ ] Practice event handling with different event types (click, mouseover, keypress) +- [ ] Build a simple to-do list or counter using DOM manipulation +- [ ] Explore the relationship between HTML elements and JavaScript objects + +### 📅 **Your Week-Long JavaScript Journey** +- [ ] Complete the interactive terrarium project with drag-and-drop functionality +- [ ] Master event delegation for efficient event handling +- [ ] Learn about the event loop and asynchronous JavaScript +- [ ] Practice closures by building modules with private state +- [ ] Explore modern DOM APIs like Intersection Observer +- [ ] Build interactive components without using frameworks + +### 🌟 **Your Month-Long JavaScript Mastery** +- [ ] Create a complex single-page application using vanilla JavaScript +- [ ] Learn a modern framework (React, Vue, or Angular) and compare it to vanilla DOM +- [ ] Contribute to open source JavaScript projects +- [ ] Master advanced concepts like web components and custom elements +- [ ] Build performant web applications with optimal DOM patterns +- [ ] Teach others about DOM manipulation and JavaScript fundamentals + +## 🎯 Your JavaScript DOM Mastery Timeline + +```mermaid +timeline + title DOM & JavaScript Learning Progression + + section Foundation (15 minutes) + DOM Understanding: Element selection methods + : Tree structure navigation + : Property access patterns + + section Event Handling (20 minutes) + User Interaction: Pointer event basics + : Event listener setup + : Cross-device compatibility + : Event prevention techniques + + section Closures (25 minutes) + Scope Management: Private variable creation + : Function persistence + : State management patterns + : Memory efficiency + + section Drag System (30 minutes) + Interactive Features: Coordinate tracking + : Position calculation + : Movement mathematics + : Cleanup procedures + + section Advanced Patterns (45 minutes) + Professional Skills: Event delegation + : Performance optimization + : Error handling + : Accessibility considerations + + section Framework Understanding (1 week) + Modern Development: Virtual DOM concepts + : State management libraries + : Component architectures + : Build tool integration + + section Expert Level (1 month) + Advanced DOM APIs: Intersection Observer + : Mutation Observer + : Custom Elements + : Web Components +``` +### 🛠️ Your JavaScript Toolkit Summary -While dragging elements around the screen may seem simple, there are many ways to achieve this and many potential challenges, depending on the desired effect. In fact, there’s an entire [drag-and-drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) you can explore. We didn’t use it in this module because we wanted a slightly different effect, but try it out in your own project to see what you can create. +After completing this lesson, you now have: +- **DOM Mastery**: Element selection, property manipulation, and tree navigation +- **Event Expertise**: Cross-device interaction handling with pointer events +- **Closure Understanding**: Private state management and function persistence +- **Interactive Systems**: Complete drag-and-drop implementation from scratch +- **Performance Awareness**: Proper event cleanup and memory management +- **Modern Patterns**: Code organization techniques used in professional development +- **User Experience**: Creating intuitive, responsive interfaces -Learn more about pointer events in the [W3C docs](https://www.w3.org/TR/pointerevents1/) and on [MDN web docs](https://developer.mozilla.org/docs/Web/API/Pointer_events). +**Professional Skills Gained**: You've built features using the same techniques as: +- **Trello/Kanban boards**: Card dragging between columns +- **File upload systems**: Drag-and-drop file handling +- **Image galleries**: Photo arrangement interfaces +- **Mobile apps**: Touch-based interaction patterns -Always check browser compatibility using [CanIUse.com](https://caniuse.com/). +**Next Level**: You're ready to explore modern frameworks like React, Vue, or Angular that build upon these fundamental DOM manipulation concepts! ## Assignment @@ -231,5 +757,7 @@ Always check browser compatibility using [CanIUse.com](https://caniuse.com/). --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/3-terrarium/3-intro-to-DOM-and-closures/assignment.md b/translations/en/3-terrarium/3-intro-to-DOM-and-closures/assignment.md index 0db47b8a0..d3c4879c6 100644 --- a/translations/en/3-terrarium/3-intro-to-DOM-and-closures/assignment.md +++ b/translations/en/3-terrarium/3-intro-to-DOM-and-closures/assignment.md @@ -1,25 +1,130 @@ - -# Work a bit more with the DOM +# DOM Element Investigation Assignment + +## Overview + +Now that you've experienced the power of DOM manipulation firsthand, it's time to explore the broader world of DOM interfaces. This assignment will deepen your understanding of how different web technologies interact with the DOM beyond just dragging elements. + +## Learning Objectives + +By completing this assignment, you will: +- **Research** and understand a specific DOM interface in depth +- **Analyze** real-world implementations of DOM manipulation +- **Connect** theoretical concepts to practical applications +- **Develop** skills in technical documentation and analysis ## Instructions -Explore the DOM further by 'adopting' a DOM element. Visit the MDN's [list of DOM interfaces](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) and choose one. Find an example of it being used on a website, and write an explanation of how it is utilized. +### Step 1: Choose Your DOM Interface + +Visit MDN's comprehensive [list of DOM interfaces](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) and select one interface that interests you. Consider choosing from these categories for variety: + +**Beginner-Friendly Options:** +- `Element.classList` - Managing CSS classes dynamically +- `Document.querySelector()` - Advanced element selection +- `Element.addEventListener()` - Event handling beyond pointer events +- `Window.localStorage` - Client-side data storage + +**Intermediate Challenges:** +- `Intersection Observer API` - Detecting element visibility +- `MutationObserver` - Watching DOM changes +- `Drag and Drop API` - Alternative to our pointer-based approach +- `Geolocation API` - Accessing user location + +**Advanced Exploration:** +- `Web Components` - Custom elements and shadow DOM +- `Canvas API` - Programmatic graphics +- `Web Workers` - Background processing +- `Service Workers` - Offline functionality + +### Step 2: Research and Document + +Create a comprehensive analysis (300-500 words) that includes: + +#### Technical Overview +- **Define** what your chosen interface does in clear, beginner-friendly language +- **Explain** the key methods, properties, or events it provides +- **Describe** the types of problems it's designed to solve + +#### Real-World Implementation +- **Find** a website that uses your chosen interface (inspect the code or research examples) +- **Document** the specific implementation with code snippets if possible +- **Analyze** why the developers chose this approach +- **Explain** how it enhances the user experience + +#### Practical Application +- **Compare** your interface to the techniques we used in the terrarium project +- **Suggest** how your interface could enhance or extend the terrarium functionality +- **Identify** other projects where this interface would be valuable + +### Step 3: Code Example + +Include a simple, working code example that demonstrates your interface in action. This should be: +- **Functional** - The code should actually work when tested +- **Commented** - Explain what each part does +- **Relevant** - Connected to a realistic use case +- **Beginner-friendly** - Understandable to someone learning web development + +## Submission Format + +Structure your submission with clear headings: + +```markdown +# [Interface Name] DOM Investigation + +## What It Does +[Technical overview] + +## Real-World Example +[Website analysis and implementation details] + +## Code Demonstration +[Your working example with comments] + +## Reflection +[How this connects to our terrarium project and future applications] +``` + +## Assessment Rubric + +| Criteria | Exemplary (A) | Proficient (B) | Developing (C) | Needs Improvement (D) | +|----------|---------------|----------------|----------------|----------------------| +| **Technical Understanding** | Demonstrates deep understanding with accurate explanations and proper terminology | Shows solid understanding with mostly accurate explanations | Basic understanding with some misconceptions | Limited understanding with significant errors | +| **Real-World Analysis** | Identifies and thoroughly analyzes actual implementation with specific examples | Finds real example with adequate analysis | Locates example but analysis lacks depth | Vague or inaccurate real-world connection | +| **Code Example** | Working, well-commented code that clearly demonstrates the interface | Functional code with adequate comments | Code works but needs better documentation | Code has errors or poor explanation | +| **Writing Quality** | Clear, engaging writing with proper structure and technical communication | Well-organized with good technical writing | Adequate organization and clarity | Poor organization or unclear communication | +| **Critical Thinking** | Makes insightful connections between concepts and suggests innovative applications | Shows good analytical thinking and relevant connections | Some analysis present but could be deeper | Limited evidence of critical thinking | + +## Tips for Success + +**Research Strategies:** +- **Start** with MDN documentation for authoritative information +- **Look** for code examples on GitHub or CodePen +- **Check** popular websites using browser developer tools +- **Watch** tutorial videos for visual explanations + +**Writing Guidelines:** +- **Use** your own words rather than copying documentation +- **Include** specific examples and code snippets +- **Explain** technical concepts as if teaching a friend +- **Connect** your interface to broader web development concepts + +**Code Example Ideas:** +- **Create** a simple demo that showcases the interface's main features +- **Build** on concepts from our terrarium project where relevant +- **Focus** on functionality over visual design +- **Test** your code to ensure it works correctly + +## Submission Deadline + +[Insert deadline here] -## Rubric +## Questions? -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | --------------------------------------------- | ------------------------------------------------ | ----------------------- | -| | Paragraph explanation is provided, with example | Paragraph explanation is provided, without example | No explanation is provided | +If you need clarification on any aspect of this assignment, don't hesitate to ask! This investigation will deepen your understanding of how the DOM enables the interactive web experiences we use every day. --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the definitive source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/3-terrarium/README.md b/translations/en/3-terrarium/README.md index e51f936a7..92e3fb9f0 100644 --- a/translations/en/3-terrarium/README.md +++ b/translations/en/3-terrarium/README.md @@ -1,45 +1,21 @@ - -# My Terrarium: A project to learn about HTML, CSS, and DOM manipulation using JavaScript 🌵🌱 - -A small drag-and-drop coding exercise. With a bit of HTML, JS, and CSS, you’ll be able to create a web interface, style it, and even add various interactions of your choice. - -![my terrarium](../../../translated_images/en/screenshot_gray.0c796099a1f9f25e40aa55ead81f268434c00af30d7092490759945eda63067d.png) - -# Lessons - -1. [Introduction to HTML](./1-intro-to-html/README.md) -2. [Introduction to CSS](./2-intro-to-css/README.md) -3. [Introduction to DOM and JS Closures](./3-intro-to-DOM-and-closures/README.md) - -## Credits - -Written with ♥️ by [Jen Looper](https://www.twitter.com/jenlooper) - -The CSS-based terrarium design was inspired by Jakub Mandra's glass jar [codepen](https://codepen.io/Rotarepmi/pen/rjpNZY). - -The artwork was hand-drawn by [Jen Looper](http://jenlooper.com) using Procreate. - ## Deploy your Terrarium -You can deploy or publish your terrarium on the web using Azure Static Web Apps. +You can deploy, or publish your Terrarium on the web using **Azure Static Web Apps**. -1. Fork this repository. +1. Fork this repo -2. Click this button: +2. Press this button 👇 -[![Deploy to Azure button](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/?feature.customportal=false&WT.mc_id=academic-77807-sagibbon#create/Microsoft.StaticApp) +[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.StaticApp) -3. Follow the wizard to create your app. Make sure to set the app root to either `/solution` or the root of your codebase. This app doesn’t include an API, so you don’t need to add one. A GitHub folder will be created in your forked repository, which will help Azure Static Web Apps' build services to build and publish your app to a new URL. +3. Follow the setup wizard to create your app. + - Set the **App root** to either `/solution` or the root of your codebase. + - There’s no API in this app, so you can skip the API configuration. + - A `.github` folder will be created automatically to help Azure Static Web Apps build and publish your app. --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/3-terrarium/solution/README.md b/translations/en/3-terrarium/solution/README.md index 0c28bb0e1..9da08ad98 100644 --- a/translations/en/3-terrarium/solution/README.md +++ b/translations/en/3-terrarium/solution/README.md @@ -1,17 +1,8 @@ - # My Terrarium: A project to learn about HTML, CSS, and DOM manipulation using JavaScript 🌵🌱 A small drag-and-drop coding exercise. With a bit of HTML, JS, and CSS, you can create a web interface, style it, and add interactivity. -![my terrarium](../../../../translated_images/en/screenshot_gray.0c796099a1f9f25e40aa55ead81f268434c00af30d7092490759945eda63067d.png) +![my terrarium](../../../../translated_images/en/screenshot_gray.0c796099a1f9f25e.webp) ## Credits diff --git a/translations/en/4-typing-game/README.md b/translations/en/4-typing-game/README.md index 9d877d08d..9d7f50cae 100644 --- a/translations/en/4-typing-game/README.md +++ b/translations/en/4-typing-game/README.md @@ -1,38 +1,273 @@ - # Event-Driven Programming - Build a Typing Game +```mermaid +journey + title Your Typing Game Development Journey + section Foundation + Plan game structure: 3: Student + Design user interface: 4: Student + Setup HTML elements: 4: Student + section Functionality + Handle user input: 4: Student + Track timing: 5: Student + Calculate accuracy: 5: Student + section Features + Add visual feedback: 5: Student + Implement game logic: 5: Student + Polish experience: 5: Student +``` ## Introduction -Typing is one of the most overlooked skills for developers. Being able to quickly translate your thoughts into code allows your creativity to flow seamlessly. And what better way to practice than by playing a game? +Here's something every developer knows but rarely talks about: typing fast is a superpower! 🚀 Think about it - the faster you can get your ideas from your brain to your code editor, the more your creativity can flow. It's like having a direct pipeline between your thoughts and the screen. -> Let's build a typing game! +```mermaid +pie title Game Features + "Real-time Feedback" : 25 + "Performance Tracking" : 20 + "Interactive UI" : 20 + "Timer System" : 15 + "Quote Management" : 10 + "Results Display" : 10 +``` +Want to know one of the best ways to level up this skill? You guessed it - we're going to build a game! -You'll use the JavaScript, HTML, and CSS skills you've learned so far to create a typing game. The game will display a random quote (we're using [Sherlock Holmes](https://en.wikipedia.org/wiki/Sherlock_Holmes) quotes) and measure how long it takes the player to type it accurately. You'll use the JavaScript, HTML, and CSS skills you've learned so far to create this game. +```mermaid +flowchart LR + A[Player starts game] --> B[Random quote displayed] + B --> C[Player types characters] + C --> D{Character correct?} + D -->|Yes| E[Green highlight] + D -->|No| F[Red highlight] + E --> G[Update accuracy] + F --> G + G --> H{Quote complete?} + H -->|No| C + H -->|Yes| I[Calculate WPM] + I --> J[Display results] + J --> K[Play again?] + K -->|Yes| B + K -->|No| L[Game over] + + style A fill:#e1f5fe + style D fill:#fff3e0 + style E fill:#e8f5e8 + style F fill:#ffebee + style I fill:#f3e5f5 +``` +> Let's create an awesome typing game together! +Ready to put all those JavaScript, HTML, and CSS skills you've been learning to work? We're going to build a typing game that'll challenge you with random quotes from the legendary detective [Sherlock Holmes](https://en.wikipedia.org/wiki/Sherlock_Holmes). The game will track how fast and accurately you can type - and trust me, it's more addictive than you might think! + +```mermaid +mindmap + root((Typing Game Development)) + User Interface + Input Elements + Visual Feedback + Responsive Design + Accessibility + Game Logic + Quote Selection + Timer Management + Accuracy Tracking + Score Calculation + Event Handling + Keyboard Input + Button Clicks + Real-time Updates + Game State Changes + Performance Metrics + Words Per Minute + Character Accuracy + Error Tracking + Progress Display + User Experience + Immediate Feedback + Clear Instructions + Engaging Content + Achievement System +``` ![demo](../../../4-typing-game/images/demo.gif) -## Prerequisites +## What You'll Need to Know -This lesson assumes you're familiar with the following concepts: +```mermaid +flowchart TD + A[User Action] --> B{Event Type?} + B -->|Key Press| C[Keyboard Event] + B -->|Button Click| D[Mouse Event] + B -->|Timer| E[Time Event] + + C --> F[Check Character] + D --> G[Start/Reset Game] + E --> H[Update Timer] + + F --> I{Correct?} + I -->|Yes| J[Highlight Green] + I -->|No| K[Highlight Red] + + J --> L[Update Score] + K --> L + L --> M[Check Game State] + + G --> N[Generate New Quote] + H --> O[Display Time] + + M --> P{Game Complete?} + P -->|Yes| Q[Show Results] + P -->|No| R[Continue Game] + + style A fill:#e1f5fe + style F fill:#e8f5e8 + style I fill:#fff3e0 + style Q fill:#f3e5f5 +``` +Before we dive in, make sure you're comfortable with these concepts (don't worry if you need a quick refresher - we've all been there!): -- Creating text input and button elements -- Using CSS and applying styles with classes +- Creating text input and button controls +- CSS and setting styles using classes - JavaScript basics - - Working with arrays - - Generating random numbers - - Retrieving the current time + - Creating an array + - Creating a random number + - Getting the current time + +If any of these feel a bit rusty, that's totally fine! Sometimes the best way to solidify your knowledge is by jumping into a project and figuring things out as you go. + +### 🔄 **Pedagogical Check-in** +**Foundation Assessment**: Before starting development, ensure you understand: +- ✅ How HTML forms and input elements work +- ✅ CSS classes and dynamic styling +- ✅ JavaScript event listeners and handlers +- ✅ Array manipulation and random selection +- ✅ Time measurement and calculations + +**Quick Self-Test**: Can you explain how these concepts work together in an interactive game? +- **Events** trigger when users interact with elements +- **Handlers** process those events and update game state +- **CSS** provides visual feedback for user actions +- **Timing** enables performance measurement and game progression + +```mermaid +quadrantChart + title Typing Game Skills Development + x-axis Beginner --> Expert + y-axis Static --> Interactive + quadrant-1 Advanced Games + quadrant-2 Real-time Apps + quadrant-3 Basic Pages + quadrant-4 Interactive Sites + + HTML Forms: [0.3, 0.2] + CSS Styling: [0.4, 0.3] + Event Handling: [0.7, 0.8] + Game Logic: [0.8, 0.9] + Performance Tracking: [0.9, 0.7] +``` +## Let's Build This Thing! + +[Creating a typing game by using event driven programming](./typing-game/README.md) + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open your browser console and try listening for keyboard events with `addEventListener` +- [ ] Create a simple HTML page with an input field and test typing detection +- [ ] Practice string manipulation by comparing typed text with target text +- [ ] Experiment with `setTimeout` to understand timing functions + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and understand event-driven programming +- [ ] Build a basic version of the typing game with word validation +- [ ] Add visual feedback for correct and incorrect typing +- [ ] Implement a simple scoring system based on speed and accuracy +- [ ] Style your game with CSS to make it visually appealing + +### 📅 **Your Week-Long Game Development** +- [ ] Complete the full typing game with all features and polish +- [ ] Add difficulty levels with varying word complexity +- [ ] Implement user statistics tracking (WPM, accuracy over time) +- [ ] Create sound effects and animations for better user experience +- [ ] Make your game mobile-responsive for touch devices +- [ ] Share your game online and gather feedback from users + +### 🌟 **Your Month-Long Interactive Development** +- [ ] Build multiple games exploring different interaction patterns +- [ ] Learn about game loops, state management, and performance optimization +- [ ] Contribute to open source game development projects +- [ ] Master advanced timing concepts and smooth animations +- [ ] Create a portfolio showcasing various interactive applications +- [ ] Mentor others interested in game development and user interaction + +## 🎯 Your Typing Game Mastery Timeline + +```mermaid +timeline + title Game Development Learning Progression + + section Setup (10 minutes) + Project Structure: HTML foundation + : CSS styling setup + : JavaScript file creation + + section User Interface (20 minutes) + Interactive Elements: Input fields + : Button controls + : Display areas + : Responsive layout + + section Event Handling (25 minutes) + User Interaction: Keyboard events + : Mouse events + : Real-time feedback + : State management + + section Game Logic (30 minutes) + Core Functionality: Quote generation + : Character comparison + : Accuracy calculation + : Timer implementation + + section Performance Tracking (35 minutes) + Metrics & Analytics: WPM calculation + : Error tracking + : Progress visualization + : Results display + + section Polish & Enhancement (45 minutes) + User Experience: Visual feedback + : Sound effects + : Animations + : Accessibility features + + section Advanced Features (1 week) + Extended Functionality: Difficulty levels + : Leaderboards + : Custom quotes + : Multiplayer options + + section Professional Skills (1 month) + Game Development: Performance optimization + : Code architecture + : Testing strategies + : Deployment patterns +``` +### 🛠️ Your Game Development Toolkit Summary + +After completing this project, you'll have mastered: +- **Event-Driven Programming**: Responsive user interfaces that react to input +- **Real-Time Feedback**: Instant visual and performance updates +- **Performance Measurement**: Accurate timing and scoring systems +- **Game State Management**: Controlling application flow and user experience +- **Interactive Design**: Creating engaging, addictive user experiences +- **Modern Web APIs**: Utilizing browser capabilities for rich interactions +- **Accessibility Patterns**: Inclusive design for all users -## Lesson +**Real-World Applications**: These skills directly apply to: +- **Web Applications**: Any interactive interface or dashboard +- **Educational Software**: Learning platforms and skill assessment tools +- **Productivity Tools**: Text editors, IDEs, and collaboration software +- **Gaming Industry**: Browser games and interactive entertainment +- **Mobile Development**: Touch-based interfaces and gesture handling -[Creating a typing game by using event-driven programming](./typing-game/README.md) +**Next Level**: You're ready to explore advanced game frameworks, real-time multiplayer systems, or complex interactive applications! ## Credits @@ -40,5 +275,7 @@ Written with ♥️ by [Christopher Harrison](http://www.twitter.com/geektrainer --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/4-typing-game/solution/README.md b/translations/en/4-typing-game/solution/README.md index 6c0b26c89..b78db64df 100644 --- a/translations/en/4-typing-game/solution/README.md +++ b/translations/en/4-typing-game/solution/README.md @@ -1,12 +1,3 @@ - This is a placeholder, left blank purposefully --- diff --git a/translations/en/4-typing-game/typing-game/README.md b/translations/en/4-typing-game/typing-game/README.md index 17187baa2..8cc87d363 100644 --- a/translations/en/4-typing-game/typing-game/README.md +++ b/translations/en/4-typing-game/typing-game/README.md @@ -1,56 +1,93 @@ - # Creating a game using events +Have you ever wondered how websites know when you click a button or type in a text box? That's the magic of event-driven programming! What better way to learn this essential skill than by building something useful - a typing speed game that reacts to every keystroke you make. + +You're going to see firsthand how web browsers "talk" to your JavaScript code. Every time you click, type, or move your mouse, the browser is sending little messages (we call them events) to your code, and you get to decide how to respond! + +By the time we're done here, you'll have built a real typing game that tracks your speed and accuracy. More importantly, you'll understand the fundamental concepts that power every interactive website you've ever used. Let's dive in! + ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/21) -## Event-driven programming +## Event driven programming + +Think about your favorite app or website - what makes it feel alive and responsive? It's all about how it reacts to what you do! Every tap, click, swipe, or keystroke creates what we call an "event," and that's where the real magic of web development happens. + +Here's what makes programming for the web so interesting: we never know when someone will click that button or start typing in a text box. They might click immediately, wait five minutes, or maybe never click at all! This unpredictability means we need to think differently about how we write our code. + +Instead of writing code that runs from top to bottom like a recipe, we write code that sits patiently waiting for something to happen. It's similar to how telegraph operators in the 1800s would sit by their machines, ready to respond the moment a message came through the wire. -When building a browser-based application, we provide a graphical user interface (GUI) for users to interact with what we've created. The most common ways users interact with the browser are by clicking and typing in various elements. The challenge for us as developers is that we don't know when they will perform these actions! +So what exactly is an "event"? Simply put, it's something that happens! When you click a button - that's an event. When you type a letter - that's an event. When you move your mouse - that's another event. -[Event-driven programming](https://en.wikipedia.org/wiki/Event-driven_programming) is the type of programming we use to create our GUI. If we break down the term, the key word here is **event**. According to [Merriam-Webster](https://www.merriam-webster.com/dictionary/event), an event is "something which happens." This perfectly describes our situation. We know something will happen that we want to respond to with code, but we don't know when it will occur. +Event-driven programming lets us set up our code to listen and respond. We create special functions called **event listeners** that wait patiently for specific things to happen, then spring into action when they do. -The way we specify the code we want to execute is by creating a function. In [procedural programming](https://en.wikipedia.org/wiki/Procedural_programming), functions are called in a specific order. This is also true in event-driven programming. The difference lies in **how** the functions are called. +Think of event listeners like having a doorbell for your code. You set up the doorbell (`addEventListener()`), tell it what sound to listen for (like a 'click' or 'keypress'), and then specify what should happen when someone rings it (your custom function). -To handle events (like button clicks or typing), we register **event listeners**. An event listener is a function that waits for an event to occur and executes in response. Event listeners can update the UI, make server calls, or perform any other necessary actions based on the user's input. We add an event listener using [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) and provide a function to execute. +**Here's how event listeners work:** +- **Listens** for specific user actions like clicks, keystrokes, or mouse movements +- **Executes** your custom code when the specified event occurs +- **Responds** immediately to user interactions, creating a seamless experience +- **Handles** multiple events on the same element using different listeners -> **NOTE:** There are many ways to create event listeners. You can use anonymous functions, create named functions, or use shortcuts like setting the `click` property. In this exercise, we will focus on `addEventListener` and anonymous functions, as this is the most common and flexible approach used by web developers. `addEventListener` works for all events, and the event name can be passed as a parameter. +> **NOTE:** It's worth highlighting there are numerous ways to create event listeners. You can use anonymous functions, or create named ones. You can use various shortcuts, like setting the `click` property, or using `addEventListener()`. In our exercise we are going to focus on `addEventListener()` and anonymous functions, as it's probably the most common technique web developers use. It's also the most flexible, as `addEventListener()` works for all events, and the event name can be provided as a parameter. ### Common events -There are [dozens of events](https://developer.mozilla.org/docs/Web/Events) you can listen to when building an application. Essentially, anything a user does on a page triggers an event, giving you the power to create the desired user experience. Fortunately, you'll typically only need a few key events. Here are some common ones (including the two we'll use for our game): +While web browsers offer dozens of different events you can listen for, most interactive applications rely on just a handful of essential events. Understanding these core events will give you the foundation to build sophisticated user interactions. -- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): Triggered when the user clicks on something, like a button or hyperlink. -- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): Triggered when the user right-clicks. -- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): Triggered when the user highlights text. -- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): Triggered when the user enters text. +There are [dozens of events](https://developer.mozilla.org/docs/Web/Events) available for you to listen to when creating an application. Basically anything a user does on a page raises an event, which gives you a lot of power to ensure they get the experience you desire. Fortunately, you'll normally only need a small handful of events. Here's a few common ones (including the two we'll use when creating our game): -## Creating the game +| Event | Description | Common Use Cases | +|-------|-------------|------------------| +| `click` | The user clicked on something | Buttons, links, interactive elements | +| `contextmenu` | The user clicked the right mouse button | Custom right-click menus | +| `select` | The user highlighted some text | Text editing, copy operations | +| `input` | The user input some text | Form validation, real-time search | + +**Understanding these event types:** +- **Triggers** when users interact with specific elements on your page +- **Provides** detailed information about the user's action through event objects +- **Enables** you to create responsive, interactive web applications +- **Works** consistently across different browsers and devices -We will create a game to explore how events work in JavaScript. Our game will test a player's typing skills, which is an essential skill for developers. Here's the general flow of the game: +## Creating the game -- The player clicks the start button and is presented with a quote to type. -- The player types the quote as quickly as possible in a textbox. - - As each word is completed, the next word is highlighted. - - If the player makes a typo, the textbox turns red. - - When the player completes the quote, a success message is displayed along with the elapsed time. +Now that you understand how events work, let's put that knowledge into practice by building something useful. We'll create a typing speed game that demonstrates event handling while helping you develop an important developer skill. + +We're going to create a game to explore how events work in JavaScript. Our game will test a player's typing skill, which is one of the most underrated skills all developers should have. Fun fact: the QWERTY keyboard layout we use today was actually designed in the 1870s for typewriters - and good typing skills are still just as valuable for programmers today! The general flow of the game will look like this: + +```mermaid +flowchart TD + A[Player clicks Start] --> B[Random quote displays] + B --> C[Player types in textbox] + C --> D{Word complete?} + D -->|Yes| E[Highlight next word] + D -->|No| F{Correct so far?} + F -->|Yes| G[Keep normal styling] + F -->|No| H[Show error styling] + E --> I{Quote complete?} + I -->|No| C + I -->|Yes| J[Show success message with time] + G --> C + H --> C +``` +**Here's how our game will work:** +- **Starts** when the player clicks the start button and displays a random quote +- **Tracks** the player's typing progress word by word in real-time +- **Highlights** the current word to guide the player's focus +- **Provides** immediate visual feedback for typing errors +- **Calculates** and displays the total time when the quote is completed -Let's build the game and learn about events! +Let's build our game, and learn about events! ### File structure -We will need three files: **index.html**, **script.js**, and **style.css**. Let's set them up to make things easier. +Before we start coding, let's get organized! Having a clean file structure from the beginning will save you headaches later and make your project more professional. 😊 -- Create a new folder for your project by opening a console or terminal and running the following command: +We're going to keep things simple with just three files: `index.html` for our page structure, `script.js` for all our game logic, and `style.css` to make everything look great. This is the classic trio that powers most of the web! + +**Create a new folder for your work by opening a console or terminal window and issuing the following command:** ```bash # Linux or macOS @@ -60,29 +97,49 @@ mkdir typing-game && cd typing-game md typing-game && cd typing-game ``` -- Open Visual Studio Code. +**Here's what these commands do:** +- **Creates** a new directory called `typing-game` for your project files +- **Navigates** into the newly created directory automatically +- **Sets up** a clean workspace for your game development + +**Open Visual Studio Code:** ```bash code . ``` -- Add three files to the folder in Visual Studio Code: - - index.html - - script.js - - style.css +**This command:** +- **Launches** Visual Studio Code in the current directory +- **Opens** your project folder in the editor +- **Provides** access to all the development tools you'll need + +**Add three files to the folder in Visual Studio Code with the following names:** +- `index.html` - Contains the structure and content of your game +- `script.js` - Handles all the game logic and event listeners +- `style.css` - Defines the visual appearance and styling ## Create the user interface -Based on the requirements, we know we need a few elements on our HTML page. Think of this as a recipe where we need specific ingredients: +Now let's build the stage where all our game action will happen! Think of this like designing the control panel for a spaceship - we need to make sure everything our players need is right where they expect it to be. -- A place to display the quote for the user to type. -- A place to display messages, like a success message. -- A textbox for typing. -- A start button. +Let's figure out what our game actually needs. If you were playing a typing game, what would you want to see on the screen? Here's what we'll need: -Each of these elements will need IDs so we can interact with them in JavaScript. We will also include references to the CSS and JavaScript files. +| UI Element | Purpose | HTML Element | +|------------|---------|-------------| +| Quote Display | Shows the text to type | `

` with `id="quote"` | +| Message Area | Displays status and success messages | `

` with `id="message"` | +| Text Input | Where players type the quote | `` with `id="typed-value"` | +| Start Button | Begins the game | ` - +

+

New? Add your Information

+
+
+ + +
+
+ + +
+ + ``` -This form will save the input information to local storage. -Next, create the results area. Add some divs below the final form tag: +**Here's what this form accomplishes:** +- **Creates** a semantic form structure with proper labels and input associations +- **Enables** browser autocomplete functionality for improved user experience +- **Requires** both fields to be filled before submission using the `required` attribute +- **Organizes** inputs with descriptive class names for easy styling and JavaScript targeting +- **Provides** clear instructions for users who are setting up the extension for the first time + +### Building the Results Display + +Next, create the results area that will show the carbon footprint data. Add this HTML below the form: -```HTML +```html
-
loading...
-
-
-
-

Region:

-

Carbon Usage:

-

Fossil Fuel Percentage:

-
- +
loading...
+
+
+
+

Region:

+

Carbon Usage:

+

Fossil Fuel Percentage:

+
+
``` -Now, try building the extension. Install the package dependencies: -``` -npm install -``` - -This command uses npm (Node Package Manager) to install webpack for the build process. Webpack bundles the code, and you can see the output in `/dist/main.js`. +**Breaking down what this structure provides:** +- **`loading`**: **Displays** a loading message while API data is being fetched +- **`errors`**: **Shows** error messages if API calls fail or data is invalid +- **`data`**: **Holds** raw data for debugging purposes during development +- **`result-container`**: **Presents** formatted carbon footprint information to users +- **`clear-btn`**: **Allows** users to change their region and reconfigure the extension -At this stage, the extension should build successfully. If you deploy it in Edge, you'll see a neatly displayed form. - -Congratulations! You've taken the first steps toward building a browser extension. In the next lessons, you'll add more functionality and features. - ---- +### Setting Up the Build Process -## 🚀 Challenge +Now let's install the project dependencies and test the build process: -Explore a browser extension store and install an extension. Examine its files to uncover interesting details. What do you find? - -## Post-Lecture Quiz - -[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/24) - -## Review & Self Study - -In this lesson, you learned about the history of web browsers. Take some time to explore how the inventors of the World Wide Web envisioned its use. Here are some useful resources: +```bash +npm install +``` -[The History of Web Browsers](https://www.mozilla.org/firefox/browsers/browser-history/) +**What this installation process accomplishes:** +- **Downloads** Webpack and other development dependencies specified in `package.json` +- **Configures** the build toolchain for compiling modern JavaScript +- **Prepares** the development environment for extension building and testing +- **Enables** code bundling, optimization, and cross-browser compatibility features -[History of the Web](https://webfoundation.org/about/vision/history-of-the-web/) +> 💡 **Build Process Insight**: Webpack bundles your source code from `/src/index.js` into `/dist/main.js`. This process optimizes your code for production and ensures browser compatibility. -[An interview with Tim Berners-Lee](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want) +### Testing Your Progress -## Assignment +At this point, you can test your extension: +1. **Run** the build command to compile your code +2. **Load** the extension into your browser using the developer mode +3. **Verify** that the form displays correctly and looks professional +4. **Check** that all form elements are properly aligned and functional + +**What you've accomplished:** +- **Built** the foundational HTML structure for your extension +- **Created** both configuration and results interfaces with proper semantic markup +- **Set up** a modern development workflow using industry-standard tools +- **Prepared** the foundation for adding interactive JavaScript functionality + +### 🔄 **Pedagogical Check-in** +**Extension Development Progress**: Verify your understanding before continuing: +- ✅ Can you explain the purpose of each file in the project structure? +- ✅ Do you understand how the build process transforms your source code? +- ✅ Why do we separate configuration and results into different UI sections? +- ✅ How does the form structure support both usability and accessibility? + +**Development Workflow Understanding**: You should now be able to: +1. **Modify** HTML and CSS for your extension interface +2. **Run** the build command to compile your changes +3. **Reload** the extension in your browser to test updates +4. **Debug** issues using browser developer tools + +You've completed the first phase of browser extension development. Like how the Wright brothers first needed to understand aerodynamics before achieving flight, understanding these foundational concepts prepares you for building more complex interactive features in the next lesson. + +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Enhance the browser extension by adding form validation and user feedback features to improve the user experience when entering API keys and region codes. + +**Prompt:** Create JavaScript validation functions that check if the API key field contains at least 20 characters and if the region code follows the correct format (like 'US-NEISO'). Add visual feedback by changing input border colors to green for valid inputs and red for invalid ones. Also add a toggle feature to show/hide the API key for security purposes. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + +## 🚀 Challenge + +Take a look at a browser extension store and install one to your browser. You can examine its files in interesting ways. What do you discover? + +## Post-Lecture Quiz + +[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/24) + +## Review & Self Study + +In this lesson you learned a little about the history of the web browser; take this opportunity to learn about how the inventors of the World Wide Web envisioned its use by reading more about its history. Some useful sites include: + +[The History of Web Browsers](https://www.mozilla.org/firefox/browsers/browser-history/) + +[History of the Web](https://webfoundation.org/about/vision/history-of-the-web/) + +[An interview with Tim Berners-Lee](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want) + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open Chrome/Edge extensions page (chrome://extensions) and explore what you have installed +- [ ] Look at your browser's DevTools Network tab while loading a webpage +- [ ] Try viewing page source (Ctrl+U) to see HTML structure +- [ ] Inspect any webpage element and modify its CSS in DevTools + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and understand browser fundamentals +- [ ] Create a basic manifest.json file for a browser extension +- [ ] Build a simple "Hello World" extension that shows a popup +- [ ] Test loading your extension in developer mode +- [ ] Explore the browser extension documentation for your target browser + +### 📅 **Your Week-Long Extension Journey** +- [ ] Complete a functional browser extension with real utility +- [ ] Learn about content scripts, background scripts, and popup interactions +- [ ] Master browser APIs like storage, tabs, and messaging +- [ ] Design user-friendly interfaces for your extension +- [ ] Test your extension across different websites and scenarios +- [ ] Publish your extension to the browser's extension store + +### 🌟 **Your Month-Long Browser Development** +- [ ] Build multiple extensions solving different user problems +- [ ] Learn advanced browser APIs and security best practices +- [ ] Contribute to open source browser extension projects +- [ ] Master cross-browser compatibility and progressive enhancement +- [ ] Create extension development tools and templates for others +- [ ] Become a browser extension expert who helps other developers + +## 🎯 Your Browser Extension Mastery Timeline + +```mermaid +timeline + title Browser Extension Development Progression + + section Foundation (15 minutes) + Browser Understanding: Core architecture + : Rendering process + : Extension integration points + + section Setup (20 minutes) + Development Environment: Project structure + : Build tools configuration + : Browser developer mode + : Extension loading process + + section Interface Design (25 minutes) + User Experience: HTML structure + : CSS styling + : Form validation + : Responsive design + + section Core Functionality (35 minutes) + JavaScript Integration: Event handling + : API interactions + : Data storage + : Error handling + + section Browser APIs (45 minutes) + Platform Integration: Permissions system + : Storage APIs + : Tab management + : Context menus + + section Advanced Features (1 week) + Professional Extensions: Background scripts + : Content scripts + : Cross-browser compatibility + : Performance optimization + + section Publishing (2 weeks) + Distribution: Store submission + : Review process + : User feedback + : Update management + + section Expert Level (1 month) + Extension Ecosystem: Advanced APIs + : Security best practices + : Enterprise features + : Framework integration +``` +### 🛠️ Your Extension Development Toolkit Summary + +After completing this lesson, you now have: +- **Browser Architecture Knowledge**: Understanding of rendering engines, security models, and extension integration +- **Development Environment**: Modern toolchain with Webpack, NPM, and debugging capabilities +- **UI/UX Foundation**: Semantic HTML structure with progressive disclosure patterns +- **Security Awareness**: Understanding of browser permissions and safe development practices +- **Cross-Browser Concepts**: Knowledge of compatibility considerations and testing approaches +- **API Integration**: Foundation for working with external data sources +- **Professional Workflow**: Industry-standard development and testing procedures + +**Real-World Applications**: These skills directly apply to: +- **Web Development**: Single-page applications and progressive web apps +- **Desktop Applications**: Electron and web-based desktop software +- **Mobile Development**: Hybrid apps and web-based mobile solutions +- **Enterprise Tools**: Internal productivity applications and workflow automation +- **Open Source**: Contributing to browser extension projects and web standards + +**Next Level**: You're ready to add interactive functionality, work with browser APIs, and create extensions that solve real user problems! + +## Assignment [Restyle your extension](assignment.md) --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/5-browser-extension/1-about-browsers/assignment.md b/translations/en/5-browser-extension/1-about-browsers/assignment.md index fca9ed925..745addb73 100644 --- a/translations/en/5-browser-extension/1-about-browsers/assignment.md +++ b/translations/en/5-browser-extension/1-about-browsers/assignment.md @@ -1,25 +1,137 @@ - -# Restyle your Extension +# Assignment: Restyle Your Browser Extension + +## Overview + +Now that you've built the HTML structure for your carbon footprint browser extension, it's time to make it visually appealing and user-friendly. Great design enhances the user experience and makes your extension more professional and engaging. + +Your extension comes with basic CSS styling, but this assignment challenges you to create a unique visual identity that reflects your personal style while maintaining excellent usability. ## Instructions -The codebase for this extension includes pre-existing styles, but you’re not obligated to use them. Personalize your extension by modifying its CSS file to create your own unique design. +### Part 1: Analyze the Current Design + +Before making changes, examine the existing CSS structure: + +1. **Locate** the CSS files in your extension project +2. **Review** the current styling approach and color scheme +3. **Identify** areas for improvement in layout, typography, and visual hierarchy +4. **Consider** how the design supports user goals (easy form completion and clear data display) + +### Part 2: Design Your Custom Styling + +Create a cohesive visual design that includes: + +**Color Scheme:** +- Choose a primary color palette that reflects environmental themes +- Ensure sufficient contrast for accessibility (use tools like WebAIM's contrast checker) +- Consider how colors will look across different browser themes + +**Typography:** +- Select readable fonts that work well at small extension sizes +- Establish a clear hierarchy with appropriate font sizes and weights +- Ensure text remains legible in both light and dark browser themes + +**Layout and Spacing:** +- Improve the visual organization of form elements and data display +- Add appropriate padding and margins for better readability +- Consider responsive design principles for different screen sizes + +### Part 3: Implement Your Design + +Modify the CSS files to implement your design: + +```css +/* Example starting points for customization */ + +.form-data { + /* Style the configuration form */ + background: /* your choice */; + padding: /* your spacing */; + border-radius: /* your preference */; +} + +.result-container { + /* Style the data display area */ + background: /* complementary color */; + border: /* your border style */; + margin: /* your spacing */; +} + +/* Add your custom styles here */ +``` + +**Key areas to style:** +- **Form elements**: Input fields, labels, and submit button +- **Results display**: Data container, text styling, and loading states +- **Interactive elements**: Hover effects, button states, and transitions +- **Overall layout**: Container spacing, background colors, and visual hierarchy + +### Part 4: Test and Refine + +1. **Build** your extension with `npm run build` +2. **Load** the updated extension into your browser +3. **Test** all visual states (form entry, loading, results display, errors) +4. **Verify** accessibility with browser developer tools +5. **Refine** your styles based on actual usage + +## Creative Challenges + +### Basic Level +- Update colors and fonts to create a cohesive theme +- Improve spacing and alignment throughout the interface +- Add subtle hover effects to interactive elements + +### Intermediate Level +- Design custom icons or graphics for your extension +- Implement smooth transitions between different states +- Create a unique loading animation for API calls + +### Advanced Level +- Design multiple theme options (light/dark/high-contrast) +- Implement responsive design for different browser window sizes +- Add micro-interactions that enhance the user experience + +## Submission Guidelines + +Your completed assignment should include: + +- **Modified CSS files** with your custom styling +- **Screenshots** showing your extension in different states (form, loading, results) +- **Brief description** (2-3 sentences) explaining your design choices and how they improve the user experience + +## Assessment Rubric + +| Criteria | Exemplary (4) | Proficient (3) | Developing (2) | Beginning (1) | +|----------|---------------|----------------|----------------|----------------| +| **Visual Design** | Creative, cohesive design that enhances usability and reflects strong design principles | Good design choices with consistent styling and clear visual hierarchy | Basic design improvements with some consistency issues | Minimal styling changes or inconsistent design | +| **Functionality** | All styles work perfectly across different states and browser environments | Styles work well with minor issues in edge cases | Most styles functional with some display problems | Significant styling issues that impact usability | +| **Code Quality** | Clean, well-organized CSS with meaningful class names and efficient selectors | Good CSS structure with appropriate use of selectors and properties | Acceptable CSS with some organization issues | Poor CSS structure or overly complex styling | +| **Accessibility** | Excellent color contrast, readable fonts, and consideration for users with disabilities | Good accessibility practices with minor areas for improvement | Basic accessibility considerations with some issues | Limited attention to accessibility requirements | + +## Tips for Success + +> 💡 **Design Tip**: Start with subtle changes and build up to more dramatic styling. Small improvements in typography and spacing often have big impacts on perceived quality. + +**Best practices to follow:** +- **Test** your extension in both light and dark browser themes +- **Use** relative units (em, rem) for better scalability +- **Maintain** consistent spacing using CSS custom properties +- **Consider** how your design will look to users with different visual needs +- **Validate** your CSS to ensure it follows proper syntax + +> ⚠️ **Common Mistake**: Don't sacrifice usability for visual appeal. Your extension should be both beautiful and functional. -## Rubric +**Remember to:** +- **Keep** important information easily readable +- **Ensure** buttons and interactive elements are easy to click +- **Maintain** clear visual feedback for user actions +- **Test** your design with real data, not just placeholder text -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | -------------------------------------------- | --------------------- | ----------------- | -| | Code is submitted with fully functional new styles | Styling is incomplete | Styles contain errors | +Good luck creating a browser extension that's both functional and visually stunning! --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the definitive source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/5-browser-extension/2-forms-browsers-local-storage/README.md b/translations/en/5-browser-extension/2-forms-browsers-local-storage/README.md index e4b5202ca..942130823 100644 --- a/translations/en/5-browser-extension/2-forms-browsers-local-storage/README.md +++ b/translations/en/5-browser-extension/2-forms-browsers-local-storage/README.md @@ -1,31 +1,99 @@ - # Browser Extension Project Part 2: Call an API, use Local Storage +```mermaid +journey + title Your API Integration & Storage Journey + section Foundation + Setup DOM references: 3: Student + Add event listeners: 4: Student + Handle form submission: 4: Student + section Data Management + Implement local storage: 4: Student + Build API calls: 5: Student + Handle async operations: 5: Student + section User Experience + Add error handling: 5: Student + Create loading states: 4: Student + Polish interactions: 5: Student +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/25) -### Introduction - -In this lesson, you'll learn how to call an API by submitting your browser extension's form and displaying the results within the extension. Additionally, you'll explore how to store data in your browser's local storage for future use and reference. - -✅ Follow the numbered sections in the relevant files to know where to insert your code. - -### Set up the elements to manipulate in the extension: - -By now, you've created the HTML for the form and the results `
` in your browser extension. From this point forward, you'll work in the `/src/index.js` file to build your extension step by step. Refer to the [previous lesson](../1-about-browsers/README.md) for instructions on setting up your project and the build process. - -In your `index.js` file, start by creating some `const` variables to hold the values associated with different fields: - -```JavaScript +## Introduction + +Remember that browser extension you started building? Right now you've got a nice-looking form, but it's essentially static. Today we'll bring it to life by connecting it to real data and giving it memory. + +Think about the Apollo mission control computers - they didn't just display fixed information. They constantly communicated with spacecraft, updated with telemetry data, and remembered critical mission parameters. That's the kind of dynamic behavior we're building today. Your extension will reach out to the internet, grab real environmental data, and remember your settings for next time. + +API integration might sound complex, but it's really just teaching your code how to communicate with other services. Whether you're fetching weather data, social media feeds, or carbon footprint information like we'll do today, it's all about establishing these digital connections. We'll also explore how browsers can persist information - similar to how libraries have used card catalogs to remember where books belong. + +By the end of this lesson, you'll have a browser extension that fetches real data, stores user preferences, and provides a smooth experience. Let's get started! + +```mermaid +mindmap + root((Dynamic Extensions)) + DOM Manipulation + Element Selection + Event Handling + State Management + UI Updates + Local Storage + Data Persistence + Key-Value Pairs + Session Management + User Preferences + API Integration + HTTP Requests + Authentication + Data Parsing + Error Handling + Async Programming + Promises + Async/Await + Error Catching + Non-blocking Code + User Experience + Loading States + Error Messages + Smooth Transitions + Data Validation +``` +✅ Follow the numbered segments in the appropriate files to know where to place your code + +## Set up the elements to manipulate in the extension + +Before your JavaScript can manipulate the interface, it needs references to specific HTML elements. Think of it like a telescope needing to be pointed at particular stars - before Galileo could study Jupiter's moons, he had to locate and focus on Jupiter itself. + +In your `index.js` file, we'll create `const` variables that capture references to each important form element. This is similar to how scientists label their equipment - instead of searching through the entire laboratory each time, they can directly access what they need. + +```mermaid +flowchart LR + A[JavaScript Code] --> B[document.querySelector] + B --> C[CSS Selectors] + C --> D[HTML Elements] + + D --> E[".form-data"] + D --> F[".region-name"] + D --> G[".api-key"] + D --> H[".loading"] + D --> I[".errors"] + D --> J[".result-container"] + + E --> K[Form Element] + F --> L[Input Field] + G --> M[Input Field] + H --> N[UI Element] + I --> O[UI Element] + J --> P[UI Element] + + style A fill:#e1f5fe + style D fill:#e8f5e8 + style K fill:#fff3e0 + style L fill:#fff3e0 + style M fill:#fff3e0 +``` +```javascript // form fields const form = document.querySelector('.form-data'); const region = document.querySelector('.region-name'); @@ -41,123 +109,259 @@ const myregion = document.querySelector('.my-region'); const clearBtn = document.querySelector('.clear-btn'); ``` -All these fields are referenced by their CSS class, as you defined them in the HTML during the previous lesson. - -### Add listeners - -Next, add event listeners to the form and the clear button that resets the form. This ensures that when a user submits the form or clicks the reset button, an action is triggered. Also, add the call to initialize the app at the bottom of the file: - -```JavaScript +**Here's what this code does:** +- **Captures** form elements using `document.querySelector()` with CSS class selectors +- **Creates** references to input fields for the region name and API key +- **Establishes** connections to result display elements for carbon usage data +- **Sets up** access to UI elements like loading indicators and error messages +- **Stores** each element reference in a `const` variable for easy reuse throughout your code + +## Add event listeners + +Now we'll make your extension respond to user actions. Event listeners are your code's way of monitoring user interactions. Think of them like the operators in early telephone exchanges - they listened for incoming calls and connected the right circuits when someone wanted to make a connection. + +```mermaid +sequenceDiagram + participant User + participant Form + participant JavaScript + participant API + participant Storage + + User->>Form: Fills out region/API key + User->>Form: Clicks submit + Form->>JavaScript: Triggers submit event + JavaScript->>JavaScript: handleSubmit(e) + JavaScript->>Storage: Save user preferences + JavaScript->>API: Fetch carbon data + API->>JavaScript: Returns data + JavaScript->>Form: Update UI with results + + User->>Form: Clicks clear button + Form->>JavaScript: Triggers click event + JavaScript->>Storage: Clear saved data + JavaScript->>Form: Reset to initial state +``` +```javascript form.addEventListener('submit', (e) => handleSubmit(e)); clearBtn.addEventListener('click', (e) => reset(e)); init(); ``` -✅ Notice the shorthand used to listen for submit or click events, and how the event is passed to the handleSubmit or reset functions. Can you write the equivalent of this shorthand in a longer format? Which approach do you prefer? +**Understanding these concepts:** +- **Attaches** a submit listener to the form that triggers when users press Enter or click submit +- **Connects** a click listener to the clear button for resetting the form +- **Passes** the event object `(e)` to handler functions for additional control +- **Calls** the `init()` function immediately to set up the initial state of your extension + +✅ Notice the shorthand arrow function syntax used here. This modern JavaScript approach is cleaner than traditional function expressions, but both work equally well! + +### 🔄 **Pedagogical Check-in** +**Event Handling Understanding**: Before moving to initialization, ensure you can: +- ✅ Explain how `addEventListener` connects user actions to JavaScript functions +- ✅ Understand why we pass the event object `(e)` to handler functions +- ✅ Recognize the difference between `submit` and `click` events +- ✅ Describe when the `init()` function runs and why + +**Quick Self-Test**: What would happen if you forgot `e.preventDefault()` in a form submission? +*Answer: The page would reload, losing all JavaScript state and interrupting the user experience* + +## Build the initialization and reset functions -### Build out the init() function and the reset() function: +Let's create the initialization logic for your extension. The `init()` function is like a ship's navigation system checking its instruments - it determines the current state and adjusts the interface accordingly. It checks if someone has used your extension before and loads their previous settings. -Now, you'll create the function that initializes the extension, called `init()`: +The `reset()` function provides users with a fresh start - similar to how scientists reset their instruments between experiments to ensure clean data. -```JavaScript +```javascript function init() { - //if anything is in localStorage, pick it up + // Check if user has previously saved API credentials const storedApiKey = localStorage.getItem('apiKey'); const storedRegion = localStorage.getItem('regionName'); - //set icon to be generic green - //todo + // Set extension icon to generic green (placeholder for future lesson) + // TODO: Implement icon update in next lesson if (storedApiKey === null || storedRegion === null) { - //if we don't have the keys, show the form + // First-time user: show the setup form form.style.display = 'block'; results.style.display = 'none'; loading.style.display = 'none'; clearBtn.style.display = 'none'; errors.textContent = ''; } else { - //if we have saved keys/regions in localStorage, show results when they load - displayCarbonUsage(storedApiKey, storedRegion); + // Returning user: load their saved data automatically + displayCarbonUsage(storedApiKey, storedRegion); results.style.display = 'none'; form.style.display = 'none'; clearBtn.style.display = 'block'; } -}; +} function reset(e) { e.preventDefault(); - //clear local storage for region only + // Clear stored region to allow user to choose a new location localStorage.removeItem('regionName'); + // Restart the initialization process init(); } - ``` -This function contains some interesting logic. As you read through it, can you understand what happens? - -- Two `const` variables are set up to check if the user has stored an APIKey and region code in local storage. -- If either of these is null, the form is displayed by changing its style to 'block.' -- The results, loading indicator, and clear button are hidden, and any error text is cleared. -- If both the key and region exist, a routine is started to: - - Call the API to retrieve carbon usage data. - - Hide the results area. - - Hide the form. - - Display the reset button. - -Before proceeding, it's helpful to learn about an important browser concept: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). LocalStorage is a convenient way to store strings in the browser as `key-value` pairs. This type of web storage can be managed using JavaScript to handle data within the browser. LocalStorage does not expire, whereas SessionStorage (another type of web storage) is cleared when the browser is closed. Each type of storage has its own advantages and disadvantages. - -> Note: Your browser extension has its own local storage. The main browser window operates as a separate instance and behaves independently. - -You can set your APIKey to have a string value, for example, and view it in Edge by "inspecting" a web page (right-click to inspect) and navigating to the Applications tab to see the storage. - -![Local storage pane](../../../../translated_images/en/localstorage.472f8147b6a3f8d141d9551c95a2da610ac9a3c6a73d4a1c224081c98bae09d9.png) +**Breaking down what happens here:** +- **Retrieves** stored API key and region from browser's local storage +- **Checks** if this is a first-time user (no stored credentials) or returning user +- **Shows** the setup form for new users and hides other interface elements +- **Loads** saved data automatically for returning users and displays the reset option +- **Manages** the user interface state based on available data + +**Key concepts about Local Storage:** +- **Persists** data between browser sessions (unlike session storage) +- **Stores** data as key-value pairs using `getItem()` and `setItem()` +- **Returns** `null` when no data exists for a given key +- **Provides** a simple way to remember user preferences and settings + +> 💡 **Understanding Browser Storage**: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) is like giving your extension persistent memory. Consider how the ancient Library of Alexandria stored scrolls - information remained available even when scholars left and returned. +> +> **Key characteristics:** +> - **Persists** data even after you close your browser +> - **Survives** computer restarts and browser crashes +> - **Provides** substantial storage space for user preferences +> - **Offers** instant access without network delays + +> **Important Note**: Your browser extension has its own isolated local storage that's separate from regular web pages. This provides security and prevents conflicts with other websites. + +You can view your stored data by opening browser Developer Tools (F12), navigating to the **Application** tab, and expanding the **Local Storage** section. + +```mermaid +stateDiagram-v2 + [*] --> CheckStorage: Extension starts + CheckStorage --> FirstTime: No stored data + CheckStorage --> Returning: Data found + + FirstTime --> ShowForm: Display setup form + ShowForm --> UserInput: User enters data + UserInput --> SaveData: Store in localStorage + SaveData --> FetchAPI: Get carbon data + + Returning --> LoadData: Read from localStorage + LoadData --> FetchAPI: Get carbon data + + FetchAPI --> ShowResults: Display data + ShowResults --> UserAction: User interacts + + UserAction --> Reset: Clear button clicked + UserAction --> ShowResults: View data + + Reset --> ClearStorage: Remove saved data + ClearStorage --> FirstTime: Back to setup +``` +![Local storage pane](../../../../translated_images/en/localstorage.472f8147b6a3f8d1.webp) -✅ Consider situations where you would NOT want to store certain data in LocalStorage. Generally, storing API Keys in LocalStorage is a bad idea! Can you understand why? In our case, since this app is purely for learning and won't be published in an app store, we'll use this method. +> ⚠️ **Security Consideration**: In production applications, storing API keys in LocalStorage poses security risks since JavaScript can access this data. For learning purposes, this approach works fine, but real applications should use secure server-side storage for sensitive credentials. -Notice that you use the Web API to interact with LocalStorage, either by using `getItem()`, `setItem()`, or `removeItem()`. It's widely supported across browsers. +## Handle form submission -Before building the `displayCarbonUsage()` function called in `init()`, let's implement the functionality to handle the initial form submission. +Now we'll handle what happens when someone submits your form. By default, browsers reload the page when forms are submitted, but we'll intercept this behavior to create a smoother experience. -### Handle the form submission +This approach mirrors how mission control handles spacecraft communications - instead of resetting the entire system for each transmission, they maintain continuous operation while processing new information. -Create a function called `handleSubmit` that accepts an event argument `(e)`. Prevent the event from propagating (in this case, stop the browser from refreshing) and call a new function, `setUpUser`, passing in the arguments `apiKey.value` and `region.value`. This way, you use the two values provided via the initial form when the relevant fields are filled. +Create a function that captures the form submission event and extracts the user's input: -```JavaScript +```javascript function handleSubmit(e) { e.preventDefault(); setUpUser(apiKey.value, region.value); } ``` -✅ Refresh your memory: The HTML you created in the previous lesson includes two input fields whose `values` are captured via the `const` variables you set up at the top of the file. Both fields are marked as `required`, so the browser prevents users from submitting null values. +**In the above, we've:** +- **Prevents** the default form submission behavior that would refresh the page +- **Extracts** user input values from the API key and region fields +- **Passes** the form data to the `setUpUser()` function for processing +- **Maintains** single-page application behavior by avoiding page reloads + +✅ Remember that your HTML form fields include the `required` attribute, so the browser automatically validates that users provide both the API key and region before this function runs. -### Set up the user +## Set up user preferences -Next, move on to the `setUpUser` function, where you'll set local storage values for `apiKey` and `regionName`. Add a new function: +The `setUpUser` function is responsible for saving the user's credentials and initiating the first API call. This creates a smooth transition from setup to displaying results. -```JavaScript +```javascript function setUpUser(apiKey, regionName) { + // Save user credentials for future sessions localStorage.setItem('apiKey', apiKey); localStorage.setItem('regionName', regionName); + + // Update UI to show loading state loading.style.display = 'block'; errors.textContent = ''; clearBtn.style.display = 'block'; - //make initial call + + // Fetch carbon usage data with user's credentials displayCarbonUsage(apiKey, regionName); } ``` -This function displays a loading message while the API is being called. At this point, you've reached the most critical function of this browser extension! - -### Display Carbon Usage - -Finally, it's time to query the API! - -Before proceeding, let's discuss APIs. APIs, or [Application Programming Interfaces](https://www.webopedia.com/TERM/A/API.html), are essential tools for web developers. They provide standardized ways for programs to interact and communicate with each other. For example, if you're building a website that needs to query a database, someone might have created an API for you to use. While there are many types of APIs, one of the most popular is a [REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/). - -✅ The term 'REST' stands for 'Representational State Transfer' and involves using variously-configured URLs to fetch data. Research the different types of APIs available to developers. Which format appeals to you? - -There are some key points to note about this function. First, observe the [`async` keyword](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Writing functions to run asynchronously ensures they wait for an action, such as data being returned, to complete before continuing. +**Step by step, here's what's happening:** +- **Saves** the API key and region name to local storage for future use +- **Shows** a loading indicator to inform users that data is being fetched +- **Clears** any previous error messages from the display +- **Reveals** the clear button for users to reset their settings later +- **Initiates** the API call to fetch real carbon usage data + +This function creates a seamless user experience by managing both data persistence and user interface updates in one coordinated action. + +## Display carbon usage data + +Now we'll connect your extension to external data sources through APIs. This transforms your extension from a standalone tool into something that can access real-time information from across the internet. + +**Understanding APIs** + +[APIs](https://www.webopedia.com/TERM/A/API.html) are how different applications communicate with each other. Think of them like the telegraph system that connected distant cities in the 19th century - operators would send requests to distant stations and receive responses with the requested information. Every time you check social media, ask a voice assistant a question, or use a delivery app, APIs are facilitating these data exchanges. + +```mermaid +flowchart TD + A[Your Extension] --> B[HTTP Request] + B --> C[CO2 Signal API] + C --> D{Valid Request?} + D -->|Yes| E[Query Database] + D -->|No| F[Return Error] + E --> G[Carbon Data] + G --> H[JSON Response] + H --> I[Your Extension] + F --> I + I --> J[Update UI] + + subgraph "API Request" + K[Headers: auth-token] + L[Parameters: countryCode] + M[Method: GET] + end + + subgraph "API Response" + N[Carbon Intensity] + O[Fossil Fuel %] + P[Timestamp] + end + + style C fill:#e8f5e8 + style G fill:#fff3e0 + style I fill:#e1f5fe +``` +**Key concepts about REST APIs:** +- **REST** stands for 'Representational State Transfer' +- **Uses** standard HTTP methods (GET, POST, PUT, DELETE) to interact with data +- **Returns** data in predictable formats, typically JSON +- **Provides** consistent, URL-based endpoints for different types of requests + +✅ The [CO2 Signal API](https://www.co2signal.com/) we'll use provides real-time carbon intensity data from electrical grids worldwide. This helps users understand the environmental impact of their electricity usage! + +> 💡 **Understanding Asynchronous JavaScript**: The [`async` keyword](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) enables your code to handle multiple operations simultaneously. When you request data from a server, you don't want your entire extension to freeze - that would be like air traffic control stopping all operations while waiting for one plane to respond. +> +> **Key benefits:** +> - **Maintains** extension responsiveness while data loads +> - **Allows** other code to continue executing during network requests +> - **Improves** code readability compared to traditional callback patterns +> - **Enables** graceful error handling for network issues Here's a quick video about `async`: @@ -165,62 +369,168 @@ Here's a quick video about `async`: > 🎥 Click the image above for a video about async/await. -Create a new function to query the CO2Signal API: - -```JavaScript -import axios from '../node_modules/axios'; +### 🔄 **Pedagogical Check-in** +**Async Programming Understanding**: Before diving into the API function, verify you understand: +- ✅ Why we use `async/await` instead of blocking the entire extension +- ✅ How `try/catch` blocks handle network errors gracefully +- ✅ The difference between synchronous and asynchronous operations +- ✅ Why API calls can fail and how to handle those failures + +**Real-World Connection**: Consider these everyday async examples: +- **Ordering food**: You don't wait by the kitchen - you get a receipt and continue other activities +- **Sending emails**: Your email app doesn't freeze while sending - you can compose more emails +- **Loading web pages**: Images load progressively while you can already read the text + +**API Authentication Flow**: +```mermaid +sequenceDiagram + participant Ext as Extension + participant API as CO2 Signal API + participant DB as Database + + Ext->>API: Request with auth-token + API->>API: Validate token + API->>DB: Query carbon data + DB->>API: Return data + API->>Ext: JSON response + Ext->>Ext: Update UI +``` +Create the function to fetch and display carbon usage data: +```javascript +// Modern fetch API approach (no external dependencies needed) async function displayCarbonUsage(apiKey, region) { try { - await axios - .get('https://api.co2signal.com/v1/latest', { - params: { - countryCode: region, - }, - headers: { - 'auth-token': apiKey, - }, - }) - .then((response) => { - let CO2 = Math.floor(response.data.data.carbonIntensity); - - //calculateColor(CO2); - - loading.style.display = 'none'; - form.style.display = 'none'; - myregion.textContent = region; - usage.textContent = - Math.round(response.data.data.carbonIntensity) + ' grams (grams C02 emitted per kilowatt hour)'; - fossilfuel.textContent = - response.data.data.fossilFuelPercentage.toFixed(2) + - '% (percentage of fossil fuels used to generate electricity)'; - results.style.display = 'block'; - }); + // Fetch carbon intensity data from CO2 Signal API + const response = await fetch('https://api.co2signal.com/v1/latest', { + method: 'GET', + headers: { + 'auth-token': apiKey, + 'Content-Type': 'application/json' + }, + // Add query parameters for the specific region + ...new URLSearchParams({ countryCode: region }) && { + url: `https://api.co2signal.com/v1/latest?countryCode=${region}` + } + }); + + // Check if the API request was successful + if (!response.ok) { + throw new Error(`API request failed: ${response.status}`); + } + + const data = await response.json(); + const carbonData = data.data; + + // Calculate rounded carbon intensity value + const carbonIntensity = Math.round(carbonData.carbonIntensity); + + // Update the user interface with fetched data + loading.style.display = 'none'; + form.style.display = 'none'; + myregion.textContent = region.toUpperCase(); + usage.textContent = `${carbonIntensity} grams (grams CO₂ emitted per kilowatt hour)`; + fossilfuel.textContent = `${carbonData.fossilFuelPercentage.toFixed(2)}% (percentage of fossil fuels used to generate electricity)`; + results.style.display = 'block'; + + // TODO: calculateColor(carbonIntensity) - implement in next lesson + } catch (error) { - console.log(error); + console.error('Error fetching carbon data:', error); + + // Show user-friendly error message loading.style.display = 'none'; results.style.display = 'none'; - errors.textContent = 'Sorry, we have no data for the region you have requested.'; + errors.textContent = 'Sorry, we couldn\'t fetch data for that region. Please check your API key and region code.'; } } ``` -This is a large function. What's happening here? +**Breaking down what happens here:** +- **Uses** the modern `fetch()` API instead of external libraries like Axios for cleaner, dependency-free code +- **Implements** proper error checking with `response.ok` to catch API failures early +- **Handles** asynchronous operations with `async/await` for more readable code flow +- **Authenticates** with the CO2 Signal API using the `auth-token` header +- **Parses** JSON response data and extracts carbon intensity information +- **Updates** multiple UI elements with formatted environmental data +- **Provides** user-friendly error messages when API calls fail + +**Key modern JavaScript concepts demonstrated:** +- **Template literals** with `${}` syntax for clean string formatting +- **Error handling** with try/catch blocks for robust applications +- **Async/await** pattern for handling network requests gracefully +- **Object destructuring** to extract specific data from API responses +- **Method chaining** for multiple DOM manipulations + +✅ This function demonstrates several important web development concepts - communicating with external servers, handling authentication, processing data, updating interfaces, and managing errors gracefully. These are fundamental skills that professional developers use regularly. + +```mermaid +flowchart TD + A[Start API Call] --> B[Fetch Request] + B --> C{Network Success?} + C -->|No| D[Network Error] + C -->|Yes| E{Response OK?} + E -->|No| F[API Error] + E -->|Yes| G[Parse JSON] + G --> H{Valid Data?} + H -->|No| I[Data Error] + H -->|Yes| J[Update UI] + + D --> K[Show Error Message] + F --> K + I --> K + J --> L[Hide Loading] + K --> L + + style A fill:#e1f5fe + style J fill:#e8f5e8 + style K fill:#ffebee + style L fill:#f3e5f5 +``` +### 🔄 **Pedagogical Check-in** +**Complete System Understanding**: Verify your mastery of the entire flow: +- ✅ How DOM references enable JavaScript to control the interface +- ✅ Why local storage creates persistence between browser sessions +- ✅ How async/await makes API calls without freezing the extension +- ✅ What happens when API calls fail and how errors are handled +- ✅ Why user experience includes loading states and error messages + +🎉 **What you've accomplished:** You've created a browser extension that: +- **Connects** to the internet and retrieves real environmental data +- **Persists** user settings between sessions +- **Handles** errors gracefully instead of crashing +- **Provides** a smooth, professional user experience + +Test your work by running `npm run build` and refreshing your extension in the browser. You now have a functional carbon footprint tracker. The next lesson will add dynamic icon functionality to complete the extension. -- Following best practices, the `async` keyword is used to make the function behave asynchronously. The function includes a `try/catch` block because it will return a promise when the API provides data. Since you can't control the speed of the API's response (or whether it responds at all), you need to handle this uncertainty by calling it asynchronously. -- The function queries the CO2Signal API to retrieve data for your region using your API Key. To use the key, you need to include authentication in the header parameters. -- Once the API responds, various elements of its response data are assigned to the parts of your screen set up to display this information. -- If there's an error or no result, an error message is displayed. +--- -✅ Asynchronous programming patterns are another valuable tool in your skillset. Read [about the different ways](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) you can configure this type of code. +## GitHub Copilot Agent Challenge 🚀 -Congratulations! If you build your extension (`npm run build`) and refresh it in your extensions pane, you now have a functioning extension! The only thing left to fix is the icon, which you'll address in the next lesson. +Use the Agent mode to complete the following challenge: ---- +**Description:** Enhance the browser extension by adding error handling improvements and user experience features. This challenge will help you practice working with APIs, local storage, and DOM manipulation using modern JavaScript patterns. +**Prompt:** Create an enhanced version of the displayCarbonUsage function that includes: 1) A retry mechanism for failed API calls with exponential backoff, 2) Input validation for the region code before making the API call, 3) A loading animation with progress indicators, 4) Caching of API responses in localStorage with expiration timestamps (cache for 30 minutes), and 5) A feature to display historical data from previous API calls. Also add proper TypeScript-style JSDoc comments to document all function parameters and return types. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. ## 🚀 Challenge -We've discussed several types of APIs in these lessons. Choose a web API and research in depth what it offers. For example, explore APIs available within browsers, such as the [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). In your opinion, what makes an API great? +Expand your understanding of APIs by exploring the wealth of browser-based APIs available for web development. Choose one of these browser APIs and build a small demonstration: + +- [Geolocation API](https://developer.mozilla.org/docs/Web/API/Geolocation_API) - Get user's current location +- [Notification API](https://developer.mozilla.org/docs/Web/API/Notifications_API) - Send desktop notifications +- [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) - Create interactive drag interfaces +- [Web Storage API](https://developer.mozilla.org/docs/Web/API/Web_Storage_API) - Advanced local storage techniques +- [Fetch API](https://developer.mozilla.org/docs/Web/API/Fetch_API) - Modern alternative to XMLHttpRequest + +**Research questions to consider:** +- What real-world problems does this API solve? +- How does the API handle errors and edge cases? +- What security considerations exist when using this API? +- How widely supported is this API across different browsers? + +After your research, identify what characteristics make an API developer-friendly and reliable. ## Post-Lecture Quiz @@ -228,7 +538,109 @@ We've discussed several types of APIs in these lessons. Choose a web API and res ## Review & Self Study -In this lesson, you learned about LocalStorage and APIs, both of which are highly useful for professional web developers. Can you think about how these two concepts work together? Consider how you would design a website that stores items to be used by an API. +You learned about LocalStorage and APIs in this lesson, both very useful for the professional web developer. Can you think about how these two things work together? Think about how you would architect a web site that would store items to be used by an API. + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open DevTools Application tab and explore localStorage on any website +- [ ] Create a simple HTML form and test form validation in the browser +- [ ] Try storing and retrieving data using localStorage in the browser console +- [ ] Inspect form data being submitted using the Network tab + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and understand form handling concepts +- [ ] Build a browser extension form that saves user preferences +- [ ] Implement client-side form validation with helpful error messages +- [ ] Practice using the chrome.storage API for extension data persistence +- [ ] Create a user interface that responds to saved user settings + +### 📅 **Your Week-Long Extension Building** +- [ ] Complete a full-featured browser extension with form functionality +- [ ] Master different storage options: local, sync, and session storage +- [ ] Implement advanced form features like autocomplete and validation +- [ ] Add import/export functionality for user data +- [ ] Test your extension thoroughly across different browsers +- [ ] Polish your extension's user experience and error handling + +### 🌟 **Your Month-Long Web API Mastery** +- [ ] Build complex applications using various browser storage APIs +- [ ] Learn about offline-first development patterns +- [ ] Contribute to open source projects involving data persistence +- [ ] Master privacy-focused development and GDPR compliance +- [ ] Create reusable libraries for form handling and data management +- [ ] Share knowledge about web APIs and extension development + +## 🎯 Your Extension Development Mastery Timeline + +```mermaid +timeline + title API Integration & Storage Learning Progression + + section DOM Fundamentals (15 minutes) + Element References: querySelector mastery + : Event listener setup + : State management basics + + section Local Storage (20 minutes) + Data Persistence: Key-value storage + : Session management + : User preference handling + : Storage inspection tools + + section Form Handling (25 minutes) + User Input: Form validation + : Event prevention + : Data extraction + : UI state transitions + + section API Integration (35 minutes) + External Communication: HTTP requests + : Authentication patterns + : JSON data parsing + : Response handling + + section Async Programming (40 minutes) + Modern JavaScript: Promise handling + : Async/await patterns + : Error management + : Non-blocking operations + + section Error Handling (30 minutes) + Robust Applications: Try/catch blocks + : User-friendly messages + : Graceful degradation + : Debugging techniques + + section Advanced Patterns (1 week) + Professional Development: Caching strategies + : Rate limiting + : Retry mechanisms + : Performance optimization + + section Production Skills (1 month) + Enterprise Features: Security best practices + : API versioning + : Monitoring & logging + : Scalable architecture +``` +### 🛠️ Your Full-Stack Development Toolkit Summary + +After completing this lesson, you now have: +- **DOM Mastery**: Precise element targeting and manipulation +- **Storage Expertise**: Persistent data management with localStorage +- **API Integration**: Real-time data fetching and authentication +- **Async Programming**: Non-blocking operations with modern JavaScript +- **Error Handling**: Robust applications that gracefully handle failures +- **User Experience**: Loading states, validation, and smooth interactions +- **Modern Patterns**: fetch API, async/await, and ES6+ features + +**Professional Skills Gained**: You've implemented patterns used in: +- **Web Applications**: Single-page apps with external data sources +- **Mobile Development**: API-driven apps with offline capabilities +- **Desktop Software**: Electron apps with persistent storage +- **Enterprise Systems**: Authentication, caching, and error handling +- **Modern Frameworks**: React/Vue/Angular data management patterns + +**Next Level**: You're ready to explore advanced topics like caching strategies, real-time WebSocket connections, or complex state management! ## Assignment @@ -236,5 +648,7 @@ In this lesson, you learned about LocalStorage and APIs, both of which are highl --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/5-browser-extension/2-forms-browsers-local-storage/assignment.md b/translations/en/5-browser-extension/2-forms-browsers-local-storage/assignment.md index b0f626087..b75a332ed 100644 --- a/translations/en/5-browser-extension/2-forms-browsers-local-storage/assignment.md +++ b/translations/en/5-browser-extension/2-forms-browsers-local-storage/assignment.md @@ -1,25 +1,100 @@ - # Adopt an API +## Overview + +APIs open up endless possibilities for creative web development! In this assignment, you'll choose an external API and build a browser extension that solves a real problem or provides valuable functionality to users. + ## Instructions -APIs can be a lot of fun to experiment with. Here is a [list of many free ones](https://github.com/public-apis/public-apis). Choose an API and create a browser extension that addresses a problem. It could be something as small as not having enough pictures of pets (in which case, try the [dog CEO API](https://dog.ceo/dog-api/)) or something more significant—just have fun with it! +### Step 1: Choose Your API +Select an API from this curated [list of free public APIs](https://github.com/public-apis/public-apis). Consider these categories: + +**Popular options for beginners:** +- **Entertainment**: [Dog CEO API](https://dog.ceo/dog-api/) for random dog pictures +- **Weather**: [OpenWeatherMap](https://openweathermap.org/api) for current weather data +- **Quotes**: [Quotable API](https://quotable.io/) for inspirational quotes +- **News**: [NewsAPI](https://newsapi.org/) for current headlines +- **Fun Facts**: [Numbers API](http://numbersapi.com/) for interesting number facts + +### Step 2: Plan Your Extension +Before coding, answer these planning questions: +- What problem does your extension solve? +- Who is your target user? +- What data will you store in local storage? +- How will you handle API failures or rate limits? + +### Step 3: Build Your Extension +Your extension should include: + +**Required Features:** +- Form inputs for any required API parameters +- API integration with proper error handling +- Local storage for user preferences or API keys +- Clean, responsive user interface +- Loading states and user feedback + +**Code Requirements:** +- Use modern JavaScript (ES6+) features +- Implement async/await for API calls +- Include proper error handling with try/catch blocks +- Add meaningful comments explaining your code +- Follow consistent code formatting + +### Step 4: Test and Polish +- Test your extension with various inputs +- Handle edge cases (no internet, invalid API responses) +- Ensure your extension works after browser restart +- Add user-friendly error messages + +## Bonus Challenges + +Take your extension to the next level: +- Add multiple API endpoints for richer functionality +- Implement data caching to reduce API calls +- Create keyboard shortcuts for common actions +- Add data export/import features +- Implement user customization options + +## Submission Requirements + +1. **Working browser extension** that successfully integrates with your chosen API +2. **README file** explaining: + - Which API you chose and why + - How to install and use your extension + - Any API keys or setup required + - Screenshots of your extension in action +3. **Clean, commented code** following modern JavaScript practices ## Rubric -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | ------------------------------------------------------------------------ | ---------------------------------------- | ----------------------- | -| | A fully functional browser extension is submitted using an API from the list above | A partially functional browser extension is submitted | The submission contains errors | +| Criteria | Exemplary (90-100%) | Proficient (80-89%) | Developing (70-79%) | Beginning (60-69%) | +|----------|---------------------|---------------------|---------------------|--------------------| +| **API Integration** | Flawless API integration with comprehensive error handling and edge case management | Successful API integration with basic error handling | API works but has limited error handling | API integration has significant issues | +| **Code Quality** | Clean, well-commented modern JavaScript following best practices | Good code structure with adequate comments | Code works but needs better organization | Poor code quality with minimal comments | +| **User Experience** | Polished interface with excellent loading states and user feedback | Good interface with basic user feedback | Basic interface that functions adequately | Poor user experience with confusing interface | +| **Local Storage** | Sophisticated use of local storage with data validation and management | Proper implementation of local storage for key features | Basic local storage implementation | Minimal or incorrect use of local storage | +| **Documentation** | Comprehensive README with setup instructions and screenshots | Good documentation covering most requirements | Basic documentation missing some details | Poor or missing documentation | + +## Getting Started Tips + +1. **Start simple**: Choose an API that doesn't require complex authentication +2. **Read the docs**: Thoroughly understand your chosen API's endpoints and responses +3. **Plan your UI**: Sketch your extension's interface before coding +4. **Test frequently**: Build incrementally and test each feature as you add it +5. **Handle errors**: Always assume API calls might fail and plan accordingly + +## Resources + +- [Browser Extension Documentation](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions) +- [Fetch API Guide](https://developer.mozilla.org/docs/Web/API/Fetch_API/Using_Fetch) +- [Local Storage Tutorial](https://developer.mozilla.org/docs/Web/API/Window/localStorage) +- [JSON Parsing and Handling](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) + +Have fun building something useful and creative! 🚀 --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/5-browser-extension/3-background-tasks-and-performance/README.md b/translations/en/5-browser-extension/3-background-tasks-and-performance/README.md index 30943c028..a501c4611 100644 --- a/translations/en/5-browser-extension/3-background-tasks-and-performance/README.md +++ b/translations/en/5-browser-extension/3-background-tasks-and-performance/README.md @@ -1,158 +1,450 @@ - # Browser Extension Project Part 3: Learn about Background Tasks and Performance +```mermaid +journey + title Your Performance Optimization Journey + section Foundation + Learn browser tools: 3: Student + Understand profiling: 4: Student + Identify bottlenecks: 4: Student + section Extension Features + Build color system: 4: Student + Create background tasks: 5: Student + Update icons dynamically: 5: Student + section Optimization + Monitor performance: 5: Student + Debug issues: 4: Student + Polish experience: 5: Student +``` +Ever wonder what makes some browser extensions feel snappy and responsive while others seem sluggish? The secret lies in what's happening behind the scenes. While users click around your extension's interface, there's a whole world of background processes quietly managing data fetching, icon updates, and system resources. + +This is our final lesson in the browser extension series, and we're going to make your carbon footprint tracker work smoothly. You'll add dynamic icon updates and learn how to spot performance issues before they become problems. It's like tuning a race car - small optimizations can make a huge difference in how everything runs. + +By the time we're done, you'll have a polished extension and understand the performance principles that separate good web apps from great ones. Let's dive into the world of browser optimization. + ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/27) ### Introduction -In the last two lessons of this module, you learned how to create a form and a display area for data fetched from an API. This is a very common way to establish a web presence. You even learned how to handle asynchronous data fetching. Your browser extension is almost complete. +In our previous lessons, you built a form, connected it to an API, and tackled asynchronous data fetching. Your extension is taking shape nicely. + +Now we need to add the finishing touches - like making that extension icon change colors based on the carbon data. This reminds me of how NASA had to optimize every system on the Apollo spacecraft. They couldn't afford any wasted cycles or memory because lives depended on performance. While our browser extension isn't quite that critical, the same principles apply - efficient code creates better user experiences. + +```mermaid +mindmap + root((Performance & Background Tasks)) + Browser Performance + Rendering Pipeline + Asset Optimization + DOM Manipulation + JavaScript Execution + Profiling Tools + Developer Tools + Performance Tab + Timeline Analysis + Bottleneck Detection + Extension Architecture + Background Scripts + Content Scripts + Message Passing + Icon Management + Optimization Strategies + Code Splitting + Lazy Loading + Caching + Resource Compression + Visual Feedback + Dynamic Icons + Color Coding + Real-time Updates + User Experience +``` +## Web Performance Basics -The remaining tasks involve managing background processes, such as refreshing the color of the extension's icon. This is a great opportunity to discuss how the browser handles these types of tasks. Let's consider these browser tasks in the context of optimizing the performance of your web assets as you develop them. +When your code runs efficiently, people can actually *feel* the difference. You know that moment when a page loads instantly or an animation flows smoothly? That's good performance at work. -## Web Performance Basics +Performance isn't just about speed - it's about making web experiences that feel natural instead of clunky and frustrating. Back in the early days of computing, Grace Hopper famously kept a nanosecond (a piece of wire about a foot long) on her desk to show how far light travels in one billionth of a second. It was her way of explaining why every microsecond matters in computing. Let's explore the detective tools that help you figure out what's slowing things down. > "Website performance is about two things: how fast the page loads, and how fast the code on it runs." -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/) -The topic of making websites lightning-fast across all devices, for all users, and in all situations is understandably vast. Here are some key points to keep in mind when building either a standard web project or a browser extension. +The topic of how to make your websites blazingly fast on all kinds of devices, for all kinds of users, in all kinds of situations, is unsurprisingly vast. Here are some points to keep in mind as you build either a standard web project or a browser extension. + +The first step in optimizing your site is understanding what's actually happening under the hood. Fortunately, your browser comes with powerful detective tools built right in. + +```mermaid +flowchart LR + A[HTML] --> B[Parse] + B --> C[DOM Tree] + D[CSS] --> E[Parse] + E --> F[CSSOM] + G[JavaScript] --> H[Execute] + + C --> I[Render Tree] + F --> I + H --> I + + I --> J[Layout] + J --> K[Paint] + K --> L[Composite] + L --> M[Display] + + subgraph "Critical Rendering Path" + N["1. Parse HTML"] + O["2. Parse CSS"] + P["3. Execute JS"] + Q["4. Build Render Tree"] + R["5. Layout Elements"] + S["6. Paint Pixels"] + T["7. Composite Layers"] + end + + style M fill:#e8f5e8 + style I fill:#fff3e0 + style H fill:#ffebee +``` +To open Developer Tools in Edge, click those three dots in the top right corner, then go to More Tools > Developer Tools. Or use the keyboard shortcut: `Ctrl` + `Shift` + `I` on Windows or `Option` + `Command` + `I` on Mac. Once you're there, click on the Performance tab - this is where you'll do your investigation. -The first step to ensuring your site runs efficiently is to gather data about its performance. The best place to start is the developer tools in your web browser. In Edge, click the "Settings and more" button (the three dots icon in the top-right corner of the browser), then navigate to More Tools > Developer Tools and open the Performance tab. You can also use the keyboard shortcuts `Ctrl` + `Shift` + `I` on Windows or `Option` + `Command` + `I` on Mac to open developer tools. +**Here's your performance detective toolkit:** +- **Open** Developer Tools (you'll use these constantly as a developer!) +- **Head** to the Performance tab - think of it as your web app's fitness tracker +- **Hit** that Record button and watch your page in action +- **Study** the results to spot what's slowing things down -The Performance tab includes a Profiling tool. Open a website (for example, [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) and click the 'Record' button, then refresh the site. Stop the recording at any time, and you'll see routines generated for 'script', 'render', and 'paint' processes: +Let's try this out. Open a website (Microsoft.com works well for this) and click that 'Record' button. Now refresh the page and watch the profiler capture everything that happens. When you stop recording, you'll see a detailed breakdown of how the browser 'scripts', 'renders', and 'paints' the site. It reminds me of how mission control monitors every system during a rocket launch - you get real-time data on exactly what's happening and when. -![Edge profiler](../../../../translated_images/en/profiler.5a4a62479c5df01cfec9aab74173dba13f91d2c968e1a1ae434c26165792df15.png) +![Edge profiler](../../../../translated_images/en/profiler.5a4a62479c5df01c.webp) -✅ Visit the [Microsoft Documentation](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) on the Performance panel in Edge. +✅ The [Microsoft Documentation](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) has tons more details if you want to dive deeper -> Tip: To get an accurate reading of your website's startup time, clear your browser's cache. +> Pro tip: Clear your browser cache before testing to see how your site performs for first-time visitors - it's usually quite different from repeat visits! -Select elements of the profile timeline to zoom in on events that occur while your page loads. +Select elements of the profile timeline to zoom in on events that happen while your page loads. -Get a snapshot of your page's performance by selecting a part of the profile timeline and reviewing the summary pane: +Get a snapshot of your page's performance by selecting a part of the profile timeline and looking at the summary pane: -![Edge profiler snapshot](../../../../translated_images/en/snapshot.97750180ebcad73794a3594b36925eb5c8dbaac9e03fec7f9b974188c9ac63c7.png) +![Edge profiler snapshot](../../../../translated_images/en/snapshot.97750180ebcad737.webp) Check the Event Log pane to see if any event took longer than 15 ms: -![Edge event log](../../../../translated_images/en/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.png) +![Edge event log](../../../../translated_images/en/log.804026979f3707e0.webp) + +✅ Get to know your profiler! Open the developer tools on this site and see if there are any bottlenecks. What's the slowest-loading asset? The fastest? + +```mermaid +flowchart TD + A[Open DevTools] --> B[Navigate to Performance Tab] + B --> C[Click Record Button] + C --> D[Perform Actions] + D --> E[Stop Recording] + E --> F{Analyze Results} + + F --> G[Check Timeline] + F --> H[Review Network] + F --> I[Examine Scripts] + F --> J[Identify Paint Events] + + G --> K{Long Tasks?} + H --> L{Large Assets?} + I --> M{Render Blocking?} + J --> N{Expensive Paints?} + + K -->|Yes| O[Optimize JavaScript] + L -->|Yes| P[Compress Assets] + M -->|Yes| Q[Add Async/Defer] + N -->|Yes| R[Simplify Styles] + + O --> S[Test Again] + P --> S + Q --> S + R --> S + + style A fill:#e1f5fe + style F fill:#fff3e0 + style S fill:#e8f5e8 +``` +## What to Look For When Profiling -✅ Familiarize yourself with the profiler! Open the developer tools on this site and check for bottlenecks. What is the slowest-loading asset? The fastest? +Running the profiler is just the beginning - the real skill is knowing what those colorful charts are actually telling you. Don't worry, you'll get the hang of reading them. Experienced developers have learned to spot the warning signs before they become full-blown problems. -## Profiling checks +Let's talk about the usual suspects - the performance troublemakers that tend to sneak into web projects. Like how Marie Curie had to carefully monitor radiation levels in her lab, we need to watch for certain patterns that indicate trouble brewing. Catching these early will save you (and your users) a lot of frustration. -In general, there are some "problem areas" every web developer should monitor when building a site to avoid unpleasant surprises during production deployment. +**Asset sizes**: Websites have been getting "heavier" over the years, and a lot of that extra weight comes from images. It's like we've been stuffing more and more into our digital suitcases. -**Asset sizes**: The web has become 'heavier' and slower over the years, partly due to the use of images. +✅ Check out the [Internet Archive](https://httparchive.org/reports/page-weight) to see how page sizes have grown over time - it's quite revealing. -✅ Explore the [Internet Archive](https://httparchive.org/reports/page-weight) for a historical view of page weight and more. +**Here's how to keep your assets optimized:** +- **Compress** those images! Modern formats like WebP can cut file sizes dramatically +- **Serve** the right image size for each device - no need to send huge desktop images to phones +- **Minify** your CSS and JavaScript - every byte counts +- **Use** lazy loading so images only download when users actually scroll to them -A good practice is to ensure your images are optimized and delivered at the appropriate size and resolution for your users. +**DOM traversals**: The browser has to build its Document Object Model based on the code you write, so it's in the interest of good page performance to keep your tags minimal, only using and styling what the page needs. To this point, excess CSS associated with a page could be optimized; styles that need to be used only on one page don't need to be included in the main style sheet, for example. -**DOM traversals**: The browser builds its Document Object Model based on the code you write, so good page performance depends on keeping your tags minimal and only using and styling what the page requires. For example, excess CSS associated with a page can be optimized; styles needed for only one page don't need to be included in the main stylesheet. +**Key strategies for DOM optimization:** +- **Minimizes** the number of HTML elements and nesting levels +- **Removes** unused CSS rules and consolidates stylesheets efficiently +- **Organizes** CSS to load only what's needed for each page +- **Structures** HTML semantically for better browser parsing -**JavaScript**: Every JavaScript developer should watch for 'render-blocking' scripts that must load before the rest of the DOM can be traversed and painted in the browser. Consider using `defer` with your inline scripts (as demonstrated in the Terrarium module). +**JavaScript**: Every JavaScript developer should watch for 'render-blocking' scripts that must be loaded before the rest of the DOM can be traversed and painted to the browser. Consider using `defer` with your inline scripts (as is done in the Terrarium module). -✅ Test some sites on a [Site Speed Test website](https://www.webpagetest.org/) to learn more about common checks for site performance. +**Modern JavaScript optimization techniques:** +- **Uses** the `defer` attribute to load scripts after DOM parsing +- **Implements** code splitting to load only necessary JavaScript +- **Applies** lazy loading for non-critical functionality +- **Minimizes** the use of heavy libraries and frameworks when possible -Now that you understand how the browser renders the assets you send to it, let's look at the final steps to complete your extension: +✅ Try some sites on a [Site Speed Test website](https://www.webpagetest.org/) to learn more about the common checks that are done to determine site performance. -### Create a function to calculate color +### 🔄 **Pedagogical Check-in** +**Performance Understanding**: Before building extension features, ensure you can: +- ✅ Explain the critical rendering path from HTML to pixels +- ✅ Identify common performance bottlenecks in web applications +- ✅ Use browser developer tools to profile page performance +- ✅ Understand how asset size and DOM complexity affect speed + +**Quick Self-Test**: What happens when you have render-blocking JavaScript? +*Answer: The browser must download and execute the script before it can continue parsing HTML and rendering the page* -In `/src/index.js`, add a function called `calculateColor()` after the series of `const` variables you set to access the DOM: +**Real-World Performance Impact**: +- **100ms delay**: Users notice the slowdown +- **1 second delay**: Users start losing focus +- **3+ seconds**: 40% of users abandon the page +- **Mobile networks**: Performance matters even more -```JavaScript +Now that you have an idea of how the browser renders the assets you send to it, let's look at the last few things you need to do to complete your extension: + +### Create a function to calculate color + +Now we'll create a function that turns numerical data into meaningful colors. Think of it like a traffic light system - green for clean energy, red for high carbon intensity. + +This function will take the CO2 data from our API and determine what color best represents the environmental impact. It's similar to how scientists use color-coding in heat maps to visualize complex data patterns - from ocean temperatures to star formation. Let's add this to `/src/index.js`, right after those `const` variables we set up earlier: + +```mermaid +flowchart LR + A[CO2 Value] --> B[Find Closest Scale Point] + B --> C[Get Scale Index] + C --> D[Map to Color] + D --> E[Send to Background] + + subgraph "Color Scale" + F["0-150: Green (Clean)"] + G["150-600: Yellow (Moderate)"] + H["600-750: Orange (High)"] + I["750+: Brown (Very High)"] + end + + subgraph "Message Passing" + J[Content Script] + K[chrome.runtime.sendMessage] + L[Background Script] + M[Icon Update] + end + + style A fill:#e1f5fe + style D fill:#e8f5e8 + style E fill:#fff3e0 +``` +```javascript function calculateColor(value) { - let co2Scale = [0, 150, 600, 750, 800]; - let colors = ['#2AA364', '#F5EB4D', '#9E4229', '#381D02', '#381D02']; + // Define CO2 intensity scale (grams per kWh) + const co2Scale = [0, 150, 600, 750, 800]; + // Corresponding colors from green (clean) to dark brown (high carbon) + const colors = ['#2AA364', '#F5EB4D', '#9E4229', '#381D02', '#381D02']; - let closestNum = co2Scale.sort((a, b) => { + // Find the closest scale value to our input + const closestNum = co2Scale.sort((a, b) => { return Math.abs(a - value) - Math.abs(b - value); })[0]; - console.log(value + ' is closest to ' + closestNum); - let num = (element) => element > closestNum; - let scaleIndex = co2Scale.findIndex(num); - - let closestColor = colors[scaleIndex]; + + console.log(`${value} is closest to ${closestNum}`); + + // Find the index for color mapping + const num = (element) => element > closestNum; + const scaleIndex = co2Scale.findIndex(num); + + const closestColor = colors[scaleIndex]; console.log(scaleIndex, closestColor); + // Send color update message to background script chrome.runtime.sendMessage({ action: 'updateIcon', value: { color: closestColor } }); } ``` -What happens here? You pass a value (the carbon intensity) from the API call you completed in the last lesson, then calculate how close its value is to the index in the colors array. You then send the closest color value to the chrome runtime. +**Let's break down this clever little function:** +- **Sets up** two arrays - one for CO2 levels, another for colors (green = clean, brown = dirty!) +- **Finds** the closest match to our actual CO2 value using some neat array sorting +- **Grabs** the matching color using the findIndex() method +- **Sends** a message to Chrome's background script with our chosen color +- **Uses** template literals (those backticks) for cleaner string formatting +- **Keeps** everything organized with const declarations -The chrome.runtime has [an API](https://developer.chrome.com/extensions/runtime) that handles various background tasks, which your extension utilizes: +The `chrome.runtime` [API](https://developer.chrome.com/extensions/runtime) is like the nervous system of your extension - it handles all the behind-the-scenes communication and tasks: > "Use the chrome.runtime API to retrieve the background page, return details about the manifest, and listen for and respond to events in the app or extension lifecycle. You can also use this API to convert the relative path of URLs to fully-qualified URLs." -✅ If you're developing this browser extension for Edge, you might be surprised to use a chrome API. The newer Edge browser versions run on the Chromium browser engine, allowing you to leverage these tools. - -> Note: If you want to profile a browser extension, launch the dev tools from within the extension itself, as it operates as a separate browser instance. +**Why the Chrome Runtime API is so handy:** +- **Lets** different parts of your extension talk to each other +- **Handles** background work without freezing the user interface +- **Manages** your extension's lifecycle events +- **Makes** message passing between scripts super easy + +✅ If you're developing this browser extension for Edge, it might surprise you that you're using a chrome API. The newer Edge browser versions run on the Chromium browser engine, so you can leverage these tools. + +```mermaid +architecture-beta + group browser(logos:chrome)[Browser] + + service popup(logos:html5)[Popup UI] in browser + service content(logos:javascript)[Content Script] in browser + service background(database)[Background Script] in browser + service api(logos:api)[External API] in browser + + popup:R -- L:content + content:R -- L:background + background:T -- B:api + content:T -- B:api + + junction junctionCenter in browser + popup:R -- L:junctionCenter + junctionCenter:R -- L:background +``` +> **Pro Tip**: If you want to profile a browser extension, launch the dev tools from within the extension itself, as it is its own separate browser instance. This gives you access to extension-specific performance metrics. ### Set a default icon color -Now, in the `init()` function, set the icon to a generic green color initially by calling chrome's `updateIcon` action: +Before we start fetching real data, let's give our extension a starting point. Nobody likes staring at a blank or broken-looking icon. We'll start with a green color so users know the extension is working from the moment they install it. + +In your `init()` function, let's set up that default green icon: -```JavaScript +```javascript chrome.runtime.sendMessage({ action: 'updateIcon', - value: { - color: 'green', - }, + value: { + color: 'green', + }, }); ``` + +**What this initialization accomplishes:** +- **Sets** a neutral green color as the default state +- **Provides** immediate visual feedback when the extension loads +- **Establishes** the communication pattern with the background script +- **Ensures** users see a functional extension before data loads ### Call the function, execute the call -Next, call the function you just created by adding it to the promise returned by the CO2Signal API: +Now let's connect everything together so that when fresh CO2 data comes in, your icon automatically updates with the right color. It's like connecting the final circuit in an electronic device - suddenly all the individual components work as one system. -```JavaScript -//let CO2... +Add this line right after you get the CO2 data from the API: + +```javascript +// After retrieving CO2 data from the API +// let CO2 = data.data[0].intensity.actual; calculateColor(CO2); ``` -Finally, in `/dist/background.js`, add the listener for these background action calls: +**This integration accomplishes:** +- **Connects** the API data flow with the visual indicator system +- **Triggers** icon updates automatically when new data arrives +- **Ensures** real-time visual feedback based on current carbon intensity +- **Maintains** the separation of concerns between data fetching and display logic + +And finally, in `/dist/background.js`, add the listener for these background action calls: -```JavaScript +```javascript +// Listen for messages from the content script chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { if (msg.action === 'updateIcon') { chrome.action.setIcon({ imageData: drawIcon(msg.value) }); } }); -//borrowed from energy lollipop extension, nice feature! + +// Draw dynamic icon using Canvas API +// Borrowed from energy lollipop extension - nice feature! function drawIcon(value) { - let canvas = new OffscreenCanvas(200, 200); - let context = canvas.getContext('2d'); + // Create an offscreen canvas for better performance + const canvas = new OffscreenCanvas(200, 200); + const context = canvas.getContext('2d'); + // Draw a colored circle representing carbon intensity context.beginPath(); context.fillStyle = value.color; context.arc(100, 100, 50, 0, 2 * Math.PI); context.fill(); + // Return the image data for the browser icon return context.getImageData(50, 50, 100, 100); } ``` -In this code, you add a listener for any messages sent to the backend task manager. If the message is called 'updateIcon', the subsequent code runs to draw an icon of the appropriate color using the Canvas API. + +**Here's what this background script does:** +- **Listens** for messages from your main script (like a receptionist taking calls) +- **Processes** those 'updateIcon' requests to change your toolbar icon +- **Creates** new icons on the fly using the Canvas API +- **Draws** a simple colored circle that shows the current carbon intensity +- **Updates** your browser toolbar with the fresh icon +- **Uses** OffscreenCanvas for smooth performance (no UI blocking) ✅ You'll learn more about the Canvas API in the [Space Game lessons](../../6-space-game/2-drawing-to-canvas/README.md). -Now, rebuild your extension (`npm run build`), refresh and launch your extension, and watch the color change. Is it time to run an errand or wash the dishes? Now you know! +```mermaid +sequenceDiagram + participant CS as Content Script + participant BG as Background Script + participant Canvas as OffscreenCanvas + participant Browser as Browser Icon + + CS->>BG: sendMessage({action: 'updateIcon', color}) + BG->>Canvas: new OffscreenCanvas(200, 200) + Canvas->>Canvas: getContext('2d') + Canvas->>Canvas: beginPath() + fillStyle + arc() + Canvas->>Canvas: fill() + getImageData() + Canvas->>BG: Return image data + BG->>Browser: chrome.action.setIcon(imageData) + Browser->>Browser: Update toolbar icon +``` +### 🔄 **Pedagogical Check-in** +**Complete Extension Understanding**: Verify your mastery of the entire system: +- ✅ How does message passing work between different extension scripts? +- ✅ Why do we use OffscreenCanvas instead of regular Canvas for performance? +- ✅ What role does the Chrome Runtime API play in extension architecture? +- ✅ How does the color calculation algorithm map data to visual feedback? -Congratulations, you've built a functional browser extension and gained insights into how the browser works and how to profile its performance. +**Performance Considerations**: Your extension now demonstrates: +- **Efficient messaging**: Clean communication between script contexts +- **Optimized rendering**: OffscreenCanvas prevents UI blocking +- **Real-time updates**: Dynamic icon changes based on live data +- **Memory management**: Proper cleanup and resource handling ---- +**Time to test your extension:** +- **Build** everything with `npm run build` +- **Reload** your extension in the browser (don't forget this step) +- **Open** your extension and watch that icon change colors +- **Check** how it responds to real carbon data from around the world + +Now you'll know at a glance whether it's a good time for that load of laundry or if you should wait for cleaner energy. You've just built something genuinely useful and learned about browser performance along the way. + +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Enhance the browser extension's performance monitoring capabilities by adding a feature that tracks and displays load times for different components of the extension. + +**Prompt:** Create a performance monitoring system for the browser extension that measures and logs the time it takes to fetch CO2 data from the API, calculate colors, and update the icon. Add a function called `performanceTracker` that uses the Performance API to measure these operations and displays the results in the browser console with timestamps and duration metrics. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. ## 🚀 Challenge -Explore some open-source websites that have been around for a long time. Based on their GitHub history, try to determine how they were optimized for performance over the years, if at all. What is the most common pain point? +Here's an interesting detective mission: pick a few open source websites that have been around for years (think Wikipedia, GitHub, or Stack Overflow) and dig into their commit history. Can you spot where they made performance improvements? What problems kept cropping up? + +**Your investigation approach:** +- **Search** commit messages for words like "optimize," "performance," or "faster" +- **Look** for patterns - do they keep fixing the same types of issues? +- **Identify** the common culprits that slow down websites +- **Share** what you discover - other developers learn from real-world examples ## Post-Lecture Quiz @@ -160,9 +452,128 @@ Explore some open-source websites that have been around for a long time. Based o ## Review & Self Study -Consider subscribing to a [performance newsletter](https://perf.email/). - -Investigate how browsers measure web performance by exploring the performance tabs in their developer tools. Do you notice any significant differences? +Consider signing up for a [performance newsletter](https://perf.email/) + +Investigate some of the ways that browsers gauge web performance by looking through the performance tabs in their web tools. Do you find any major differences? + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open browser Task Manager (Shift+Esc in Chrome) to see extension resource usage +- [ ] Use DevTools Performance tab to record and analyze webpage performance +- [ ] Check the browser's Extensions page to see which extensions impact startup time +- [ ] Try disabling extensions temporarily to see performance differences + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and understand performance concepts +- [ ] Implement a background script for your browser extension +- [ ] Learn to use browser.alarms for efficient background tasks +- [ ] Practice message passing between content scripts and background scripts +- [ ] Measure and optimize your extension's resource usage + +### 📅 **Your Week-Long Performance Journey** +- [ ] Complete a high-performance browser extension with background functionality +- [ ] Master service workers and modern extension architecture +- [ ] Implement efficient data synchronization and caching strategies +- [ ] Learn advanced debugging techniques for extension performance +- [ ] Optimize your extension for both functionality and resource efficiency +- [ ] Create comprehensive tests for extension performance scenarios + +### 🌟 **Your Month-Long Optimization Mastery** +- [ ] Build enterprise-grade browser extensions with optimal performance +- [ ] Learn about Web Workers, Service Workers, and modern web performance +- [ ] Contribute to open source projects focused on performance optimization +- [ ] Master browser internals and advanced debugging techniques +- [ ] Create performance monitoring tools and best practices guides +- [ ] Become a performance expert who helps optimize web applications + +## 🎯 Your Browser Extension Mastery Timeline + +```mermaid +timeline + title Complete Extension Development Progression + + section Performance Fundamentals (20 minutes) + Browser Profiling: DevTools mastery + : Timeline analysis + : Bottleneck identification + : Critical rendering path + + section Background Tasks (25 minutes) + Extension Architecture: Message passing + : Background scripts + : Runtime API usage + : Cross-context communication + + section Visual Feedback (30 minutes) + Dynamic UI: Color calculation algorithms + : Canvas API integration + : Icon generation + : Real-time updates + + section Performance Optimization (35 minutes) + Efficient Code: Async operations + : Memory management + : Resource cleanup + : Performance monitoring + + section Production Ready (45 minutes) + Polish & Testing: Cross-browser compatibility + : Error handling + : User experience + : Performance validation + + section Advanced Features (1 week) + Extension Ecosystem: Chrome Web Store + : User feedback + : Analytics integration + : Update management + + section Professional Development (2 weeks) + Enterprise Extensions: Team collaboration + : Code reviews + : CI/CD pipelines + : Security audits + + section Expert Mastery (1 month) + Platform Expertise: Advanced Chrome APIs + : Performance optimization + : Architecture patterns + : Open source contribution +``` +### 🛠️ Your Complete Extension Development Toolkit + +After completing this trilogy, you now have mastered: +- **Browser Architecture**: Deep understanding of how extensions integrate with browser systems +- **Performance Profiling**: Ability to identify and fix bottlenecks using developer tools +- **Async Programming**: Modern JavaScript patterns for responsive, non-blocking operations +- **API Integration**: External data fetching with authentication and error handling +- **Visual Design**: Dynamic UI updates and Canvas-based graphics generation +- **Message Passing**: Inter-script communication in extension architectures +- **User Experience**: Loading states, error handling, and intuitive interactions +- **Production Skills**: Testing, debugging, and optimization for real-world deployment + +**Real-World Applications**: Your extension development skills apply directly to: +- **Progressive Web Apps**: Similar architecture and performance patterns +- **Electron Desktop Apps**: Cross-platform applications using web technologies +- **Mobile Hybrid Apps**: Cordova/PhoneGap development using web APIs +- **Enterprise Web Applications**: Complex dashboard and productivity tools +- **Chrome DevTools Extensions**: Advanced developer tooling and debugging +- **Web API Integration**: Any application that communicates with external services + +**Professional Impact**: You can now: +- **Build** production-ready browser extensions from concept to deployment +- **Optimize** web application performance using industry-standard profiling tools +- **Architect** scalable systems with proper separation of concerns +- **Debug** complex async operations and cross-context communication +- **Contribute** to open source extension projects and browser standards + +**Next Level Opportunities**: +- **Chrome Web Store Developer**: Publish extensions for millions of users +- **Web Performance Engineer**: Specialize in optimization and user experience +- **Browser Platform Developer**: Contribute to browser engine development +- **Extension Framework Creator**: Build tools that help other developers +- **Developer Relations**: Share knowledge through teaching and content creation + +🌟 **Achievement Unlocked**: You've built a complete, functional browser extension that demonstrates professional development practices and modern web standards! ## Assignment @@ -170,5 +581,7 @@ Investigate how browsers measure web performance by exploring the performance ta --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/5-browser-extension/3-background-tasks-and-performance/assignment.md b/translations/en/5-browser-extension/3-background-tasks-and-performance/assignment.md index 395340cfd..ecf96fd16 100644 --- a/translations/en/5-browser-extension/3-background-tasks-and-performance/assignment.md +++ b/translations/en/5-browser-extension/3-background-tasks-and-performance/assignment.md @@ -1,23 +1,100 @@ - # Analyze a site for performance -Provide a detailed report of a website, highlighting areas where performance issues exist. Examine why the site is slow and suggest ways to improve its speed. Don't rely solely on browser tools; research additional tools that can enhance your report. +## Assignment Overview + +Performance analysis is a critical skill for modern web developers. In this assignment, you'll conduct a comprehensive performance audit of a real website, using both browser-based tools and third-party services to identify bottlenecks and propose optimization strategies. + +Your task is to provide a detailed performance report that demonstrates your understanding of web performance principles and your ability to use professional analysis tools effectively. + +## Assignment Instructions + +**Choose a website** for analysis - select one of the following options: +- A popular website you use frequently (news site, social media, e-commerce) +- An open-source project website (GitHub pages, documentation sites) +- A local business website or portfolio site +- Your own project or previous coursework + +**Conduct multi-tool analysis** using at least three different approaches: +- **Browser DevTools** - Use Chrome/Edge Performance tab for detailed profiling +- **Online auditing tools** - Try Lighthouse, GTmetrix, or WebPageTest +- **Network analysis** - Examine resource loading, file sizes, and request patterns + +**Document your findings** in a comprehensive report that includes: + +### Performance Metrics Analysis +- **Load time measurements** from multiple tools and perspectives +- **Core Web Vitals** scores (LCP, FID, CLS) and their implications +- **Resource breakdown** showing which assets contribute most to load time +- **Network waterfall analysis** identifying blocking resources + +### Problem Identification +- **Specific performance bottlenecks** with supporting data +- **Root cause analysis** explaining why each issue occurs +- **User impact assessment** describing how problems affect real users +- **Priority ranking** of issues based on severity and fixing difficulty + +### Optimization Recommendations +- **Specific, actionable improvements** with expected impact +- **Implementation strategies** for each recommended change +- **Modern best practices** that could be applied (lazy loading, compression, etc.) +- **Tools and techniques** for ongoing performance monitoring + +## Research Requirements + +**Don't rely only on browser tools** - expand your analysis using: + +**Third-party auditing services:** +- [Google Lighthouse](https://developers.google.com/web/tools/lighthouse) - Comprehensive audits +- [GTmetrix](https://gtmetrix.com/) - Performance and optimization insights +- [WebPageTest](https://www.webpagetest.org/) - Real-world testing conditions +- [Pingdom](https://tools.pingdom.com/) - Global performance monitoring + +**Specialized analysis tools:** +- [Bundle Analyzer](https://bundlephobia.com/) - JavaScript bundle size analysis +- [Image optimization tools](https://squoosh.app/) - Asset optimization opportunities +- [Security headers analysis](https://securityheaders.com/) - Security performance impact + +## Deliverables Format + +Create a professional report (2-3 pages) that includes: + +1. **Executive Summary** - Key findings and recommendations overview +2. **Methodology** - Tools used and testing approach +3. **Current Performance Assessment** - Baseline metrics and measurements +4. **Issues Identified** - Detailed problem analysis with supporting data +5. **Recommendations** - Prioritized improvement strategies +6. **Implementation Roadmap** - Step-by-step optimization plan + +**Include visual evidence:** +- Screenshots of performance tools and metrics +- Charts or graphs showing performance data +- Before/after comparisons where possible +- Network waterfall charts and resource breakdowns ## Rubric -| Criteria | Exemplary | Adequate | Needs Improvement | -| -------- | ---------------------------------------------------------------------------------------------------------- | --------------------------- | ----------------------------- | -| | A report is presented with details drawn not only from browser tools but from 3rd party tools if available | A basic report is presented | A minimal report is presented | +| Criteria | Exemplary (90-100%) | Adequate (70-89%) | Needs Improvement (50-69%) | +| -------- | ------------------- | ----------------- | -------------------------- | +| **Analysis Depth** | Comprehensive analysis using 4+ tools with detailed metrics, root cause analysis, and user impact assessment | Good analysis using 3 tools with clear metrics and basic problem identification | Basic analysis using 2 tools with limited depth and minimal problem identification | +| **Tool Diversity** | Uses browser tools + 3+ third-party services with comparative analysis and insights from each | Uses browser tools + 2 third-party services with some comparative analysis | Uses browser tools + 1 third-party service with limited comparison | +| **Problem Identification** | Identifies 5+ specific performance issues with detailed root cause analysis and quantified impact | Identifies 3-4 performance issues with good analysis and some impact measurement | Identifies 1-2 performance issues with basic analysis | +| **Recommendations** | Provides specific, actionable recommendations with implementation details, expected impact, and modern best practices | Provides good recommendations with some implementation guidance and expected outcomes | Provides basic recommendations with limited implementation details | +| **Professional Presentation** | Well-organized report with clear structure, visual evidence, executive summary, and professional formatting | Good organization with some visual evidence and clear structure | Basic organization with minimal visual evidence | + +## Learning Outcomes + +By completing this assignment, you will demonstrate your ability to: +- **Apply** professional performance analysis tools and methodologies +- **Identify** performance bottlenecks using data-driven analysis +- **Analyze** the relationship between code quality and user experience +- **Recommend** specific, actionable optimization strategies +- **Communicate** technical findings in a professional format + +This assignment reinforces the performance concepts learned in the lesson while building practical skills you'll use throughout your web development career. --- + **Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the definitive source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/5-browser-extension/README.md b/translations/en/5-browser-extension/README.md index aa01000d7..c26263f27 100644 --- a/translations/en/5-browser-extension/README.md +++ b/translations/en/5-browser-extension/README.md @@ -1,12 +1,3 @@ - # Building a browser extension Creating browser extensions is an enjoyable and engaging way to explore app performance while developing a unique type of web asset. This module includes lessons on how browsers function, how to deploy a browser extension, how to create a form, interact with an API, utilize local storage, and assess and enhance your website's performance. @@ -23,7 +14,7 @@ Users can manually activate this extension by entering an API key and region cod ### Credits -![a green browser extension](../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.png) +![a green browser extension](../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp) ## Credits diff --git a/translations/en/5-browser-extension/solution/README.md b/translations/en/5-browser-extension/solution/README.md index 188ce0728..a4a73ca0c 100644 --- a/translations/en/5-browser-extension/solution/README.md +++ b/translations/en/5-browser-extension/solution/README.md @@ -1,17 +1,8 @@ - # Carbon Trigger Browser Extension: Completed Code Using tmrow's CO2 Signal API to monitor electricity consumption, create a browser extension that provides a reminder directly in your browser about the intensity of electricity usage in your region. Using this extension on the fly can help you make informed decisions about your activities based on this data. -![extension screenshot](../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.png) +![extension screenshot](../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp) ## Getting Started @@ -31,7 +22,7 @@ npm run build To install on Edge, open the 'three dot' menu in the top right corner of the browser to access the Extensions panel. From there, select 'Load Unpacked' to add a new extension. When prompted, open the 'dist' folder, and the extension will load. To use it, you will need an API key for CO2 Signal's API ([get one here via email](https://www.co2signal.com/) - enter your email in the box on this page) and the [code for your region](http://api.electricitymap.org/v3/zones) corresponding to the [Electricity Map](https://www.electricitymap.org/map) (for example, in Boston, I use 'US-NEISO'). -![installing](../../../../translated_images/en/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.png) +![installing](../../../../translated_images/en/install-on-edge.78634f02842c4828.webp) Once you input the API key and region into the extension interface, the colored dot in the browser extension bar will update to reflect your region's energy usage. It will also provide guidance on which energy-intensive activities might be suitable for you to undertake. The idea for this 'dot' system was inspired by the [Energy Lollipop extension](https://energylollipop.com/) for California emissions. diff --git a/translations/en/5-browser-extension/solution/translation/README.es.md b/translations/en/5-browser-extension/solution/translation/README.es.md index cbd3d98a6..ebaaaf6b7 100644 --- a/translations/en/5-browser-extension/solution/translation/README.es.md +++ b/translations/en/5-browser-extension/solution/translation/README.es.md @@ -1,12 +1,3 @@ - # Carbon Trigger Browser Extension: Complete Code Using tmrow's CO2 signal API to track electricity usage, create a browser extension so you can have a direct reminder in your browser about your region's electricity consumption. Using this ad hoc extension will help you make decisions about your activities based on this information. diff --git a/translations/en/5-browser-extension/solution/translation/README.fr.md b/translations/en/5-browser-extension/solution/translation/README.fr.md index c6f3aaea1..fff037d4f 100644 --- a/translations/en/5-browser-extension/solution/translation/README.fr.md +++ b/translations/en/5-browser-extension/solution/translation/README.fr.md @@ -1,17 +1,8 @@ - # Carbon Trigger Browser Extension: Completed Code Using the CO2 Signal API from tmrow to monitor electricity consumption, create a browser extension so you can get a direct reminder in your browser about the electricity usage in your region. Using this ad hoc extension will help you make informed decisions about your activities based on this information. -![extension screenshot](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.png) +![extension screenshot](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp) ## Getting Started @@ -31,7 +22,7 @@ npm run build To install on Edge, use the 'three dots' menu in the top-right corner of the browser to find the Extensions panel. From there, select 'Load unpacked extension' to load a new extension. Open the 'dist' folder when prompted, and the extension will load. To use it, you will need an API key for the CO2 Signal API ([get one here via email](https://www.co2signal.com/) - enter your email in the box on this page) and the [code for your region](http://api.electricitymap.org/v3/zones) corresponding to the [Electricity Map](https://www.electricitymap.org/map) (for Boston, for example, I use 'US-NEISO'). -![installation](../../../../../translated_images/en/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.png) +![installation](../../../../../translated_images/en/install-on-edge.78634f02842c4828.webp) Once the API key and region are entered in the extension interface, the colored dot in the browser's extension bar should change to reflect your region's energy consumption and give you an indicator of energy-intensive activities that might be appropriate to perform. The concept behind this 'dot' system was inspired by the [Energy Lollipop extension](https://energylollipop.com/) for California emissions. diff --git a/translations/en/5-browser-extension/solution/translation/README.hi.md b/translations/en/5-browser-extension/solution/translation/README.hi.md index d3d669f08..eabc3599f 100644 --- a/translations/en/5-browser-extension/solution/translation/README.hi.md +++ b/translations/en/5-browser-extension/solution/translation/README.hi.md @@ -1,17 +1,8 @@ - # Carbon Trigger Browser Extension: Completed Code Using tmrow's CO2 Signal API to track electricity usage, this browser extension provides a reminder about how carbon-intensive the electricity in your area is while you're browsing. By using this extension, you can make informed decisions about your activities based on this information. -![Extension Screenshot](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.png) +![Extension Screenshot](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp) ## Getting Started @@ -31,7 +22,7 @@ npm run build To install on Edge, use the 'three dots' menu in the top-right corner of the browser to find the Extensions panel. From there, select 'Load unpacked' to load a new extension. When prompted, open the 'dist' folder, and the extension will load. To use it, you will need an API key for CO2 Signal ([get it here via email](https://www.co2signal.com/) by entering your email in the box on that page) and [the code for your region](http://api.electricitymap.org/v3/zones) from [Electricity Map](https://www.electricitymap.org/map) (for example, in Boston, I use 'US-NEISO'). -![Installing](../../../../../translated_images/en/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.png) +![Installing](../../../../../translated_images/en/install-on-edge.78634f02842c4828.webp) Once the API key and region are entered into the extension interface, the colored dot in the browser extension bar should change to reflect the energy usage in your area and provide an indicator of whether energy-intensive activities are appropriate for your performance. The concept behind this 'dot' system was inspired by the [Energy Lollipop Extension](https://energylollipop.com/) for California emissions. diff --git a/translations/en/5-browser-extension/solution/translation/README.it.md b/translations/en/5-browser-extension/solution/translation/README.it.md index c2123fb9a..a0a06a408 100644 --- a/translations/en/5-browser-extension/solution/translation/README.it.md +++ b/translations/en/5-browser-extension/solution/translation/README.it.md @@ -1,17 +1,8 @@ - # Carbon Trigger Browser Extension: Code to Get Started We will use tmrow's CO2 Signal API to monitor electricity usage and create a browser extension that provides a direct reminder in your browser about the electricity intensity in your region. Using this custom extension will help you evaluate your activities based on this information. -![screenshot of the extension](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.png) +![screenshot of the extension](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp) ## Getting Started @@ -31,7 +22,7 @@ npm run build To install on Edge, use the "three dots" menu in the top-right corner of the browser to find the Extensions panel. If not already enabled, turn on Developer Mode (bottom left). Select "Load unpacked" to load a new extension. Open the "dist" folder when prompted, and the extension will be loaded. To use it, you will need an API key for the CO2 Signal API (you can [get one here via email](https://www.co2signal.com/) - enter your email in the box on this page) and the [code for your region](http://api.electricitymap.org/v3/zones) corresponding to the [electricity map](https://www.electricitymap.org/map) (for example, in Boston, "US-NEISO"). -![installation](../../../../../translated_images/en/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.png) +![installation](../../../../../translated_images/en/install-on-edge.78634f02842c4828.webp) Once the API key and region are entered in the extension interface, the colored dot in the browser's extension bar should change to reflect your region's energy usage and provide a pointer on which high-energy activities would be appropriate to perform. The concept behind this "dot" system was inspired by the [Energy Lollipop extension](https://energylollipop.com/) for California emissions. diff --git a/translations/en/5-browser-extension/solution/translation/README.ja.md b/translations/en/5-browser-extension/solution/translation/README.ja.md index d1544e973..23c1e1c80 100644 --- a/translations/en/5-browser-extension/solution/translation/README.ja.md +++ b/translations/en/5-browser-extension/solution/translation/README.ja.md @@ -1,17 +1,8 @@ - # Carbon Trigger Browser Extension: Completed Code Using tmrow's CO2 Signal API, this browser extension tracks electricity usage in your area and displays it as a reminder directly in your browser. By using this extension on an ad hoc basis, you can make decisions about your activities based on this information. -![extension screenshot](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.png) +![extension screenshot](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp) ## Getting Started @@ -31,7 +22,7 @@ npm run build To install it on Edge, find the "Extensions" panel from the "three dots" menu in the top-right corner of the browser. From there, select "Load Unpacked" to load the new extension. When prompted, open the "dist" folder, and the extension will be loaded. To use it, you'll need an API key for the CO2 Signal API ([get one here via email](https://www.co2signal.com/) - enter your email in the box on this page) and the [code for your region](http://api.electricitymap.org/v3/zones) corresponding to the [Electricity Map](https://www.electricitymap.org/map) (for example, in Boston, you would use 'US-NEISO'). -![installing](../../../../../translated_images/en/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.png) +![installing](../../../../../translated_images/en/install-on-edge.78634f02842c4828.webp) Once you input the API key and region into the extension interface, the colored dot displayed in your browser's extension bar will change to reflect your area's energy usage. This helps indicate whether it's a good time to engage in activities that require energy. The concept for this "dot" system was inspired by the [Energy Lollipop extension](https://energylollipop.com/) for California emissions. diff --git a/translations/en/5-browser-extension/solution/translation/README.ms.md b/translations/en/5-browser-extension/solution/translation/README.ms.md index 4cab9010b..934bcbc7c 100644 --- a/translations/en/5-browser-extension/solution/translation/README.ms.md +++ b/translations/en/5-browser-extension/solution/translation/README.ms.md @@ -1,17 +1,8 @@ - # Carbon Trigger Browser Extension: Complete Code Using the CO2 Signal API from tmrow to monitor electricity usage, build a browser extension that alerts you in your browser about the intensity of electricity consumption in your region. This extension can help you make informed decisions about your activities based on this information. -![browser extension screenshot](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.png) +![browser extension screenshot](../../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp) ## Getting Started @@ -31,7 +22,7 @@ npm run build To install it on Edge, use the 'three dots' menu in the top-right corner of the browser to find the Extensions panel. From there, select 'Load Unpacked' to load a new extension. Open the 'dist' folder when prompted, and the extension will be loaded. To use it, you’ll need an API key for the CO2 Signal API ([get one here via email](https://www.co2signal.com/) - enter your email in the box on this page) and [the code for your region](http://api.electricitymap.org/v3/zones) corresponding to the [Electricity Map](https://www.electricitymap.org/map) (in Boston, for example, I use 'US-NEISO'). -![downloading](../../../../../translated_images/en/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.png) +![downloading](../../../../../translated_images/en/install-on-edge.78634f02842c4828.webp) Once the API key and region are entered into the extension interface, the colored dot in the browser extension bar will change to reflect your region's energy usage and provide guidance on heavy activities that are appropriate for you to undertake. The concept behind this 'dot' system was inspired by [the Energy Lollipop browser extension](https://energylollipop.com/) for California emissions. diff --git a/translations/en/5-browser-extension/start/README.md b/translations/en/5-browser-extension/start/README.md index 63eeb8a42..00bb41c4a 100644 --- a/translations/en/5-browser-extension/start/README.md +++ b/translations/en/5-browser-extension/start/README.md @@ -1,17 +1,8 @@ - # Carbon Trigger Browser Extension: Starter Code Using tmrow's CO2 Signal API to monitor electricity usage, create a browser extension that provides a reminder directly in your browser about the intensity of electricity usage in your region. Using this extension on the fly can help you make informed decisions about your activities based on this data. -![extension screenshot](../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3875e1bc9405edd45a3d2e02963e48900adb91926a62a5807.png) +![extension screenshot](../../../../translated_images/en/extension-screenshot.0e7f5bfa110e92e3.webp) ## Getting Started @@ -31,7 +22,7 @@ npm run build To install on Edge, open the 'three dot' menu in the top right corner of the browser to access the Extensions panel. From there, select 'Load Unpacked' to add a new extension. When prompted, open the 'dist' folder, and the extension will load. To use it, you’ll need an API key for CO2 Signal's API ([request one here via email](https://www.co2signal.com/) - enter your email in the box on this page) and the [region code](http://api.electricitymap.org/v3/zones) corresponding to the [Electricity Map](https://www.electricitymap.org/map) (for example, in Boston, I use 'US-NEISO'). -![installing](../../../../translated_images/en/install-on-edge.78634f02842c48283726c531998679a6f03a45556b2ee99d8ff231fe41446324.png) +![installing](../../../../translated_images/en/install-on-edge.78634f02842c4828.webp) Once you input the API key and region into the extension interface, the colored dot in the browser extension bar will update to reflect your region's energy usage. It will also provide guidance on which energy-intensive activities might be suitable for you to undertake. The idea for this 'dot' system was inspired by the [Energy Lollipop extension](https://energylollipop.com/) for California emissions. diff --git a/translations/en/6-space-game/1-introduction/README.md b/translations/en/6-space-game/1-introduction/README.md index 54e75fdc2..e965583f8 100644 --- a/translations/en/6-space-game/1-introduction/README.md +++ b/translations/en/6-space-game/1-introduction/README.md @@ -1,50 +1,133 @@ - # Build a Space Game Part 1: Introduction -![video](../../../../6-space-game/images/pewpew.gif) - +```mermaid +journey + title Your Game Development Journey + section Foundation + Learn game architecture: 3: Student + Understand inheritance: 4: Student + Explore composition: 4: Student + section Communication + Build pub/sub system: 4: Student + Design event flow: 5: Student + Connect components: 5: Student + section Application + Create game objects: 5: Student + Implement patterns: 5: Student + Plan game structure: 5: Student +``` +![Space game animation showing gameplay](../../../../6-space-game/images/pewpew.gif) + +Just like NASA's mission control coordinates multiple systems during a space launch, we're going to build a space game that demonstrates how different parts of a program can work together seamlessly. While creating something you can actually play, you'll learn essential programming concepts that apply to any software project. + +We'll explore two fundamental approaches to organizing code: inheritance and composition. These aren't just academic concepts – they're the same patterns that power everything from video games to banking systems. We'll also implement a communication system called pub/sub that works like the communication networks used in spacecraft, allowing different components to share information without creating dependencies. + +By the end of this series, you'll understand how to build applications that can scale and evolve – whether you're developing games, web applications, or any other software system. + +```mermaid +mindmap + root((Game Architecture)) + Object Organization + Inheritance + Composition + Class Hierarchies + Behavior Mixing + Communication Patterns + Pub/Sub System + Event Emitters + Message Passing + Loose Coupling + Game Objects + Properties (x, y) + Behaviors (move, collide) + Lifecycle Management + State Management + Design Patterns + Factory Functions + Observer Pattern + Component System + Event-Driven Architecture + Scalability + Modular Design + Maintainable Code + Testing Strategies + Performance Optimization +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/29) -### Inheritance and Composition in game development +## Inheritance and Composition in Game Development -In earlier lessons, you didn’t need to worry much about the design architecture of the apps you built, as the projects were small in scope. However, as your applications grow in size and complexity, architectural decisions become more important. There are two major approaches to building larger applications in JavaScript: *composition* and *inheritance*. Both have their advantages and disadvantages, but let’s explore them in the context of a game. +As projects grow in complexity, code organization becomes critical. What begins as a simple script can become difficult to maintain without proper structure – much like how the Apollo missions required careful coordination between thousands of components. -✅ One of the most famous programming books ever written is about [design patterns](https://en.wikipedia.org/wiki/Design_Patterns). +We'll explore two fundamental approaches for organizing code: inheritance and composition. Each has distinct advantages, and understanding both helps you choose the right approach for different situations. We'll demonstrate these concepts through our space game, where heroes, enemies, power-ups, and other objects must interact efficiently. -In a game, you have `game objects`, which are objects that exist on the screen. This means they have a location on a Cartesian coordinate system, defined by `x` and `y` coordinates. As you develop a game, you’ll notice that all your game objects share some standard properties, common to every game you create. These include: +✅ One of the most famous programming books ever written has to do with [design patterns](https://en.wikipedia.org/wiki/Design_Patterns). -- **location-based**: Most, if not all, game elements are location-based. This means they have an `x` and `y` coordinate. -- **movable**: These are objects that can move to a new location. Typically, this includes heroes, monsters, or NPCs (non-player characters), but not static objects like trees. -- **self-destructing**: These objects exist for a limited time before marking themselves for deletion. This is often represented by a `dead` or `destroyed` boolean that signals to the game engine that the object should no longer be rendered. -- **cool-down**: 'Cool-down' is a common property for short-lived objects. For example, a piece of text or a graphical effect like an explosion that should only appear for a few milliseconds. +In any game, you have `game objects` – the interactive elements that populate your game world. Heroes, enemies, power-ups, and visual effects are all game objects. Each exists at specific screen coordinates using `x` and `y` values, similar to plotting points on a coordinate plane. + +Despite their visual differences, these objects often share fundamental behaviors: + +- **They exist somewhere** – Every object has x and y coordinates so the game knows where to draw it +- **Many can move around** – Heroes run, enemies chase, bullets fly across the screen +- **They have a lifespan** – Some stick around forever, others (like explosions) appear briefly and vanish +- **They react to stuff** – When things collide, power-ups get collected, health bars update ✅ Think about a game like Pac-Man. Can you identify the four object types listed above in this game? -### Expressing behavior +```mermaid +classDiagram + class GameObject { + +x: number + +y: number + +type: string + +exists_somewhere() + } + + class MovableObject { + +moveTo(x, y) + +can_move_around() + } + + class TemporaryObject { + +lifespan: number + +has_lifespan() + } + + class InteractiveObject { + +onCollision() + +reacts_to_stuff() + } + + GameObject <|-- MovableObject + GameObject <|-- TemporaryObject + GameObject <|-- InteractiveObject + + MovableObject <|-- Hero + MovableObject <|-- Enemy + MovableObject <|-- Bullet + + TemporaryObject <|-- PowerUp + TemporaryObject <|-- Explosion + + InteractiveObject <|-- Collectible + InteractiveObject <|-- Obstacle +``` +### Expressing Behavior Through Code -The properties described above represent behaviors that game objects can have. So how do we encode these behaviors? We can express them as methods associated with either classes or objects. +Now that you understand the common behaviors game objects share, let's explore how to implement these behaviors in JavaScript. You can express object behavior through methods attached to either classes or individual objects, and there are several approaches to choose from. -**Classes** +**The Class-Based Approach** -One approach is to use `classes` along with `inheritance` to add specific behaviors to a class. +Classes and inheritance provide a structured approach to organizing game objects. Like the taxonomic classification system developed by Carl Linnaeus, you start with a base class containing common properties, then create specialized classes that inherit these fundamentals while adding specific capabilities. -✅ Inheritance is an important concept to understand. Learn more in [MDN's article about inheritance](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). +✅ Inheritance is an important concept to understand. Learn more on [MDN's article about inheritance](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). -In code, a game object might look like this: +Here's how you can implement game objects using classes and inheritance: ```javascript - -//set up the class GameObject +// Step 1: Create the base GameObject class class GameObject { constructor(x, y, type) { this.x = x; @@ -52,173 +135,390 @@ class GameObject { this.type = type; } } +``` + +**Let's break this down step by step:** +- We're creating a basic template that every game object can use +- The constructor saves where the object is (`x`, `y`) and what kind of thing it is +- This becomes the foundation that all your game objects will build on -//this class will extend the GameObject's inherent class properties +```javascript +// Step 2: Add movement capability through inheritance class Movable extends GameObject { - constructor(x,y, type) { - super(x,y, type) + constructor(x, y, type) { + super(x, y, type); // Call parent constructor } -//this movable object can be moved on the screen + // Add the ability to move to a new position moveTo(x, y) { this.x = x; this.y = y; } } +``` + +**In the above, we've:** +- **Extended** the GameObject class to add movement functionality +- **Called** the parent constructor using `super()` to initialize inherited properties +- **Added** a `moveTo()` method that updates the object's position -//this is a specific class that extends the Movable class, so it can take advantage of all the properties that it inherits +```javascript +// Step 3: Create specific game object types class Hero extends Movable { - constructor(x,y) { - super(x,y, 'Hero') + constructor(x, y) { + super(x, y, 'Hero'); // Set type automatically } } -//this class, on the other hand, only inherits the GameObject properties class Tree extends GameObject { - constructor(x,y) { - super(x,y, 'Tree') + constructor(x, y) { + super(x, y, 'Tree'); // Trees don't need movement } } -//a hero can move... -const hero = new Hero(); -hero.moveTo(5,5); +// Step 4: Use your game objects +const hero = new Hero(0, 0); +hero.moveTo(5, 5); // Hero can move! -//but a tree cannot -const tree = new Tree(); +const tree = new Tree(10, 15); +// tree.moveTo() would cause an error - trees can't move ``` -✅ Take a few minutes to imagine how a Pac-Man character (like Inky, Pinky, or Blinky) could be written in JavaScript. +**Understanding these concepts:** +- **Creates** specialized object types that inherit appropriate behaviors +- **Demonstrates** how inheritance allows selective feature inclusion +- **Shows** that heroes can move while trees remain stationary +- **Illustrates** how the class hierarchy prevents inappropriate actions + +✅ Take a few minutes to re-envision a Pac-Man hero (Inky, Pinky or Blinky, for example) and how it would be written in JavaScript. -**Composition** +**The Composition Approach** -Another way to handle object inheritance is through *Composition*. In this approach, objects express their behavior like this: +Composition follows a modular design philosophy, similar to how engineers design spacecraft with interchangeable components. Instead of inheriting from a parent class, you combine specific behaviors to create objects with exactly the functionality they need. This approach offers flexibility without rigid hierarchical constraints. ```javascript -//create a constant gameObject +// Step 1: Create base behavior objects const gameObject = { x: 0, y: 0, type: '' }; -//...and a constant movable const movable = { moveTo(x, y) { this.x = x; this.y = y; } -} -//then the constant movableObject is composed of the gameObject and movable constants -const movableObject = {...gameObject, ...movable}; +}; +``` -//then create a function to create a new Hero who inherits the movableObject properties +**Here's what this code does:** +- **Defines** a base `gameObject` with position and type properties +- **Creates** a separate `movable` behavior object with movement functionality +- **Separates** concerns by keeping position data and movement logic independent + +```javascript +// Step 2: Compose objects by combining behaviors +const movableObject = { ...gameObject, ...movable }; + +// Step 3: Create factory functions for different object types function createHero(x, y) { return { ...movableObject, x, y, type: 'Hero' - } + }; } -//...and a static object that inherits only the gameObject properties + function createStatic(x, y, type) { return { - ...gameObject + ...gameObject, x, y, type - } + }; } -//create the hero and move it -const hero = createHero(10,10); -hero.moveTo(5,5); -//and create a static tree which only stands around -const tree = createStatic(0,0, 'Tree'); ``` -**Which pattern should I use?** +**In the above, we've:** +- **Combined** base object properties with movement behavior using spread syntax +- **Created** factory functions that return customized objects +- **Enabled** flexible object creation without rigid class hierarchies +- **Allowed** objects to have exactly the behaviors they need -The choice is yours. JavaScript supports both paradigms. +```javascript +// Step 4: Create and use your composed objects +const hero = createHero(10, 10); +hero.moveTo(5, 5); // Works perfectly! --- +const tree = createStatic(0, 0, 'Tree'); +// tree.moveTo() is undefined - no movement behavior was composed +``` -Another common pattern in game development addresses the challenge of managing the game’s user experience and performance. +**Key points to remember:** +- **Composes** objects by mixing behaviors rather than inheriting them +- **Provides** more flexibility than rigid inheritance hierarchies +- **Allows** objects to have exactly the features they need +- **Uses** modern JavaScript spread syntax for clean object combination +``` -## Pub/sub pattern +**Which Pattern Should You Choose?** + +**Which Pattern Should You Choose?** + +```mermaid +quadrantChart + title Code Organization Patterns + x-axis Simple --> Complex + y-axis Rigid --> Flexible + quadrant-1 Advanced Composition + quadrant-2 Hybrid Approaches + quadrant-3 Basic Inheritance + quadrant-4 Modern Composition + + Class Inheritance: [0.3, 0.2] + Interface Implementation: [0.6, 0.4] + Mixin Patterns: [0.7, 0.7] + Pure Composition: [0.8, 0.9] + Factory Functions: [0.5, 0.8] + Prototype Chain: [0.4, 0.3] +``` + +> 💡 **Pro Tip**: Both patterns have their place in modern JavaScript development. Classes work well for clearly defined hierarchies, while composition shines when you need maximum flexibility. +> +**Here's when to use each approach:** +- **Choose** inheritance when you have clear "is-a" relationships (a Hero *is-a* Movable object) +- **Select** composition when you need "has-a" relationships (a Hero *has* movement abilities) +- **Consider** your team's preferences and project requirements +- **Remember** that you can mix both approaches in the same application + +### 🔄 **Pedagogical Check-in** +**Object Organization Understanding**: Before moving to communication patterns, ensure you can: +- ✅ Explain the difference between inheritance and composition +- ✅ Identify when to use classes vs factory functions +- ✅ Understand how the `super()` keyword works in inheritance +- ✅ Recognize the benefits of each approach for game development + +**Quick Self-Test**: How would you create a Flying Enemy that can both move and fly? +- **Inheritance approach**: `class FlyingEnemy extends Movable` +- **Composition approach**: `{ ...movable, ...flyable, ...gameObject }` + +**Real-World Connection**: These patterns appear everywhere: +- **React Components**: Props (composition) vs class inheritance +- **Game Engines**: Entity-component systems use composition +- **Mobile Apps**: UI frameworks often use inheritance hierarchies + +## Communication Patterns: The Pub/Sub System + +As applications grow complex, managing communication between components becomes challenging. The publish-subscribe pattern (pub/sub) solves this problem using principles similar to radio broadcasting – one transmitter can reach multiple receivers without knowing who's listening. + +Consider what happens when a hero takes damage: the health bar updates, sound effects play, visual feedback appears. Rather than coupling the hero object directly to these systems, pub/sub allows the hero to broadcast a "damage taken" message. Any system that needs to respond can subscribe to this message type and react accordingly. + +✅ **Pub/Sub** stands for 'publish-subscribe' + +```mermaid +flowchart TD + A[Hero Takes Damage] --> B[Publish: HERO_DAMAGED] + B --> C[Event System] + + C --> D[Health Bar Subscriber] + C --> E[Sound System Subscriber] + C --> F[Visual Effects Subscriber] + C --> G[Achievement System Subscriber] + + D --> H[Update Health Display] + E --> I[Play Damage Sound] + F --> J[Show Red Flash] + G --> K[Check Survival Achievements] + + style A fill:#ffebee + style B fill:#e1f5fe + style C fill:#e8f5e8 + style H fill:#fff3e0 + style I fill:#fff3e0 + style J fill:#fff3e0 + style K fill:#fff3e0 +``` +### Understanding the Pub/Sub Architecture -✅ Pub/Sub stands for 'publish-subscribe' +The pub/sub pattern keeps different parts of your application loosely coupled, meaning they can work together without being directly dependent on each other. This separation makes your code more maintainable, testable, and flexible to changes. -This pattern is based on the idea that different parts of your application shouldn’t need to know about each other. Why is this important? It makes it easier to understand the overall system and simplifies making changes to behavior when needed. Here’s how it works: +**The key players in pub/sub:** +- **Messages** – Simple text labels like `'PLAYER_SCORED'` that describe what happened (plus any extra info) +- **Publishers** – The objects that shout out "Something happened!" to anyone who's listening +- **Subscribers** – The objects that say "I care about that event" and react when it happens +- **Event System** – The middleman that makes sure messages get to the right listeners -- **message**: A message is typically a text string, sometimes accompanied by an optional payload (data that provides additional context about the message). For example, a common message in a game might be `KEY_PRESSED_ENTER`. -- **publisher**: This component *publishes* a message and sends it to all subscribers. -- **subscriber**: This component *listens* for specific messages and performs a task in response, such as firing a laser. +### Building an Event System -The implementation is relatively small but incredibly powerful. Here’s an example: +Let's create a simple but powerful event system that demonstrates these concepts: ```javascript -//set up an EventEmitter class that contains listeners +// Step 1: Create the EventEmitter class class EventEmitter { constructor() { - this.listeners = {}; + this.listeners = {}; // Store all event listeners } -//when a message is received, let the listener to handle its payload + + // Register a listener for a specific message type on(message, listener) { if (!this.listeners[message]) { this.listeners[message] = []; } this.listeners[message].push(listener); } -//when a message is sent, send it to a listener with some payload + + // Send a message to all registered listeners emit(message, payload = null) { if (this.listeners[message]) { - this.listeners[message].forEach(l => l(message, payload)) + this.listeners[message].forEach(listener => { + listener(message, payload); + }); } } } - ``` -To use the code above, we can create a simple implementation: +**Breaking down what happens here:** +- **Creates** a central event management system using a simple class +- **Stores** listeners in an object organized by message type +- **Registers** new listeners using the `on()` method +- **Broadcasts** messages to all interested listeners using `emit()` +- **Supports** optional data payloads for passing relevant information + +### Putting It All Together: A Practical Example + +Alright, let's see this in action! We'll build a simple movement system that shows how clean and flexible pub/sub can be: ```javascript -//set up a message structure +// Step 1: Define your message types const Messages = { - HERO_MOVE_LEFT: 'HERO_MOVE_LEFT' + HERO_MOVE_LEFT: 'HERO_MOVE_LEFT', + HERO_MOVE_RIGHT: 'HERO_MOVE_RIGHT', + ENEMY_SPOTTED: 'ENEMY_SPOTTED' }; -//invoke the eventEmitter you set up above + +// Step 2: Create your event system and game objects const eventEmitter = new EventEmitter(); -//set up a hero -const hero = createHero(0,0); -//let the eventEmitter know to watch for messages pertaining to the hero moving left, and act on it +const hero = createHero(0, 0); +``` + +**Here's what this code does:** +- **Defines** a constants object to prevent typos in message names +- **Creates** an event emitter instance to handle all communication +- **Initializes** a hero object at the starting position + +```javascript +// Step 3: Set up event listeners (subscribers) eventEmitter.on(Messages.HERO_MOVE_LEFT, () => { - hero.move(5,0); + hero.moveTo(hero.x - 5, hero.y); + console.log(`Hero moved to position: ${hero.x}, ${hero.y}`); }); -//set up the window to listen for the keyup event, specifically if the left arrow is hit, emit a message to move the hero left -window.addEventListener('keyup', (evt) => { - if (evt.key === 'ArrowLeft') { - eventEmitter.emit(Messages.HERO_MOVE_LEFT) - } +eventEmitter.on(Messages.HERO_MOVE_RIGHT, () => { + hero.moveTo(hero.x + 5, hero.y); + console.log(`Hero moved to position: ${hero.x}, ${hero.y}`); }); ``` -In this example, we connect a keyboard event, `ArrowLeft`, to send the `HERO_MOVE_LEFT` message. We then listen for that message and move the `hero` accordingly. The strength of this pattern lies in the fact that the event listener and the hero don’t need to know about each other. You could remap `ArrowLeft` to the `A` key, or even assign a completely different action to `ArrowLeft` by making a few changes to the eventEmitter’s `on` function: +**In the above, we've:** +- **Registered** event listeners that respond to movement messages +- **Updated** the hero's position based on the movement direction +- **Added** console logging to track the hero's position changes +- **Separated** the movement logic from the input handling ```javascript -eventEmitter.on(Messages.HERO_MOVE_LEFT, () => { - hero.move(5,0); +// Step 4: Connect keyboard input to events (publishers) +window.addEventListener('keydown', (event) => { + switch(event.key) { + case 'ArrowLeft': + eventEmitter.emit(Messages.HERO_MOVE_LEFT); + break; + case 'ArrowRight': + eventEmitter.emit(Messages.HERO_MOVE_RIGHT); + break; + } }); ``` -As your game grows in complexity, this pattern remains consistent, keeping your code clean and manageable. It’s highly recommended to adopt this approach. +**Understanding these concepts:** +- **Connects** keyboard input to game events without tight coupling +- **Enables** the input system to communicate with game objects indirectly +- **Allows** multiple systems to respond to the same keyboard events +- **Makes** it easy to change key bindings or add new input methods + +```mermaid +sequenceDiagram + participant User + participant Keyboard + participant EventEmitter + participant Hero + participant SoundSystem + participant Camera + + User->>Keyboard: Presses ArrowLeft + Keyboard->>EventEmitter: emit('HERO_MOVE_LEFT') + EventEmitter->>Hero: Move left 5 pixels + EventEmitter->>SoundSystem: Play footstep sound + EventEmitter->>Camera: Follow hero + + Hero->>Hero: Update position + SoundSystem->>SoundSystem: Play audio + Camera->>Camera: Adjust viewport +``` +> 💡 **Pro Tip**: The beauty of this pattern is flexibility! You can easily add sound effects, screen shake, or particle effects by simply adding more event listeners – no need to modify the existing keyboard or movement code. +> +**Here's why you'll love this approach:** +- Adding new features becomes super easy – just listen for the events you care about +- Multiple things can react to the same event without stepping on each other +- Testing gets way simpler because each piece works independently +- When something breaks, you know exactly where to look + +### Why Pub/Sub Scales Effectively + +The pub/sub pattern maintains simplicity as applications grow in complexity. Whether managing dozens of enemies, dynamic UI updates, or sound systems, the pattern handles increased scale without architectural changes. New features integrate into the existing event system without affecting established functionality. + +> ⚠️ **Common Mistake**: Don't create too many specific message types early on. Start with broad categories and refine them as your game's needs become clearer. +> +**Best practices to follow:** +- **Groups** related messages into logical categories +- **Uses** descriptive names that clearly indicate what happened +- **Keeps** message payloads simple and focused +- **Documents** your message types for team collaboration + +### 🔄 **Pedagogical Check-in** +**Event-Driven Architecture Understanding**: Verify your grasp of the complete system: +- ✅ How does the pub/sub pattern prevent tight coupling between components? +- ✅ Why is it easier to add new features with event-driven architecture? +- ✅ What role does the EventEmitter play in the communication flow? +- ✅ How do message constants prevent bugs and improve maintainability? + +**Design Challenge**: How would you handle these game scenarios with pub/sub? +1. **Enemy dies**: Update score, play sound, spawn power-up, remove from screen +2. **Level complete**: Stop music, show UI, save progress, load next level +3. **Power-up collected**: Enhance abilities, update UI, play effect, start timer + +**Professional Connection**: This pattern appears in: +- **Frontend Frameworks**: React/Vue event systems +- **Backend Services**: Microservice communication +- **Game Engines**: Unity's event system +- **Mobile Development**: iOS/Android notification systems --- -## 🚀 Challenge +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: -Think about how the pub-sub pattern could improve a game. Which parts of the game should emit events, and how should the game respond to them? Use your creativity to imagine a new game and how its components might interact. +**Description:** Create a simple game object system using both inheritance and the pub/sub pattern. You'll implement a basic game where different objects can communicate through events without directly knowing about each other. + +**Prompt:** Create a JavaScript game system with the following requirements: 1) Create a base GameObject class with x, y coordinates and a type property. 2) Create a Hero class that extends GameObject and can move. 3) Create an Enemy class that extends GameObject and can chase the hero. 4) Implement an EventEmitter class for the pub/sub pattern. 5) Set up event listeners so when the hero moves, nearby enemies receive a 'HERO_MOVED' event and update their position to move toward the hero. Include console.log statements to show the communication between objects. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + +## 🚀 Challenge +Consider how the pub-sub pattern can enhance game architecture. Identify which components should emit events and how the system should respond. Design a game concept and map out the communication patterns between its components. ## Post-Lecture Quiz @@ -228,11 +528,126 @@ Think about how the pub-sub pattern could improve a game. Which parts of the gam Learn more about Pub/Sub by [reading about it](https://docs.microsoft.com/azure/architecture/patterns/publisher-subscriber/?WT.mc_id=academic-77807-sagibbon). +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open any HTML5 game online and inspect its code using DevTools +- [ ] Create a simple HTML5 Canvas element and draw a basic shape +- [ ] Try using `setInterval` to create a simple animation loop +- [ ] Explore the Canvas API documentation and try a drawing method + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and understand game development concepts +- [ ] Set up your game project structure with HTML, CSS, and JavaScript files +- [ ] Create a basic game loop that updates and renders continuously +- [ ] Draw your first game sprites on the canvas +- [ ] Implement basic asset loading for images and sounds + +### 📅 **Your Week-Long Game Creation** +- [ ] Complete the full space game with all planned features +- [ ] Add polished graphics, sound effects, and smooth animations +- [ ] Implement game states (start screen, gameplay, game over) +- [ ] Create a scoring system and player progress tracking +- [ ] Make your game responsive and accessible across devices +- [ ] Share your game online and gather feedback from players + +### 🌟 **Your Month-Long Game Development** +- [ ] Build multiple games exploring different genres and mechanics +- [ ] Learn a game development framework like Phaser or Three.js +- [ ] Contribute to open source game development projects +- [ ] Master advanced game programming patterns and optimization +- [ ] Create a portfolio showcasing your game development skills +- [ ] Mentor others interested in game development and interactive media + +## 🎯 Your Game Development Mastery Timeline + +```mermaid +timeline + title Game Architecture Learning Progression + + section Object Patterns (20 minutes) + Code Organization: Class inheritance + : Composition patterns + : Factory functions + : Behavior mixing + + section Communication Systems (25 minutes) + Event Architecture: Pub/Sub implementation + : Message design + : Event emitters + : Loose coupling + + section Game Object Design (30 minutes) + Entity Systems: Property management + : Behavior composition + : State handling + : Lifecycle management + + section Architecture Patterns (35 minutes) + System Design: Component systems + : Observer pattern + : Command pattern + : State machines + + section Advanced Concepts (45 minutes) + Scalable Architecture: Performance optimization + : Memory management + : Modular design + : Testing strategies + + section Game Engine Concepts (1 week) + Professional Development: Scene graphs + : Asset management + : Rendering pipelines + : Physics integration + + section Framework Mastery (2 weeks) + Modern Game Development: React game patterns + : Canvas optimization + : WebGL basics + : PWA games + + section Industry Practices (1 month) + Professional Skills: Team collaboration + : Code reviews + : Game design patterns + : Performance profiling +``` +### 🛠️ Your Game Architecture Toolkit Summary + +After completing this lesson, you now have: +- **Design Pattern Mastery**: Understanding of inheritance vs composition trade-offs +- **Event-Driven Architecture**: Pub/sub implementation for scalable communication +- **Object-Oriented Design**: Class hierarchies and behavior composition +- **Modern JavaScript**: Factory functions, spread syntax, and ES6+ patterns +- **Scalable Architecture**: Loose coupling and modular design principles +- **Game Development Foundation**: Entity systems and component patterns +- **Professional Patterns**: Industry-standard approaches to code organization + +**Real-World Applications**: These patterns directly apply to: +- **Frontend Frameworks**: React/Vue component architecture and state management +- **Backend Services**: Microservice communication and event-driven systems +- **Mobile Development**: iOS/Android app architecture and notification systems +- **Game Engines**: Unity, Unreal, and web-based game development +- **Enterprise Software**: Event sourcing and distributed system design +- **API Design**: RESTful services and real-time communication + +**Professional Skills Gained**: You can now: +- **Design** scalable software architectures using proven patterns +- **Implement** event-driven systems that handle complex interactions +- **Choose** appropriate code organization strategies for different scenarios +- **Debug** and maintain loosely coupled systems effectively +- **Communicate** technical decisions using industry-standard terminology + +**Next Level**: You're ready to implement these patterns in a real game, explore advanced game development topics, or apply these architectural concepts to web applications! + +🌟 **Achievement Unlocked**: You've mastered fundamental software architecture patterns that power everything from simple games to complex enterprise systems! + ## Assignment [Mock up a game](assignment.md) --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/1-introduction/assignment.md b/translations/en/6-space-game/1-introduction/assignment.md index e298b1861..c9a975e41 100644 --- a/translations/en/6-space-game/1-introduction/assignment.md +++ b/translations/en/6-space-game/1-introduction/assignment.md @@ -1,25 +1,93 @@ - -# Mock up a game +# Mock up a Game: Apply Design Patterns + +## Assignment Overview + +Put your newfound knowledge of design patterns to work by creating a simple game prototype! This assignment will help you practice both architectural patterns (inheritance or composition) and the pub/sub communication system you learned about in the lesson. ## Instructions -Using the code examples from the lesson, create a representation of a game you enjoy. It should be a simple game, but the goal is to use either the class or composition pattern along with the pub/sub pattern to demonstrate how a game might start. Be creative! +Create a simple game representation that demonstrates the design patterns from this lesson. Your game should be functional but doesn't need complex graphics – focus on the underlying architecture and communication patterns. + +### Requirements + +**Choose Your Architecture Pattern:** +- **Option A**: Use class-based inheritance (like the `GameObject` → `Movable` → `Hero` example) +- **Option B**: Use composition (like the factory function approach with mixed behaviors) + +**Implement Communication:** +- **Include** an `EventEmitter` class for pub/sub messaging +- **Set up** at least 2-3 different message types (like `PLAYER_MOVE`, `ENEMY_SPAWN`, `SCORE_UPDATE`) +- **Connect** user input (keyboard/mouse) to game events through the event system + +**Game Elements to Include:** +- At least one player-controlled character +- At least one other game object (enemy, collectible, or environmental element) +- Basic interaction between objects (collision, collection, or communication) + +### Suggested Game Ideas + +**Simple Games to Consider:** +- **Snake Game** – Snake segments follow the head, food spawns randomly +- **Pong Variation** – Paddle responds to input, ball bounces off walls +- **Collector Game** – Player moves around collecting items while avoiding obstacles +- **Tower Defense Basics** – Towers detect and shoot at moving enemies + +### Code Structure Guidelines + +```javascript +// Example starting structure +const Messages = { + // Define your game messages here +}; + +class EventEmitter { + // Your event system implementation +} + +// Choose either class-based OR composition approach +// Class-based example: +class GameObject { /* base properties */ } +class Player extends GameObject { /* player-specific behavior */ } + +// OR Composition example: +const gameObject = { /* base properties */ }; +const movable = { /* movement behavior */ }; +function createPlayer() { /* combine behaviors */ } +``` + +### Testing Your Implementation + +**Verify your code works by:** +- **Testing** that objects move or change when events are triggered +- **Confirming** that multiple objects can respond to the same event +- **Checking** that you can add new behaviors without modifying existing code +- **Ensuring** keyboard/mouse input properly triggers game events + +## Submission Guidelines + +**Your submission should include:** +1. **JavaScript file(s)** with your game implementation +2. **HTML file** to run and test your game (can be simple) +3. **Comments** explaining which pattern you chose and why +4. **Brief documentation** of your message types and what they do ## Rubric -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | ------------------------------------------------------- | ----------------------------------------------------- | --------------------------------------------------- | -| | Three elements are displayed on the screen and interact | Two elements are displayed on the screen and interact | One element is displayed on the screen and interacts | +| Criteria | Exemplary (3 points) | Adequate (2 points) | Needs Improvement (1 point) | +|----------|---------------------|---------------------|------------------------------| +| **Architecture Pattern** | Correctly implements either inheritance OR composition with clear class/object hierarchy | Uses chosen pattern with minor issues or inconsistencies | Attempts to use pattern but implementation has significant problems | +| **Pub/Sub Implementation** | EventEmitter works correctly with multiple message types and proper event flow | Basic pub/sub system works with some event handling | Event system present but doesn't work reliably | +| **Game Functionality** | Three or more interactive elements that communicate through events | Two interactive elements with basic event communication | One element responds to events or basic interaction | +| **Code Quality** | Clean, well-commented code with logical organization and modern JavaScript | Generally well-organized code with adequate comments | Code works but lacks organization or clear commenting | + +**Bonus Points:** +- **Creative game mechanics** that showcase interesting uses of the patterns +- **Multiple input methods** (keyboard AND mouse events) +- **Scalable architecture** that would be easy to extend with new features --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/2-drawing-to-canvas/README.md b/translations/en/6-space-game/2-drawing-to-canvas/README.md index d8b0d81d8..123ec4870 100644 --- a/translations/en/6-space-game/2-drawing-to-canvas/README.md +++ b/translations/en/6-space-game/2-drawing-to-canvas/README.md @@ -1,216 +1,480 @@ - # Build a Space Game Part 2: Draw Hero and Monsters to Canvas +```mermaid +journey + title Your Canvas Graphics Journey + section Foundation + Understand Canvas API: 3: Student + Learn coordinate system: 4: Student + Draw basic shapes: 4: Student + section Image Handling + Load game assets: 4: Student + Handle async loading: 5: Student + Position sprites: 5: Student + section Game Rendering + Create game screen: 5: Student + Build formations: 5: Student + Optimize performance: 4: Student +``` +The Canvas API is one of web development's most powerful features for creating dynamic, interactive graphics right in your browser. In this lesson, we'll transform that blank HTML `` element into a game world filled with heroes and monsters. Think of the canvas as your digital art board where code becomes visual. + +We're building on what you learned in the previous lesson, and now we'll dive into the visual aspects. You'll learn how to load and display game sprites, position elements precisely, and create the visual foundation for your space game. This bridges the gap between static web pages and dynamic, interactive experiences. + +By the end of this lesson, you'll have a complete game scene with your hero ship positioned correctly and enemy formations ready for battle. You'll understand how modern games render graphics in browsers and gain skills to create your own interactive visual experiences. Let's explore canvas graphics and bring your space game to life! + +```mermaid +mindmap + root((Canvas Graphics)) + Canvas Element + HTML5 Feature + 2D Context + Coordinate System + Pixel Control + Drawing Operations + Basic Shapes + Text Rendering + Image Display + Path Drawing + Asset Management + Image Loading + Async Operations + Error Handling + Performance + Game Rendering + Sprite Positioning + Formation Layout + Scene Composition + Frame Updates + Visual Effects + Colors & Styles + Transformations + Animations + Layering +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/31) ## The Canvas -The canvas is an HTML element that starts off empty; it's like a blank sheet of paper. You can add content to it by drawing on it. +So what exactly is this `` element? It's HTML5's solution for creating dynamic graphics and animations in web browsers. Unlike regular images or videos that are static, the canvas gives you pixel-level control over everything that appears on screen. This makes it perfect for games, data visualizations, and interactive art. Think of it as a programmable drawing surface where JavaScript becomes your paintbrush. + +By default, a canvas element looks like a blank, transparent rectangle on your page. But that's where the potential lies! Its real power emerges when you use JavaScript to draw shapes, load images, create animations, and make things respond to user interactions. It's similar to how early computer graphics pioneers at Bell Labs in the 1960s had to program every pixel to create the first digital animations. ✅ Read [more about the Canvas API](https://developer.mozilla.org/docs/Web/API/Canvas_API) on MDN. -Here's how it's typically defined as part of the page's body: +Here's how it's typically declared, as part of the page's body: ```html ``` -In the code above, we are setting the `id`, `width`, and `height`. - -- `id`: This allows you to reference the canvas when you need to interact with it. -- `width`: This defines the width of the canvas. -- `height`: This defines the height of the canvas. - -## Drawing simple geometry - -The canvas uses a Cartesian coordinate system to draw shapes. This means it uses an x-axis and y-axis to determine where things are placed. The position `0,0` is the top-left corner, and the bottom-right corner corresponds to the `width` and `height` of the canvas. - -![the canvas's grid](../../../../translated_images/en/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.png) +**Here's what this code does:** +- **Sets** the `id` attribute so you can reference this specific canvas element in JavaScript +- **Defines** the `width` in pixels to control the canvas's horizontal size +- **Establishes** the `height` in pixels to determine the canvas's vertical dimensions + +## Drawing Simple Geometry + +Now that you know what the canvas element is, let's explore actually drawing on it! The canvas uses a coordinate system that might feel familiar from math class, but there's one important twist specific to computer graphics. + +The canvas uses Cartesian coordinates with an x-axis (horizontal) and y-axis (vertical) to position everything you draw. But here's the key difference: unlike the coordinate system from math class, the origin point `(0,0)` starts at the top-left corner, with x-values increasing as you move right and y-values increasing as you move down. This approach dates back to early computer displays where electron beams scanned from top to bottom, making top-left the natural starting point. + +```mermaid +quadrantChart + title Canvas Coordinate System + x-axis Left --> Right + y-axis Top --> Bottom + quadrant-1 Quadrant 1 + quadrant-2 Quadrant 2 + quadrant-3 Quadrant 3 + quadrant-4 Quadrant 4 + + Origin Point: [0.1, 0.1] + Hero Center: [0.5, 0.8] + Enemy Formation: [0.3, 0.2] + Power-up: [0.7, 0.6] + UI Elements: [0.9, 0.1] +``` +![the canvas's grid](../../../../translated_images/en/canvas_grid.5f209da785ded492.webp) > Image from [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) -To draw on the canvas, follow these steps: - -1. **Get a reference** to the canvas element. -2. **Get a reference** to the context object associated with the canvas. -3. **Perform a drawing operation** using the context object. +To draw on the canvas element, you'll follow the same three-step process that forms the foundation of all canvas graphics. Once you do this a few times, it becomes second nature: + +```mermaid +flowchart LR + A[HTML Canvas Element] --> B[Get Canvas Reference] + B --> C[Get 2D Context] + C --> D[Drawing Operations] + + D --> E[Draw Shapes] + D --> F[Draw Text] + D --> G[Draw Images] + D --> H[Apply Styles] + + E --> I[Render to Screen] + F --> I + G --> I + H --> I + + style A fill:#e1f5fe + style C fill:#e8f5e8 + style I fill:#fff3e0 +``` +1. **Get a reference** to your Canvas element from the DOM (just like any other HTML element) +2. **Get the 2D rendering context** – this provides all the drawing methods +3. **Start drawing!** Use the context's built-in methods to create your graphics -The code for these steps typically looks like this: +Here's how this looks in code: ```javascript -// draws a red rectangle -//1. get the canvas reference -canvas = document.getElementById("myCanvas"); +// Step 1: Get the canvas element +const canvas = document.getElementById("myCanvas"); -//2. set the context to 2D to draw basic shapes -ctx = canvas.getContext("2d"); +// Step 2: Get the 2D rendering context +const ctx = canvas.getContext("2d"); -//3. fill it with the color red +// Step 3: Set fill color and draw a rectangle ctx.fillStyle = 'red'; - -//4. and draw a rectangle with these parameters, setting location and size -ctx.fillRect(0,0, 200, 200) // x,y,width, height +ctx.fillRect(0, 0, 200, 200); // x, y, width, height ``` -✅ The Canvas API is primarily designed for 2D graphics, but you can also create 3D graphics on a webpage using the [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API). +**Let's break this down step by step:** +- We **grab** our canvas element using its ID and store it in a variable +- We **get** the 2D rendering context – this is our toolkit full of drawing methods +- We **tell** the canvas we want to fill things with red using the `fillStyle` property +- We **draw** a rectangle starting at the top-left corner (0,0) that's 200 pixels wide and tall -With the Canvas API, you can draw a variety of things, such as: +✅ The Canvas API mostly focuses on 2D shapes, but you can also draw 3D elements to a web site; for this, you might use the [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API). -- **Geometric shapes**: We've already shown how to draw a rectangle, but there are many other shapes you can create. -- **Text**: You can draw text in any font and color you like. -- **Images**: You can display images from assets like `.jpg` or `.png` files. +You can draw all sorts of things with the Canvas API like: -✅ Try it! Now that you know how to draw a rectangle, can you draw a circle on the page? Check out some creative Canvas drawings on CodePen. Here's a [particularly impressive example](https://codepen.io/dissimulate/pen/KrAwx). +- **Geometrical shapes**, we've already showed how to draw a rectangle, but there is much more you can draw. +- **Text**, you can draw a text with any font and color you wish. +- **Images**, you can draw an image based off of an image asset like a .jpg or .png for example. -## Load and draw an image asset +✅ Try it! You know how to draw a rectangle, can you draw a circle to a page? Take a look at some interesting Canvas drawings on CodePen. Here's a [particularly impressive example](https://codepen.io/dissimulate/pen/KrAwx). -To load an image asset, create an `Image` object and set its `src` property. Then, listen for the `load` event to know when the image is ready to use. The code looks like this: +### 🔄 **Pedagogical Check-in** +**Canvas Fundamentals Understanding**: Before moving to image loading, ensure you can: +- ✅ Explain how the canvas coordinate system differs from mathematical coordinates +- ✅ Understand the three-step process for canvas drawing operations +- ✅ Identify what the 2D rendering context provides +- ✅ Describe how fillStyle and fillRect work together -### Load asset +**Quick Self-Test**: How would you draw a blue circle at position (100, 50) with radius 25? +```javascript +ctx.fillStyle = 'blue'; +ctx.beginPath(); +ctx.arc(100, 50, 25, 0, 2 * Math.PI); +ctx.fill(); +``` + +**Canvas Drawing Methods You Now Know**: +- **fillRect()**: Draws filled rectangles +- **fillStyle**: Sets colors and patterns +- **beginPath()**: Starts new drawing paths +- **arc()**: Creates circles and curves + +## Load and Draw an Image Asset + +Drawing basic shapes is useful for getting started, but most games need actual images! Sprites, backgrounds, and textures are what give games their visual appeal. Loading and displaying images on the canvas works differently than drawing geometric shapes, but it's straightforward once you understand the process. + +We need to create an `Image` object, load our image file (this happens asynchronously, meaning "in the background"), and then draw it to the canvas once it's ready. This approach ensures your images display properly without blocking your application while they load. + +```mermaid +sequenceDiagram + participant JS as JavaScript + participant Img as Image Object + participant Server as File Server + participant Canvas as Canvas Context + + JS->>Img: new Image() + JS->>Img: Set src property + Img->>Server: Request image file + Server->>Img: Return image data + Img->>JS: Trigger onload event + JS->>Canvas: drawImage(img, x, y) + Canvas->>Canvas: Render to screen + + Note over JS,Canvas: Async loading prevents UI blocking +``` +### Basic Image Loading ```javascript const img = new Image(); img.src = 'path/to/my/image.png'; img.onload = () => { - // image loaded and ready to be used -} + // Imagen cargada y lista para ser usada + console.log('Image loaded successfully!'); +}; ``` -### Load asset pattern +**Here's what's happening in this code:** +- We **create** a brand new Image object to hold our sprite or texture +- We **tell** it which image file to load by setting the source path +- We **listen** for the load event so we know exactly when the image is ready to use + +### A Better Way to Load Images -It's a good idea to wrap the code above in a reusable structure, so you can easily use it and ensure the image is fully loaded before manipulating it: +Here's a more robust way to handle image loading that professional developers commonly use. We'll wrap the image loading in a Promise-based function – this approach, popularized when JavaScript Promises became standard in ES6, makes your code more organized and handles errors gracefully: ```javascript function loadAsset(path) { - return new Promise((resolve) => { + return new Promise((resolve, reject) => { const img = new Image(); img.src = path; img.onload = () => { - // image loaded and ready to be used resolve(img); - } - }) + }; + img.onerror = () => { + reject(new Error(`Failed to load image: ${path}`)); + }; + }); } -// use like so - -async function run() { - const heroImg = await loadAsset('hero.png') - const monsterImg = await loadAsset('monster.png') +// Modern usage with async/await +async function initializeGame() { + try { + const heroImg = await loadAsset('hero.png'); + const monsterImg = await loadAsset('monster.png'); + // Images are now ready to use + } catch (error) { + console.error('Failed to load game assets:', error); + } } - ``` -To draw game assets on the screen, your code might look like this: +**What we've done here:** +- **Wrapped** all that image loading logic in a Promise so we can handle it better +- **Added** error handling that actually tells us when something goes wrong +- **Used** modern async/await syntax because it's so much cleaner to read +- **Included** try/catch blocks to gracefully handle any loading hiccups + +Once your images are loaded, drawing them to the canvas is actually pretty straightforward: ```javascript -async function run() { - const heroImg = await loadAsset('hero.png') - const monsterImg = await loadAsset('monster.png') - - canvas = document.getElementById("myCanvas"); - ctx = canvas.getContext("2d"); - ctx.drawImage(heroImg, canvas.width/2,canvas.height/2); - ctx.drawImage(monsterImg, 0,0); +async function renderGameScreen() { + try { + // Load game assets + const heroImg = await loadAsset('hero.png'); + const monsterImg = await loadAsset('monster.png'); + + // Get canvas and context + const canvas = document.getElementById("myCanvas"); + const ctx = canvas.getContext("2d"); + + // Draw images to specific positions + ctx.drawImage(heroImg, canvas.width / 2, canvas.height / 2); + ctx.drawImage(monsterImg, 0, 0); + } catch (error) { + console.error('Failed to render game screen:', error); + } } ``` -## Now it's time to start building your game +**Let's walk through this step by step:** +- We **load** both our hero and monster images in the background using await +- We **grab** our canvas element and get that 2D rendering context we need +- We **position** the hero image right in the center using some quick coordinate math +- We **plop** the monster image at the top-left corner to start our enemy formation +- We **catch** any errors that might happen during loading or rendering + +```mermaid +flowchart TD + A[Load Assets] --> B{All Images Loaded?} + B -->|No| C[Show Loading] + B -->|Yes| D[Get Canvas Context] + C --> B + D --> E[Clear Screen] + E --> F[Draw Background] + F --> G[Draw Enemy Formation] + G --> H[Draw Hero Ship] + H --> I[Apply Visual Effects] + I --> J[Render Frame] + + subgraph "Rendering Pipeline" + K[Asset Management] + L[Scene Composition] + M[Drawing Operations] + N[Frame Output] + end + + style A fill:#e1f5fe + style J fill:#e8f5e8 + style I fill:#fff3e0 +``` +## Now It's Time to Start Building Your Game + +Now we'll put everything together to create the visual foundation of your space game. You have a solid understanding of canvas fundamentals and image loading techniques, so this hands-on section will guide you through building a complete game screen with properly positioned sprites. -### What to build +### What to Build -You will create a webpage with a canvas element. The canvas should display a black screen with dimensions `1024x768`. We've provided two images for you: +You will build a web page with a Canvas element. It should render a black screen `1024*768`. We've provided you with two images: -- Hero ship: +- Hero ship - ![Hero ship](../../../../translated_images/en/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.png) + ![Hero ship](../../../../translated_images/en/player.dd24c1afa8c71e9b.webp) -- 5x5 monster grid: +- 5*5 monster - ![Monster ship](../../../../translated_images/en/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.png) + ![Monster ship](../../../../translated_images/en/enemyShip.5df2a822c16650c2.webp) ### Recommended steps to start development -Locate the files provided in the `your-work` subfolder. It should contain the following: +Locate the starter files that have been created for you in the `your-work` sub folder. Your project structure should contain: ```bash --| assets - -| enemyShip.png - -| player.png --| index.html --| app.js --| package.json +your-work/ +├── assets/ +│ ├── enemyShip.png +│ └── player.png +├── index.html +├── app.js +└── package.json ``` -Open this folder in Visual Studio Code. Make sure you have a local development environment set up, preferably with Visual Studio Code, NPM, and Node installed. If you don't have `npm` installed, [here's how to set it up](https://www.npmjs.com/get-npm). +**Here's what you're working with:** +- **Game sprites** live in the `assets/` folder so everything stays organized +- **Your main HTML file** sets up the canvas element and gets everything ready +- **A JavaScript file** where you'll write all your game rendering magic +- **A package.json** that sets up a development server so you can test locally + +Open this folder in Visual Studio Code to begin development. You'll need a local development environment with Visual Studio Code, NPM, and Node.js installed. If you don't have `npm` set up on your computer, [here's how to install it](https://www.npmjs.com/get-npm). -Start your project by navigating to the `your_work` folder: +Start your development server by navigating to the `your-work` folder: ```bash cd your-work npm start ``` -This will start an HTTP server at `http://localhost:5000`. Open a browser and go to that address. The page will be blank for now, but that will change soon. +**This command does some pretty cool stuff:** +- **Starts up** a local server at `http://localhost:5000` so you can test your game +- **Serves** all your files properly so your browser can load them correctly +- **Watches** your files for changes so you can develop smoothly +- **Gives you** a professional development environment to test everything -> Note: To see updates on your screen, refresh your browser. +> 💡 **Note**: Your browser will show a blank page initially – that's expected! As you add code, refresh your browser to see your changes. This iterative development approach is similar to how NASA built the Apollo guidance computer – testing each component before integrating it into the larger system. ### Add code -Add the necessary code to `your-work/app.js` to complete the following tasks: +Add the required code to `your-work/app.js` to complete the following tasks: + +1. **Draw a canvas with black background** + > 💡 **Here's how**: Find the TODO in `/app.js` and add just two lines. Set `ctx.fillStyle` to black, then use `ctx.fillRect()` starting at (0,0) with your canvas dimensions. Easy! + +2. **Load game textures** + > 💡 **Here's how**: Use `await loadAsset()` to load your player and enemy images. Store them in variables so you can use them later. Remember – they won't show up until you actually draw them! -1. **Draw** a canvas with a black background. - > Tip: Add two lines of code under the appropriate TODO in `/app.js` to set the `ctx` element's background to black. Set the top-left coordinates to `0,0` and the height and width to match the canvas dimensions. -2. **Load** textures. - > Tip: Use `await loadTexture` to load the player and enemy images by passing their file paths. You won't see them on the screen just yet! -3. **Draw** the hero in the center of the screen, near the bottom. - > Tip: Use the `drawImage` API to draw `heroImg` on the screen. Set the coordinates to `canvas.width / 2 - 45` and `canvas.height - canvas.height / 4`. -4. **Draw** a 5x5 grid of monsters. - > Tip: Uncomment the code to draw enemies on the screen. Then, go to the `createEnemies` function and complete it. +3. **Draw hero ship in the center-bottom position** + > 💡 **Here's how**: Use `ctx.drawImage()` to position your hero. For the x-coordinate, try `canvas.width / 2 - 45` to center it, and for y-coordinate use `canvas.height - canvas.height / 4` to put it in the bottom area. - Start by defining some constants: +4. **Draw a 5×5 formation of enemy ships** + > 💡 **Here's how**: Find the `createEnemies` function and set up a nested loop. You'll need to do some math for spacing and positioning, but don't worry – I'll show you exactly how! - ```javascript - const MONSTER_TOTAL = 5; - const MONSTER_WIDTH = MONSTER_TOTAL * 98; - const START_X = (canvas.width - MONSTER_WIDTH) / 2; - const STOP_X = START_X + MONSTER_WIDTH; - ``` +First, establish constants for proper enemy formation layout: + +```javascript +const ENEMY_TOTAL = 5; +const ENEMY_SPACING = 98; +const FORMATION_WIDTH = ENEMY_TOTAL * ENEMY_SPACING; +const START_X = (canvas.width - FORMATION_WIDTH) / 2; +const STOP_X = START_X + FORMATION_WIDTH; +``` + +**Let's break down what these constants do:** +- We **set** 5 enemies per row and column (a nice 5×5 grid) +- We **define** how much space to put between enemies so they don't look cramped +- We **calculate** how wide our whole formation will be +- We **figure out** where to start and stop so the formation looks centered + +```mermaid +flowchart LR + A["Canvas Width: 1024px"] --> B["Formation Width: 490px"] + B --> C["Start X: 267px"] + C --> D["Enemy Spacing: 98px"] + + subgraph "5x5 Enemy Formation" + E["Row 1: Y=0"] + F["Row 2: Y=50"] + G["Row 3: Y=100"] + H["Row 4: Y=150"] + I["Row 5: Y=200"] + end + + subgraph "Column Spacing" + J["Col 1: X=267"] + K["Col 2: X=365"] + L["Col 3: X=463"] + M["Col 4: X=561"] + N["Col 5: X=659"] + end + + style A fill:#e1f5fe + style B fill:#e8f5e8 + style C fill:#fff3e0 +``` +Then, create nested loops to draw the enemy formation: - Next, create a loop to draw the array of monsters on the screen: +```javascript +for (let x = START_X; x < STOP_X; x += ENEMY_SPACING) { + for (let y = 0; y < 50 * 5; y += 50) { + ctx.drawImage(enemyImg, x, y); + } +} +``` - ```javascript - for (let x = START_X; x < STOP_X; x += 98) { - for (let y = 0; y < 50 * 5; y += 50) { - ctx.drawImage(enemyImg, x, y); - } - } - ``` +**Here's what this nested loop does:** +- The outer loop **moves** from left to right across our formation +- The inner loop **goes** from top to bottom to create neat rows +- We **draw** each enemy sprite at the exact x,y coordinates we calculated +- Everything stays **evenly spaced** so it looks professional and organized + +### 🔄 **Pedagogical Check-in** +**Game Rendering Mastery**: Verify your understanding of the complete rendering system: +- ✅ How does async image loading prevent UI blocking during game startup? +- ✅ Why do we calculate enemy formation positions using constants instead of hardcoding? +- ✅ What role does the 2D rendering context play in drawing operations? +- ✅ How do nested loops create organized sprite formations? + +**Performance Considerations**: Your game now demonstrates: +- **Efficient asset loading**: Promise-based image management +- **Organized rendering**: Structured drawing operations +- **Mathematical positioning**: Calculated sprite placement +- **Error handling**: Graceful failure management + +**Visual Programming Concepts**: You've learned: +- **Coordinate systems**: Translating math to screen positions +- **Sprite management**: Loading and displaying game graphics +- **Formation algorithms**: Mathematical patterns for organized layouts +- **Async operations**: Modern JavaScript for smooth user experience ## Result -The final result should look like this: +The finished result should look like so: -![Black screen with a hero and 5x5 monsters](../../../../translated_images/en/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.png) +![Black screen with a hero and 5*5 monsters](../../../../translated_images/en/partI-solution.36c53b48c9ffae2a.webp) ## Solution -Try solving this on your own first, but if you get stuck, you can check out the [solution](../../../../6-space-game/2-drawing-to-canvas/solution/app.js). +Please try solving it yourself first but if you get stuck, have a look at a [solution](../../../../6-space-game/2-drawing-to-canvas/solution/app.js) --- +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Enhance your space game canvas by adding visual effects and interactive elements using the Canvas API techniques you've learned. + +**Prompt:** Create a new file called `enhanced-canvas.html` with a canvas that displays animated stars in the background, a pulsing health bar for the hero ship, and enemy ships that slowly move downward. Include JavaScript code that draws twinkling stars using random positions and opacity, implements a health bar that changes color based on health level (green > yellow > red), and animates the enemy ships to move down the screen at different speeds. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + ## 🚀 Challenge -Now that you've learned how to draw with the 2D-focused Canvas API, explore the [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) and try creating a 3D object. +You've learned about drawing with the 2D-focused Canvas API; take a look at the [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API), and try to draw a 3D object. ## Post-Lecture Quiz @@ -220,11 +484,132 @@ Now that you've learned how to draw with the 2D-focused Canvas API, explore the Learn more about the Canvas API by [reading about it](https://developer.mozilla.org/docs/Web/API/Canvas_API). +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open the browser console and create a canvas element with `document.createElement('canvas')` +- [ ] Try drawing a rectangle using `fillRect()` on a canvas context +- [ ] Experiment with different colors using `fillStyle` property +- [ ] Draw a simple circle using the `arc()` method + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and understand canvas fundamentals +- [ ] Create a canvas drawing application with multiple shapes and colors +- [ ] Implement image loading and sprite rendering for your game +- [ ] Build a simple animation that moves objects across the canvas +- [ ] Practice canvas transformations like scaling, rotation, and translation + +### 📅 **Your Week-Long Canvas Journey** +- [ ] Complete the space game with polished graphics and sprite animations +- [ ] Master advanced canvas techniques like gradients, patterns, and compositing +- [ ] Create interactive visualizations using canvas for data representation +- [ ] Learn about canvas optimization techniques for smooth performance +- [ ] Build a drawing or painting application with various tools +- [ ] Explore creative coding patterns and generative art with canvas + +### 🌟 **Your Month-Long Graphics Mastery** +- [ ] Build complex visual applications using Canvas 2D and WebGL +- [ ] Learn graphics programming concepts and shader basics +- [ ] Contribute to open source graphics libraries and visualization tools +- [ ] Master performance optimization for graphics-intensive applications +- [ ] Create educational content about canvas programming and computer graphics +- [ ] Become a graphics programming expert who helps others create visual experiences + +## 🎯 Your Canvas Graphics Mastery Timeline + +```mermaid +timeline + title Canvas API Learning Progression + + section Canvas Fundamentals (15 minutes) + Basic Operations: Element reference + : 2D context access + : Coordinate system + : Simple shape drawing + + section Drawing Techniques (20 minutes) + Graphics Primitives: Rectangles and circles + : Colors and styles + : Text rendering + : Path operations + + section Image Handling (25 minutes) + Asset Management: Image object creation + : Async loading patterns + : Error handling + : Performance optimization + + section Game Graphics (30 minutes) + Sprite Rendering: Positioning algorithms + : Formation calculations + : Scene composition + : Frame rendering + + section Advanced Techniques (40 minutes) + Visual Effects: Transformations + : Animations + : Layering + : State management + + section Performance (35 minutes) + Optimization: Efficient drawing + : Memory management + : Frame rate control + : Asset caching + + section Professional Skills (1 week) + Production Graphics: WebGL integration + : Canvas libraries + : Game engines + : Cross-platform considerations + + section Advanced Graphics (1 month) + Specialized Applications: Data visualization + : Interactive art + : Real-time effects + : 3D graphics +``` +### 🛠️ Your Canvas Graphics Toolkit Summary + +After completing this lesson, you now have: +- **Canvas API Mastery**: Complete understanding of 2D graphics programming +- **Coordinate Mathematics**: Precise positioning and layout algorithms +- **Asset Management**: Professional image loading and error handling +- **Rendering Pipeline**: Structured approach to scene composition +- **Game Graphics**: Sprite positioning and formation calculations +- **Async Programming**: Modern JavaScript patterns for smooth performance +- **Visual Programming**: Translating mathematical concepts to screen graphics + +**Real-World Applications**: Your Canvas skills directly apply to: +- **Data Visualization**: Charts, graphs, and interactive dashboards +- **Game Development**: 2D games, simulations, and interactive experiences +- **Digital Art**: Creative coding and generative art projects +- **UI/UX Design**: Custom graphics and interactive elements +- **Educational Software**: Visual learning tools and simulations +- **Web Applications**: Dynamic graphics and real-time visualizations + +**Professional Skills Gained**: You can now: +- **Build** custom graphics solutions without external libraries +- **Optimize** rendering performance for smooth user experiences +- **Debug** complex visual problems using browser developer tools +- **Design** scalable graphics systems using mathematical principles +- **Integrate** Canvas graphics with modern web application frameworks + +**Canvas API Methods You've Mastered**: +- **Element Management**: getElementById, getContext +- **Drawing Operations**: fillRect, drawImage, fillStyle +- **Asset Loading**: Image objects, Promise patterns +- **Mathematical Positioning**: Coordinate calculations, formation algorithms + +**Next Level**: You're ready to add animation, user interaction, collision detection, or explore WebGL for 3D graphics! + +🌟 **Achievement Unlocked**: You've built a complete game rendering system using fundamental Canvas API techniques! + ## Assignment [Play with the Canvas API](assignment.md) --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/2-drawing-to-canvas/assignment.md b/translations/en/6-space-game/2-drawing-to-canvas/assignment.md index 93da6b51f..74bdf69c2 100644 --- a/translations/en/6-space-game/2-drawing-to-canvas/assignment.md +++ b/translations/en/6-space-game/2-drawing-to-canvas/assignment.md @@ -1,25 +1,74 @@ - -# Experiment with the Canvas API +# Assignment: Explore the Canvas API + +## Learning Objectives + +By completing this assignment, you will demonstrate your understanding of Canvas API fundamentals and apply creative problem-solving to build visual elements using JavaScript and HTML5 canvas. ## Instructions -Choose one feature of the Canvas API and build something creative with it. Can you design a small galaxy of repeated stars? Or perhaps an intriguing texture made of colorful lines? Feel free to browse CodePen for ideas (but avoid copying). +Choose one aspect of the Canvas API that interests you and create an engaging visual project around it. This assignment encourages you to experiment with the drawing capabilities you've learned while building something uniquely yours. + +### Project Ideas to Inspire You + +**Geometric Patterns:** +- **Create** a galaxy of animated twinkling stars using random positioning +- **Design** an interesting texture using repeated geometric shapes +- **Build** a kaleidoscope effect with rotating, colorful patterns + +**Interactive Elements:** +- **Develop** a drawing tool that responds to mouse movements +- **Implement** shapes that change color when clicked +- **Design** a simple animation loop with moving elements + +**Game-Related Graphics:** +- **Craft** a scrolling background for a space game +- **Build** particle effects like explosions or magic spells +- **Create** animated sprites with multiple frames + +### Development Guidelines + +**Research and Inspiration:** +- **Browse** CodePen for creative canvas examples (for inspiration, not copying) +- **Study** the [Canvas API documentation](https://developer.mozilla.org/docs/Web/API/Canvas_API) for additional methods +- **Experiment** with different drawing functions, colors, and animations + +**Technical Requirements:** +- **Use** proper canvas setup with `getContext('2d')` +- **Include** meaningful comments explaining your approach +- **Test** your code thoroughly to ensure it runs without errors +- **Apply** modern JavaScript syntax (const/let, arrow functions) + +**Creative Expression:** +- **Focus** on one Canvas API feature but explore it deeply +- **Add** your own creative twist to make the project personal +- **Consider** how your creation could be part of a larger application + +### Submission Guidelines + +Submit your completed project as a single HTML file with embedded CSS and JavaScript, or as separate files in a folder. Include a brief comment explaining your creative choices and the Canvas API features you explored. ## Rubric -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | --------------------------------------------------------- | ----------------------------------- | --------------------- | -| | Code is submitted showcasing an engaging texture or shape | Code is submitted, but it doesn't work | Code is not submitted | +| Criteria | Exemplary | Adequate | Needs Improvement | +|----------|-----------|----------|-------------------| +| **Technical Implementation** | Canvas API used creatively with multiple features, code runs flawlessly, modern JavaScript syntax applied | Canvas API used correctly, code runs with minor issues, basic implementation | Canvas API attempted but code has errors or doesn't execute | +| **Creativity and Design** | Highly original concept with polished visual appeal, demonstrates deep exploration of chosen Canvas feature | Good use of Canvas features with some creative elements, solid visual result | Basic implementation with minimal creativity or visual appeal | +| **Code Quality** | Well-organized, commented code following best practices, efficient algorithms | Clean code with some comments, follows basic coding standards | Code lacks organization, minimal comments, inefficient implementation | + +## Reflection Questions + +After completing your project, consider these questions: + +1. **What Canvas API feature did you choose and why?** +2. **What challenges did you encounter while building your project?** +3. **How could you extend this project into a larger application or game?** +4. **What other Canvas API features would you like to explore next?** + +> 💡 **Pro Tip**: Start simple and gradually add complexity. A well-executed simple project is better than an overly ambitious project that doesn't work properly! --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/3-moving-elements-around/README.md b/translations/en/6-space-game/3-moving-elements-around/README.md index 5ab5cb26f..41344e5ce 100644 --- a/translations/en/6-space-game/3-moving-elements-around/README.md +++ b/translations/en/6-space-game/3-moving-elements-around/README.md @@ -1,76 +1,180 @@ - # Build a Space Game Part 3: Adding Motion +```mermaid +journey + title Your Game Animation Journey + section Movement Basics + Understand motion principles: 3: Student + Learn coordinate updates: 4: Student + Implement basic movement: 4: Student + section Player Controls + Handle keyboard events: 4: Student + Prevent default behaviors: 5: Student + Create responsive controls: 5: Student + section Game Systems + Build game loop: 5: Student + Manage object lifecycle: 5: Student + Implement pub/sub pattern: 5: Student +``` +Think about your favorite games – what makes them captivating isn't just pretty graphics, it's the way everything moves and responds to your actions. Right now, your space game is like a beautiful painting, but we're about to add movement that brings it to life. + +When NASA's engineers programmed the guidance computer for the Apollo missions, they faced a similar challenge: how do you make a spacecraft respond to pilot input while automatically maintaining course corrections? The principles we'll learn today echo those same concepts – managing player-controlled movement alongside automatic system behaviors. + +In this lesson, you'll learn how to make spaceships glide across the screen, respond to player commands, and create smooth movement patterns. We'll break everything down into manageable concepts that build on each other naturally. + +By the end, you'll have players flying their hero ship around the screen while enemy vessels patrol overhead. More importantly, you'll understand the core principles that power game movement systems. + +```mermaid +mindmap + root((Game Animation)) + Movement Types + Player Controlled + Automatic Motion + Physics Based + Scripted Paths + Event Handling + Keyboard Input + Mouse Events + Touch Controls + Default Prevention + Game Loop + Update Logic + Render Frame + Clear Canvas + Frame Rate Control + Object Management + Position Updates + Collision Detection + Lifecycle Management + State Tracking + Communication + Pub/Sub Pattern + Event Emitters + Message Passing + Loose Coupling +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/33) -Games become much more engaging when you have aliens moving around on the screen! In this lesson, we’ll explore two types of movement: +## Understanding Game Movement + +Games come alive when things start moving around, and there are fundamentally two ways this happens: + +- **Player-controlled movement**: When you press a key or click your mouse, something moves. This is the direct connection between you and your game world. +- **Automatic movement**: When the game itself decides to move things – like those enemy ships that need to patrol the screen whether you're doing anything or not. -- **Keyboard/Mouse movement**: When the user interacts with the keyboard or mouse to move an object on the screen. -- **Game-induced movement**: When the game itself moves an object at specific time intervals. +Making objects move on a computer screen is simpler than you might think. Remember those x and y coordinates from math class? That's exactly what we're working with here. When Galileo tracked Jupiter's moons in 1610, he was essentially doing the same thing – plotting positions over time to understand motion patterns. -So, how do we make objects move on the screen? It all comes down to cartesian coordinates: we change the object's location (x, y) and then redraw the screen. +Moving things on screen is like creating a flipbook animation – you need to follow these three simple steps: -To achieve *movement* on the screen, you typically follow these steps: +```mermaid +flowchart LR + A["Frame N"] --> B["Update Positions"] + B --> C["Clear Canvas"] + C --> D["Draw Objects"] + D --> E["Frame N+1"] + E --> F{Continue?} + F -->|Yes| B + F -->|No| G["Game Over"] + + subgraph "Animation Cycle" + H["1. Calculate new positions"] + I["2. Erase previous frame"] + J["3. Render new frame"] + end + + style B fill:#e1f5fe + style C fill:#ffebee + style D fill:#e8f5e8 +``` +1. **Update the position** – Change where your object should be (maybe move it 5 pixels to the right) +2. **Erase the old frame** – Clear the screen so you don't see ghostly trails everywhere +3. **Draw the new frame** – Put your object in its new spot -1. **Set a new location** for the object. This is necessary to make it appear as though the object has moved. -2. **Clear the screen**. The screen must be cleared between draws. This can be done by drawing a rectangle filled with the background color. -3. **Redraw the object** at its new location. This step completes the process of moving the object from one position to another. +Do this fast enough, and boom! You've got smooth movement that feels natural to players. -Here’s an example of what this might look like in code: +Here's what it can look like in code: ```javascript -//set the hero's location +// Set the hero's location hero.x += 5; -// clear the rectangle that hosts the hero +// Clear the rectangle that hosts the hero ctx.clearRect(0, 0, canvas.width, canvas.height); -// redraw the game background and hero -ctx.fillRect(0, 0, canvas.width, canvas.height) +// Redraw the game background and hero +ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; ctx.drawImage(heroImg, hero.x, hero.y); ``` -✅ Can you think of why redrawing your hero many times per second might lead to performance issues? Check out [alternatives to this pattern](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas). +**Here's what this code does:** +- **Updates** the hero's x-coordinate by 5 pixels to move it horizontally +- **Clears** the entire canvas area to remove the previous frame +- **Fills** the canvas with a black background color +- **Redraws** the hero image at its new position + +✅ Can you think of a reason why redrawing your hero many frames per second might accrue performance costs? Read about [alternatives to this pattern](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas). ## Handle keyboard events -You can handle events by attaching specific events to your code. Keyboard events are triggered on the entire window, while mouse events like `click` can be tied to specific elements. In this project, we’ll use keyboard events. +This is where we connect player input to game action. When someone hits the spacebar to fire a laser or taps an arrow key to dodge an asteroid, your game needs to detect and respond to that input. -To handle an event, you use the window's `addEventListener()` method, which takes two input parameters. The first parameter is the event name, such as `keyup`. The second parameter is the function to be executed when the event occurs. +Keyboard events happen at the window level, meaning your entire browser window is listening for those keypresses. Mouse clicks, on the other hand, can be tied to specific elements (like clicking a button). For our space game, we'll focus on keyboard controls since that's what gives players that classic arcade feel. -Here’s an example: +This reminds me of how telegraph operators in the 1800s had to translate morse code input into meaningful messages – we're doing something similar, translating keypresses into game commands. + +To handle an event you need to use the window's `addEventListener()` method and provide it with two input parameters. The first parameter is the name of the event, for example `keyup`. The second parameter is the function that should be invoked as a result of the event taking place. + +Here's an example: ```javascript window.addEventListener('keyup', (evt) => { - // `evt.key` = string representation of the key + // evt.key = string representation of the key if (evt.key === 'ArrowUp') { // do something } -}) +}); ``` -For key events, you can use two properties on the event object to determine which key was pressed: +**Breaking down what happens here:** +- **Listens** for keyboard events on the entire window +- **Captures** the event object which contains information about which key was pressed +- **Checks** if the pressed key matches a specific key (in this case, the up arrow) +- **Executes** code when the condition is met + +For key events there are two properties on the event you can use to see what key was pressed: + +- `key` - this is a string representation of the pressed key, for example `'ArrowUp'` +- `keyCode` - this is a number representation, for example `37`, corresponds to `ArrowLeft` -- `key`: A string representation of the pressed key, such as `ArrowUp`. -- `keyCode`: A numeric representation, such as `37`, which corresponds to `ArrowLeft`. +✅ Key event manipulation is useful outside of game development. What other uses can you think of for this technique? -✅ Key event handling is useful beyond game development. Can you think of other applications for this technique? +```mermaid +sequenceDiagram + participant User + participant Browser + participant EventSystem + participant GameLogic + participant Hero + + User->>Browser: Presses ArrowUp key + Browser->>EventSystem: keydown event + EventSystem->>EventSystem: preventDefault() + EventSystem->>GameLogic: emit('KEY_EVENT_UP') + GameLogic->>Hero: hero.y -= 5 + Hero->>Hero: Update position + + Note over Browser,GameLogic: Event flow prevents browser defaults + Note over GameLogic,Hero: Pub/sub pattern enables clean communication +``` +### Special keys: a heads up! -### Special keys: a caveat +Some keys have built-in browser behaviors that can interfere with your game. Arrow keys scroll the page and spacebar jumps down – behaviors you don't want when someone is trying to pilot their spaceship. -Some *special* keys affect the browser window. For example, if you’re listening for a `keyup` event and use these special keys to move your hero, the browser might also perform horizontal scrolling. To prevent this, you can disable the browser's default behavior with the following code: +We can prevent these default behaviors and let our game handle the input instead. This is similar to how early computer programmers had to override system interrupts to create custom behaviors – we're just doing it at the browser level. Here's how: ```javascript -let onKeyDown = function (e) { +const onKeyDown = function (e) { console.log(e.keyCode); switch (e.keyCode) { case 37: @@ -88,27 +192,83 @@ let onKeyDown = function (e) { window.addEventListener('keydown', onKeyDown); ``` -This code ensures that the arrow keys and the spacebar have their *default* behavior disabled. The disabling happens when we call `e.preventDefault()`. +**Understanding this prevention code:** +- **Checks** for specific key codes that might cause unwanted browser behavior +- **Prevents** the default browser action for arrow keys and spacebar +- **Allows** other keys to function normally +- **Uses** `e.preventDefault()` to stop the browser's built-in behavior + +### 🔄 **Pedagogical Check-in** +**Event Handling Understanding**: Before moving to automatic movement, ensure you can: +- ✅ Explain the difference between `keydown` and `keyup` events +- ✅ Understand why we prevent default browser behaviors +- ✅ Describe how event listeners connect user input to game logic +- ✅ Identify which keys might interfere with game controls -## Game-induced movement +**Quick Self-Test**: What would happen if you didn't prevent default behavior for arrow keys? +*Answer: The browser would scroll the page, interfering with game movement* -Objects can move on their own using timers like `setTimeout()` or `setInterval()`. These functions update the object's location at regular intervals. Here’s an example: +**Event System Architecture**: You now understand: +- **Window-level listening**: Capturing events at the browser level +- **Event object properties**: `key` strings vs `keyCode` numbers +- **Default prevention**: Stopping unwanted browser behaviors +- **Conditional logic**: Responding to specific key combinations + +## Game induced movement + +Now let's talk about objects that move without player input. Think about enemy ships cruising across the screen, bullets flying in straight lines, or clouds drifting in the background. This autonomous movement makes your game world feel alive even when nobody's touching the controls. + +We use JavaScript's built-in timers to update positions at regular intervals. This concept is similar to how pendulum clocks work – a regular mechanism that triggers consistent, timed actions. Here's how simple it can be: ```javascript -let id = setInterval(() => { - //move the enemy on the y axis +const id = setInterval(() => { + // Move the enemy on the y axis enemy.y += 10; -}) +}, 100); ``` +**Here's what this movement code does:** +- **Creates** a timer that runs every 100 milliseconds +- **Updates** the enemy's y-coordinate by 10 pixels each time +- **Stores** the interval ID so we can stop it later if needed +- **Moves** the enemy downward on the screen automatically + ## The game loop -The game loop is a fundamental concept in game development. It’s essentially a function that runs at regular intervals, drawing everything that should be visible to the player. The game loop processes all game objects, drawing them unless they’re no longer part of the game (e.g., an enemy destroyed by a laser). +Here's the concept that ties everything together – the game loop. If your game were a movie, the game loop would be the film projector, showing frame after frame so fast that everything appears to move smoothly. -Here’s an example of a typical game loop in code: +Every game has one of these loops running behind the scenes. It's a function that updates all game objects, redraws the screen, and repeats this process continuously. This keeps track of your hero, all the enemies, any lasers flying around – the entire game state. +This concept reminds me of how early film animators like Walt Disney had to redraw characters frame by frame to create the illusion of movement. We're doing the same thing, just with code instead of pencils. + +Here's what a game loop can typically look like, expressed in code: + +```mermaid +flowchart TD + A["Start Game Loop"] --> B["Clear Canvas"] + B --> C["Fill Background"] + C --> D["Update Game Objects"] + D --> E["Draw Hero"] + E --> F["Draw Enemies"] + F --> G["Draw UI Elements"] + G --> H["Wait for Next Frame"] + H --> I{Game Running?} + I -->|Yes| B + I -->|No| J["End Game"] + + subgraph "Frame Rate Control" + K["60 FPS = 16.67ms"] + L["30 FPS = 33.33ms"] + M["10 FPS = 100ms"] + end + + style B fill:#ffebee + style D fill:#e1f5fe + style E fill:#e8f5e8 + style F fill:#e8f5e8 +``` ```javascript -let gameLoopId = setInterval(() => +const gameLoopId = setInterval(() => { function gameLoop() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; @@ -116,21 +276,33 @@ let gameLoopId = setInterval(() => drawHero(); drawEnemies(); drawStaticObjects(); + } + gameLoop(); }, 200); ``` -This loop runs every `200` milliseconds to redraw the canvas. You can adjust the interval to suit your game’s needs. +**Understanding the game loop structure:** +- **Clears** the entire canvas to remove the previous frame +- **Fills** the background with a solid color +- **Draws** all game objects in their current positions +- **Repeats** this process every 200 milliseconds to create smooth animation +- **Manages** the frame rate by controlling the interval timing ## Continuing the Space Game -You’ll build on the existing code. Start with the code you completed in Part I, or use the code provided in [Part II - starter](../../../../6-space-game/3-moving-elements-around/your-work). +Now we'll add movement to the static scene you built previously. We're going to transform it from a screenshot into an interactive experience. We'll work through this step by step to ensure each piece builds on the last. + +Grab the code from where we left off in the previous lesson (or start with the code in the [Part II- starter](../../../../6-space-game/3-moving-elements-around/your-work) folder if you need a fresh start). + +**Here's what we're building today:** +- **Hero controls**: Arrow keys will pilot your spaceship around the screen +- **Enemy movement**: Those alien ships will start their advance -- **Move the hero**: Add code to allow the hero to move using the arrow keys. -- **Move enemies**: Add code to make the enemies move from top to bottom at a set speed. +Let's begin implementing these features. ## Recommended steps -Locate the files in the `your-work` folder. It should contain the following: +Locate the files that have been created for you in the `your-work` sub folder. It should contain the following: ```bash -| assets @@ -141,25 +313,29 @@ Locate the files in the `your-work` folder. It should contain the following: -| package.json ``` -Start your project by navigating to the `your_work` folder and typing: +You start your project in the `your-work` folder by typing: ```bash cd your-work npm start ``` -This will start an HTTP server at `http://localhost:5000`. Open a browser and navigate to that address. At this point, you should see the hero and enemies on the screen, but nothing is moving—yet! +**What this command does:** +- **Navigates** to your project directory +- **Starts** a HTTP Server on address `http://localhost:5000` +- **Serves** your game files so you can test them in a browser + +The above will start a HTTP Server on address `http://localhost:5000`. Open up a browser and input that address, right now it should render the hero and all the enemies; nothing is moving - yet! ### Add code -1. **Create dedicated objects** for `hero`, `enemy`, and `game object`. These should have `x` and `y` properties. (Refer to the section on [Inheritance or composition](../README.md)). +1. **Add dedicated objects** for `hero` and `enemy` and `game object`, they should have `x` and `y` properties. (Remember the portion on [Inheritance or composition](../README.md)). - *HINT*: The `game object` should include `x` and `y` properties and the ability to draw itself on the canvas. + *HINT* `game object` should be the one with `x` and `y` and the ability to draw itself to a canvas. - > Tip: Start by creating a `GameObject` class with the following constructor, and then draw it on the canvas: + > **Tip**: Start by adding a new `GameObject` class with its constructor delineated as below, and then draw it to the canvas: - ```javascript - + ```javascript class GameObject { constructor(x, y) { this.x = x; @@ -177,145 +353,234 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na } ``` - Next, extend the `GameObject` class to create the `Hero` and `Enemy` classes: + **Understanding this base class:** + - **Defines** common properties that all game objects share (position, size, image) + - **Includes** a `dead` flag to track whether the object should be removed + - **Provides** a `draw()` method that renders the object on the canvas + - **Sets** default values for all properties that child classes can override - ```javascript +```mermaid +classDiagram + class GameObject { + +x: number + +y: number + +dead: boolean + +type: string + +width: number + +height: number + +img: Image + +draw(ctx) + } + + class Hero { + +speed: number + +type: "Hero" + +width: 98 + +height: 75 + } + + class Enemy { + +type: "Enemy" + +width: 98 + +height: 50 + +setInterval() + } + + GameObject <|-- Hero + GameObject <|-- Enemy + + class EventEmitter { + +listeners: object + +on(message, listener) + +emit(message, payload) + } +``` + Now, extend this `GameObject` to create the `Hero` and `Enemy`: + + ```javascript class Hero extends GameObject { constructor(x, y) { - ...it needs an x, y, type, and speed + super(x, y); + this.width = 98; + this.height = 75; + this.type = "Hero"; + this.speed = 5; } } ``` - ```javascript + ```javascript class Enemy extends GameObject { constructor(x, y) { super(x, y); - (this.width = 98), (this.height = 50); + this.width = 98; + this.height = 50; this.type = "Enemy"; - let id = setInterval(() => { + const id = setInterval(() => { if (this.y < canvas.height - this.height) { this.y += 5; } else { - console.log('Stopped at', this.y) + console.log('Stopped at', this.y); clearInterval(id); } - }, 300) + }, 300); } } ``` -2. **Add key-event handlers** to handle navigation (move the hero up, down, left, and right). + **Key concepts in these classes:** + - **Inherits** from `GameObject` using the `extends` keyword + - **Calls** the parent constructor with `super(x, y)` + - **Sets** specific dimensions and properties for each object type + - **Implements** automatic movement for enemies using `setInterval()` - *REMEMBER*: The coordinate system starts at the top-left corner, which is `(0, 0)`. Also, don’t forget to disable the default browser behavior. +2. **Add key-event handlers** to handle key navigation (move hero up/down left/right) - > Tip: Create an `onKeyDown` function and attach it to the window: + *REMEMBER* it's a cartesian system, top-left is `0,0`. Also remember to add code to stop *default behavior* - ```javascript - let onKeyDown = function (e) { - console.log(e.keyCode); - ...add the code from the lesson above to stop default behavior - } - }; + > **Tip**: Create your `onKeyDown` function and attach it to the window: - window.addEventListener("keydown", onKeyDown); + ```javascript + const onKeyDown = function (e) { + console.log(e.keyCode); + // Add the code from the lesson above to stop default behavior + switch (e.keyCode) { + case 37: + case 39: + case 38: + case 40: // Arrow keys + case 32: + e.preventDefault(); + break; // Space + default: + break; // do not block other keys + } + }; + + window.addEventListener("keydown", onKeyDown); ``` + + **What this event handler does:** + - **Listens** for keydown events on the entire window + - **Logs** the key code to help you debug which keys are being pressed + - **Prevents** default browser behavior for arrow keys and spacebar + - **Allows** other keys to function normally + + Check your browser console at this point, and watch the keystrokes being logged. - Check your browser console to see the keystrokes being logged. +3. **Implement** the [Pub sub pattern](../README.md), this will keep your code clean as you follow the remaining parts. -3. **Implement** the [Pub-Sub pattern](../README.md) to keep your code clean as you continue building the game. + The Publish-Subscribe pattern helps organize your code by separating event detection from event handling. This makes your code more modular and easier to maintain. - To do this, follow these steps: + To do this last part, you can: - 1. **Add an event listener** to the window: + 1. **Add an event listener** on the window: ```javascript - window.addEventListener("keyup", (evt) => { - if (evt.key === "ArrowUp") { - eventEmitter.emit(Messages.KEY_EVENT_UP); - } else if (evt.key === "ArrowDown") { - eventEmitter.emit(Messages.KEY_EVENT_DOWN); - } else if (evt.key === "ArrowLeft") { - eventEmitter.emit(Messages.KEY_EVENT_LEFT); - } else if (evt.key === "ArrowRight") { - eventEmitter.emit(Messages.KEY_EVENT_RIGHT); - } - }); - ``` - - 2. **Create an EventEmitter class** to manage publishing and subscribing to messages: + window.addEventListener("keyup", (evt) => { + if (evt.key === "ArrowUp") { + eventEmitter.emit(Messages.KEY_EVENT_UP); + } else if (evt.key === "ArrowDown") { + eventEmitter.emit(Messages.KEY_EVENT_DOWN); + } else if (evt.key === "ArrowLeft") { + eventEmitter.emit(Messages.KEY_EVENT_LEFT); + } else if (evt.key === "ArrowRight") { + eventEmitter.emit(Messages.KEY_EVENT_RIGHT); + } + }); + ``` + + **What this event system does:** + - **Detects** keyboard input and converts it to custom game events + - **Separates** input detection from game logic + - **Makes** it easy to change controls later without affecting game code + - **Allows** multiple systems to respond to the same input + +```mermaid +flowchart TD + A["Keyboard Input"] --> B["Window Event Listener"] + B --> C["Event Emitter"] + C --> D["KEY_EVENT_UP"] + C --> E["KEY_EVENT_DOWN"] + C --> F["KEY_EVENT_LEFT"] + C --> G["KEY_EVENT_RIGHT"] + + D --> H["Hero Movement"] + D --> I["Sound System"] + D --> J["Visual Effects"] + + E --> H + F --> H + G --> H + + style A fill:#e1f5fe + style C fill:#e8f5e8 + style H fill:#fff3e0 +``` + 2. **Create an EventEmitter class** to publish and subscribe to messages: ```javascript - class EventEmitter { - constructor() { - this.listeners = {}; - } - - on(message, listener) { - if (!this.listeners[message]) { - this.listeners[message] = []; - } - this.listeners[message].push(listener); - } - - emit(message, payload = null) { - if (this.listeners[message]) { - this.listeners[message].forEach((l) => l(message, payload)); - } - } - } - ``` - + class EventEmitter { + constructor() { + this.listeners = {}; + } + + on(message, listener) { + if (!this.listeners[message]) { + this.listeners[message] = []; + } + this.listeners[message].push(listener); + } + 3. **Add constants** and set up the EventEmitter: ```javascript - const Messages = { - KEY_EVENT_UP: "KEY_EVENT_UP", - KEY_EVENT_DOWN: "KEY_EVENT_DOWN", - KEY_EVENT_LEFT: "KEY_EVENT_LEFT", - KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT", - }; - - let heroImg, - enemyImg, - laserImg, - canvas, ctx, - gameObjects = [], - hero, - eventEmitter = new EventEmitter(); - ``` - - 4. **Initialize the game**: - + const Messages = { + KEY_EVENT_UP: "KEY_EVENT_UP", + KEY_EVENT_DOWN: "KEY_EVENT_DOWN", + KEY_EVENT_LEFT: "KEY_EVENT_LEFT", + KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT", + }; + + let heroImg, + enemyImg, + laserImg, + canvas, ctx, + gameObjects = [], + hero, + eventEmitter = new EventEmitter(); + ``` + + **Understanding the setup:** + - **Defines** message constants to avoid typos and make refactoring easier + - **Declares** variables for images, canvas context, and game state + - **Creates** a global event emitter for the pub-sub system + - **Initializes** an array to hold all game objects + + 4. **Initialize the game** ```javascript - function initGame() { - gameObjects = []; - createEnemies(); - createHero(); - - eventEmitter.on(Messages.KEY_EVENT_UP, () => { - hero.y -=5 ; - }) - - eventEmitter.on(Messages.KEY_EVENT_DOWN, () => { - hero.y += 5; - }); - - eventEmitter.on(Messages.KEY_EVENT_LEFT, () => { - hero.x -= 5; - }); - - eventEmitter.on(Messages.KEY_EVENT_RIGHT, () => { - hero.x += 5; - }); - } - ``` - -4. **Set up the game loop** - - Refactor the `window.onload` function to initialize the game and set up a game loop with an appropriate interval. Add a laser beam as well: - - ```javascript + function initGame() { + gameObjects = []; + createEnemies(); + createHero(); + + eventEmitter.on(Messages.KEY_EVENT_UP, () => { + hero.y -= 5; + }); + + eventEmitter.on(Messages.KEY_EVENT_DOWN, () => { + hero.y += 5; + }); + + eventEmitter.on(Messages.KEY_EVENT_LEFT, () => { + hero.x -= 5; + }); + +4. **Setup the game loop** + + Refactor the `window.onload` function to initialize the game and set up a game loop on a good interval. You'll also add a laser beam: + + ```javascript window.onload = async () => { canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); @@ -324,21 +589,27 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na laserImg = await loadTexture("assets/laserRed.png"); initGame(); - let gameLoopId = setInterval(() => { + const gameLoopId = setInterval(() => { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; ctx.fillRect(0, 0, canvas.width, canvas.height); drawGameObjects(ctx); - }, 100) - + }, 100); }; ``` -5. **Move enemies at intervals** + **Understanding the game setup:** + - **Waits** for the page to load completely before starting + - **Gets** the canvas element and its 2D rendering context + - **Loads** all image assets asynchronously using `await` + - **Starts** the game loop running at 100ms intervals (10 FPS) + - **Clears** and redraws the entire screen each frame - Refactor the `createEnemies()` function to generate enemies and add them to the new `gameObjects` class: +5. **Add code** to move enemies at a certain interval - ```javascript + Refactor the `createEnemies()` function to create the enemies and push them into the new gameObjects class: + + ```javascript function createEnemies() { const MONSTER_TOTAL = 5; const MONSTER_WIDTH = MONSTER_TOTAL * 98; @@ -355,9 +626,71 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na } ``` - Create a `createHero()` function to do the same for the hero: + **What the enemy creation does:** + - **Calculates** positions to center enemies on the screen + - **Creates** a grid of enemies using nested loops + - **Assigns** the enemy image to each enemy object + - **Adds** each enemy to the global game objects array + + and add a `createHero()` function to do a similar process for the hero. + + ```javascript + function createHero() { + hero = new Hero( + canvas.width / 2 - 45, + canvas.height - canvas.height / 4 + ); + hero.img = heroImg; + gameObjects.push(hero); + } + ``` - ```javascript + **What the hero creation does:** + - **Positions** the hero at the bottom center of the screen + - **Assigns** the hero image to the hero object + - **Adds** the hero to the game objects array for rendering + + and finally, add a `drawGameObjects()` function to start the drawing: + + ```javascript + function drawGameObjects(ctx) { + gameObjects.forEach(go => go.draw(ctx)); + } + ``` + + **Understanding the drawing function:** + - **Iterates** through all game objects in the array + - **Calls** the `draw()` method on each object + - **Passes** the canvas context so objects can render themselves + + ### 🔄 **Pedagogical Check-in** + **Complete Game System Understanding**: Verify your mastery of the entire architecture: + - ✅ How does inheritance allow Hero and Enemy to share common GameObject properties? + - ✅ Why does the pub/sub pattern make your code more maintainable? + - ✅ What role does the game loop play in creating smooth animation? + - ✅ How do event listeners connect user input to game object behavior? + + **System Integration**: Your game now demonstrates: + - **Object-Oriented Design**: Base classes with specialized inheritance + - **Event-Driven Architecture**: Pub/sub pattern for loose coupling + - **Animation Framework**: Game loop with consistent frame updates + - **Input Handling**: Keyboard events with default prevention + - **Asset Management**: Image loading and sprite rendering + + **Professional Patterns**: You've implemented: + - **Separation of Concerns**: Input, logic, and rendering separated + - **Polymorphism**: All game objects share common drawing interface + - **Message Passing**: Clean communication between components + - **Resource Management**: Efficient sprite and animation handling + + Your enemies should start advancing on your hero spaceship! + } + } + ``` + + and add a `createHero()` function to do a similar process for the hero. + + ```javascript function createHero() { hero = new Hero( canvas.width / 2 - 45, @@ -368,21 +701,45 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na } ``` - Finally, add a `drawGameObjects()` function to start drawing: + and finally, add a `drawGameObjects()` function to start the drawing: - ```javascript + ```javascript function drawGameObjects(ctx) { gameObjects.forEach(go => go.draw(ctx)); } ``` - Your enemies should now begin advancing toward your hero spaceship! + Your enemies should start advancing on your hero spaceship! --- +## GitHub Copilot Agent Challenge 🚀 + +Here's a challenge that will improve your game's polish: adding boundaries and smooth controls. Currently, your hero can fly off the screen, and the movement might feel choppy. + +**Your Mission:** Make your spaceship feel more realistic by implementing screen boundaries and fluid movement. This is similar to how NASA's flight control systems prevent spacecraft from exceeding safe operational parameters. + +**Here's what to build:** Create a system that keeps your hero spaceship on screen, and make the controls feel smooth. When players hold down an arrow key, the ship should glide continuously rather than moving in discrete steps. Consider adding visual feedback when the ship reaches screen boundaries – perhaps a subtle effect to indicate the edge of the play area. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + ## 🚀 Challenge -As you’ve seen, adding more functions, variables, and classes can lead to 'spaghetti code.' How can you better organize your code to make it more readable? Sketch out a system for organizing your code, even if it’s still in a single file. +Code organization becomes increasingly important as projects grow. You might have noticed your file getting crowded with functions, variables, and classes all mixed together. This reminds me of how the engineers organizing the Apollo mission code had to create clear, maintainable systems that multiple teams could work on simultaneously. + +**Your mission:** +Think like a software architect. How would you organize your code so that six months from now, you (or a teammate) could understand what's happening? Even if everything stays in one file for now, you can create better organization: + +- **Grouping related functions** together with clear comment headers +- **Separating concerns** - keep game logic separate from rendering +- **Using consistent naming** conventions for variables and functions +- **Creating modules** or namespaces to organize different aspects of your game +- **Adding documentation** that explains the purpose of each major section + +**Reflection questions:** +- Which parts of your code are hardest to understand when you come back to them? +- How could you organize your code to make it easier for someone else to contribute? +- What would happen if you wanted to add new features like power-ups or different enemy types? ## Post-Lecture Quiz @@ -390,7 +747,135 @@ As you’ve seen, adding more functions, variables, and classes can lead to 'spa ## Review & Self Study -While we’re building this game without frameworks, there are many JavaScript-based canvas frameworks for game development. Take some time to [read about these](https://github.com/collections/javascript-game-engines). +We've been building everything from scratch, which is fantastic for learning, but here's a little secret – there are some amazing JavaScript frameworks out there that can handle a lot of the heavy lifting for you. Once you feel comfortable with the fundamentals we've covered, it's worth [exploring what's available](https://github.com/collections/javascript-game-engines). + +Think of frameworks like having a well-stocked toolbox instead of making every tool by hand. They can solve many of those code organization challenges we talked about, plus offer features that would take weeks to build yourself. + +**Things worth exploring:** +- How game engines organize code – you'll be amazed at the clever patterns they use +- Performance tricks for making canvas games run butter-smooth +- Modern JavaScript features that can make your code cleaner and more maintainable +- Different approaches to managing game objects and their relationships + +## 🎯 Your Game Animation Mastery Timeline + +```mermaid +timeline + title Game Animation & Interaction Learning Progression + + section Movement Fundamentals (20 minutes) + Animation Principles: Frame-based animation + : Position updates + : Coordinate systems + : Smooth movement + + section Event Systems (25 minutes) + User Input: Keyboard event handling + : Default behavior prevention + : Event object properties + : Window-level listening + + section Game Architecture (30 minutes) + Object Design: Inheritance patterns + : Base class creation + : Specialized behaviors + : Polymorphic interfaces + + section Communication Patterns (35 minutes) + Pub/Sub Implementation: Event emitters + : Message constants + : Loose coupling + : System integration + + section Game Loop Mastery (40 minutes) + Real-time Systems: Frame rate control + : Update/render cycle + : State management + : Performance optimization + + section Advanced Techniques (45 minutes) + Professional Features: Collision detection + : Physics simulation + : State machines + : Component systems + + section Game Engine Concepts (1 week) + Framework Understanding: Entity-component systems + : Scene graphs + : Asset pipelines + : Performance profiling + + section Production Skills (1 month) + Professional Development: Code organization + : Team collaboration + : Testing strategies + : Deployment optimization +``` +### 🛠️ Your Game Development Toolkit Summary + +After completing this lesson, you now have mastered: +- **Animation Principles**: Frame-based movement and smooth transitions +- **Event-Driven Programming**: Keyboard input handling with proper event management +- **Object-Oriented Design**: Inheritance hierarchies and polymorphic interfaces +- **Communication Patterns**: Pub/sub architecture for maintainable code +- **Game Loop Architecture**: Real-time update and rendering cycles +- **Input Systems**: User control mapping with default behavior prevention +- **Asset Management**: Sprite loading and efficient rendering techniques + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open the browser console and try `addEventListener('keydown', console.log)` to see keyboard events +- [ ] Create a simple div element and move it around using arrow keys +- [ ] Experiment with `setInterval` to create continuous movement +- [ ] Try preventing default behavior with `event.preventDefault()` + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and understand event-driven programming +- [ ] Build the moving hero spaceship with full keyboard controls +- [ ] Implement smooth enemy movement patterns +- [ ] Add boundaries to prevent game objects from leaving the screen +- [ ] Create basic collision detection between game objects + +### 📅 **Your Week-Long Animation Journey** +- [ ] Complete the full space game with polished movement and interactions +- [ ] Add advanced movement patterns like curves, acceleration, and physics +- [ ] Implement smooth transitions and easing functions +- [ ] Create particle effects and visual feedback systems +- [ ] Optimize game performance for smooth 60fps gameplay +- [ ] Add mobile touch controls and responsive design + +### 🌟 **Your Month-Long Interactive Development** +- [ ] Build complex interactive applications with advanced animation systems +- [ ] Learn animation libraries like GSAP or create your own animation engine +- [ ] Contribute to open source game development and animation projects +- [ ] Master performance optimization for graphics-intensive applications +- [ ] Create educational content about game development and animation +- [ ] Build a portfolio showcasing advanced interactive programming skills + +**Real-World Applications**: Your game animation skills apply directly to: +- **Interactive Web Applications**: Dynamic dashboards and real-time interfaces +- **Data Visualization**: Animated charts and interactive graphics +- **Educational Software**: Interactive simulations and learning tools +- **Mobile Development**: Touch-based games and gesture handling +- **Desktop Applications**: Electron apps with smooth animations +- **Web Animations**: CSS and JavaScript animation libraries + +**Professional Skills Gained**: You can now: +- **Architect** event-driven systems that scale with complexity +- **Implement** smooth animations using mathematical principles +- **Debug** complex interaction systems using browser developer tools +- **Optimize** game performance for different devices and browsers +- **Design** maintainable code structures using proven patterns + +**Game Development Concepts Mastered**: +- **Frame Rate Management**: Understanding FPS and timing controls +- **Input Handling**: Cross-platform keyboard and event systems +- **Object Lifecycle**: Creation, update, and destruction patterns +- **State Synchronization**: Keeping game state consistent across frames +- **Event Architecture**: Decoupled communication between game systems + +**Next Level**: You're ready to add collision detection, scoring systems, sound effects, or explore modern game frameworks like Phaser or Three.js! + +🌟 **Achievement Unlocked**: You've built a complete interactive game system with professional architecture patterns! ## Assignment @@ -398,5 +883,7 @@ While we’re building this game without frameworks, there are many JavaScript-b --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, a professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/3-moving-elements-around/assignment.md b/translations/en/6-space-game/3-moving-elements-around/assignment.md index 3070d5991..7593b86d8 100644 --- a/translations/en/6-space-game/3-moving-elements-around/assignment.md +++ b/translations/en/6-space-game/3-moving-elements-around/assignment.md @@ -1,25 +1,29 @@ - # Comment Your Code ## Instructions -Review your current /app.js file in your game folder and look for ways to add comments and organize it better. Code can easily become messy, so this is a great opportunity to add comments to make it more readable and easier to work with in the future. +Clean, well-documented code is essential for maintaining and sharing your projects. In this assignment, you'll practice one of the most important habits of professional developers: writing clear, helpful comments that explain your code's purpose and functionality. + +Go over your current `app.js` file in your game folder, and find ways to comment it and tidy it up. It's very easy for code to get out of control, and now's a good chance to add comments to ensure that you have readable code so that you can use it later. + +**Your task includes:** +- **Add comments** explaining what each major section of code does +- **Document functions** with clear descriptions of their purpose and parameters +- **Organize code** into logical blocks with section headers +- **Remove** any unused or redundant code +- **Use consistent** naming conventions for variables and functions ## Rubric -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | ----------------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------- | -| | `app.js` code is thoroughly commented and structured into clear sections | `app.js` code has sufficient comments | `app.js` code is somewhat unorganized and lacks meaningful comments | +| Criteria | Exemplary | Adequate | Needs Improvement | +| -------- | --------- | -------- | ----------------- | +| **Code Documentation** | `app.js` code is fully commented with clear, helpful explanations for all major sections and functions | `app.js` code is adequately commented with basic explanations for most sections | `app.js` code has minimal comments and lacks clear explanations | +| **Code Organization** | Code is organized into logical blocks with clear section headers and consistent structure | Code has some organization with basic grouping of related functionality | Code is somewhat disorganized and difficult to follow | +| **Code Quality** | All variables and functions use descriptive names, no unused code, follows consistent conventions | Most code follows good naming practices with minimal unused code | Variable names are unclear, contains unused code, inconsistent style | --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/4-collision-detection/README.md b/translations/en/6-space-game/4-collision-detection/README.md index 435cdec6f..45e16dfad 100644 --- a/translations/en/6-space-game/4-collision-detection/README.md +++ b/translations/en/6-space-game/4-collision-detection/README.md @@ -1,131 +1,316 @@ - # Build a Space Game Part 4: Adding A Laser and Detect Collisions +```mermaid +journey + title Your Collision Detection Journey + section Physics Foundation + Understand rectangles: 3: Student + Learn intersection math: 4: Student + Grasp coordinate systems: 4: Student + section Game Mechanics + Implement laser firing: 4: Student + Add object lifecycle: 5: Student + Create collision rules: 5: Student + section System Integration + Build collision detection: 5: Student + Optimize performance: 5: Student + Test interaction systems: 5: Student +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/35) -In this lesson, you'll learn how to shoot lasers using JavaScript! We'll add two features to our game: +Think about the moment in Star Wars when Luke's proton torpedoes hit the Death Star's exhaust port. That precise collision detection changed the fate of the galaxy! In games, collision detection works the same way - it determines when objects interact and what happens next. + +In this lesson, you'll add laser weapons to your space game and implement collision detection. Just like NASA's mission planners calculate spacecraft trajectories to avoid debris, you'll learn to detect when game objects intersect. We'll break this down into manageable steps that build on each other. + +By the end, you'll have a functioning combat system where lasers destroy enemies and collisions trigger game events. These same collision principles are used in everything from physics simulations to interactive web interfaces. + +```mermaid +mindmap + root((Collision Detection)) + Physics Concepts + Rectangle Boundaries + Intersection Testing + Coordinate Systems + Separation Logic + Game Objects + Laser Projectiles + Enemy Ships + Hero Character + Collision Zones + Lifecycle Management + Object Creation + Movement Updates + Destruction Marking + Memory Cleanup + Event Systems + Keyboard Input + Collision Events + Game State Changes + Audio/Visual Effects + Performance + Efficient Algorithms + Frame Rate Optimization + Memory Management + Spatial Partitioning +``` +✅ Do a little research on the very first computer game ever written. What was its functionality? -- **A laser**: This laser will be fired from your hero's ship and move vertically upward. -- **Collision detection**: As part of implementing the ability to *shoot*, we'll also introduce some exciting game rules: - - **Laser hits enemy**: The enemy is destroyed if hit by a laser. - - **Laser hits top of the screen**: The laser is removed if it reaches the top of the screen. - - **Enemy and hero collision**: Both the enemy and the hero are destroyed if they collide. - - **Enemy reaches the bottom of the screen**: Both the enemy and the hero are destroyed if the enemy reaches the bottom of the screen. +## Collision detection -In short, you -- *the hero* -- must destroy all enemies with your laser before they reach the bottom of the screen. +Collision detection works like the proximity sensors on the Apollo lunar module - it constantly checks distances and triggers alerts when objects get too close. In games, this system determines when objects interact and what should happen next. -✅ Do a little research on the very first computer game ever created. What was its functionality? +The approach we'll use treats every game object as a rectangle, similar to how air traffic control systems use simplified geometric shapes to track aircraft. This rectangular method might seem basic, but it's computationally efficient and works well for most game scenarios. -Let's be heroic together! +### Rectangle representation -## Collision detection +Every game object needs coordinate boundaries, similar to how the Mars Pathfinder rover mapped its location on the Martian surface. Here's how we define these boundary coordinates: + +```mermaid +flowchart TD + A["🎯 Game Object"] --> B["📍 Position (x, y)"] + A --> C["📏 Dimensions (width, height)"] + + B --> D["Top: y"] + B --> E["Left: x"] + + C --> F["Bottom: y + height"] + C --> G["Right: x + width"] + + D --> H["🔲 Rectangle Bounds"] + E --> H + F --> H + G --> H + + H --> I["Collision Detection Ready"] + + style A fill:#e3f2fd + style H fill:#e8f5e8 + style I fill:#fff3e0 +``` +```javascript +rectFromGameObject() { + return { + top: this.y, + left: this.x, + bottom: this.y + this.height, + right: this.x + this.width + } +} +``` + +**Let's break this down:** +- **Top edge**: That's just where your object starts vertically (its y position) +- **Left edge**: Where it starts horizontally (its x position) +- **Bottom edge**: Add the height to the y position - now you know where it ends! +- **Right edge**: Add the width to the x position - and you've got the complete boundary -How do we detect collisions? We need to think of our game objects as rectangles moving around. Why rectangles, you ask? Because the image used to represent a game object is essentially a rectangle: it has an `x`, `y`, `width`, and `height`. +### Intersection algorithm -If two rectangles, such as the hero and an enemy, *intersect*, a collision occurs. What happens next depends on the rules of the game. To implement collision detection, you'll need the following: +Detecting rectangle intersections uses logic similar to how the Hubble Space Telescope determines if celestial objects are overlapping in its field of view. The algorithm checks for separation: -1. A way to represent a game object as a rectangle, like this: +```mermaid +flowchart LR + A["Rectangle 1"] --> B{"Separation Tests"} + C["Rectangle 2"] --> B + + B --> D["R2 left > R1 right?"] + B --> E["R2 right < R1 left?"] + B --> F["R2 top > R1 bottom?"] + B --> G["R2 bottom < R1 top?"] + + D --> H{"Any True?"} + E --> H + F --> H + G --> H + + H -->|Yes| I["❌ No Collision"] + H -->|No| J["✅ Collision Detected"] + + style B fill:#e3f2fd + style I fill:#ffebee + style J fill:#e8f5e8 +``` +```javascript +function intersectRect(r1, r2) { + return !(r2.left > r1.right || + r2.right < r1.left || + r2.top > r1.bottom || + r2.bottom < r1.top); +} +``` - ```javascript - rectFromGameObject() { - return { - top: this.y, - left: this.x, - bottom: this.y + this.height, - right: this.x + this.width - } - } - ``` +**The separation test works like radar systems:** +- Is rectangle 2 completely to the right of rectangle 1? +- Is rectangle 2 completely to the left of rectangle 1? +- Is rectangle 2 completely below rectangle 1? +- Is rectangle 2 completely above rectangle 1? -2. A function to compare rectangles, which might look like this: +If none of these conditions are true, the rectangles must be overlapping. This approach mirrors how radar operators determine if two aircraft are at safe distances. - ```javascript - function intersectRect(r1, r2) { - return !(r2.left > r1.right || - r2.right < r1.left || - r2.top > r1.bottom || - r2.bottom < r1.top); - } - ``` +## Managing object lifecycles -## How do we destroy things +When a laser hits an enemy, both objects need to be removed from the game. However, deleting objects mid-loop can cause crashes - a lesson learned the hard way in early computer systems like the Apollo Guidance Computer. Instead, we use a "mark for deletion" approach that safely removes objects between frames. -To destroy objects in a game, you need to tell the game not to render them anymore during the game loop that runs at regular intervals. One way to do this is to mark a game object as *dead* when something happens, like this: +```mermaid +stateDiagram-v2 + [*] --> Active: Object Created + Active --> Collided: Collision Detected + Collided --> MarkedDead: Set dead = true + MarkedDead --> Filtered: Next Frame + Filtered --> [*]: Object Removed + + Active --> OutOfBounds: Leaves Screen + OutOfBounds --> MarkedDead + + note right of MarkedDead + Safe to continue + current frame + end note + + note right of Filtered + Objects removed + between frames + end note +``` +Here's how we mark something for removal: ```javascript -// collision happened -enemy.dead = true +// Mark object for removal +enemy.dead = true; ``` -Then, you can filter out *dead* objects before repainting the screen, like this: +**Why this approach works:** +- We mark the object as "dead" but don't delete it right away +- This lets the current game frame finish safely +- No crashes from trying to use something that's already gone! + +Then filter out marked objects before the next render cycle: ```javascript -gameObjects = gameObject.filter(go => !go.dead); +gameObjects = gameObjects.filter(go => !go.dead); ``` -## How do we fire a laser +**What this filtering does:** +- Creates a fresh list with only the "living" objects +- Tosses out anything marked as dead +- Keeps your game running smoothly +- Prevents memory bloat from accumulating destroyed objects -Firing a laser involves responding to a key event and creating an object that moves in a specific direction. Here's what you'll need to do: +## Implementing laser mechanics -1. **Create a laser object**: The laser will originate from the top of the hero's ship and start moving upward toward the top of the screen. -2. **Attach code to a key event**: Choose a key on the keyboard (e.g., the space bar) to represent firing the laser. -3. **Create a game object that looks like a laser** when the key is pressed. +Laser projectiles in games work on the same principle as photon torpedoes in Star Trek - they're discrete objects that travel in straight lines until they hit something. Each spacebar press creates a new laser object that moves across the screen. -## Cooldown on our laser +To make this work, we need to coordinate a few different pieces: -The laser should fire every time you press a key, such as the space bar. To prevent the game from generating too many lasers in a short period, we need to implement a *cooldown*. A cooldown is essentially a timer that ensures the laser can only be fired at specific intervals. You can implement it like this: +**Key components to implement:** +- **Create** laser objects that spawn from the hero's position +- **Handle** keyboard input to trigger laser creation +- **Manage** laser movement and lifecycle +- **Implement** visual representation for the laser projectiles +## Implementing firing rate control + +Unlimited firing rates would overwhelm the game engine and make gameplay too easy. Real weapon systems face similar constraints - even the USS Enterprise's phasers needed time to recharge between shots. + +We'll implement a cooldown system that prevents rapid-fire spamming while maintaining responsive controls: + +```mermaid +sequenceDiagram + participant Player + participant Weapon + participant Cooldown + participant Game + + Player->>Weapon: Press Spacebar + Weapon->>Cooldown: Check if cool + + alt Weapon is Ready + Cooldown->>Weapon: cool = true + Weapon->>Game: Create Laser + Weapon->>Cooldown: Start new cooldown + Cooldown->>Cooldown: cool = false + + Note over Cooldown: Wait 500ms + + Cooldown->>Cooldown: cool = true + else Weapon is Cooling + Cooldown->>Weapon: cool = false + Weapon->>Player: No action + end +``` ```javascript class Cooldown { constructor(time) { this.cool = false; setTimeout(() => { this.cool = true; - }, time) + }, time); } } class Weapon { - constructor { + constructor() { + this.cooldown = null; } + fire() { if (!this.cooldown || this.cooldown.cool) { - // produce a laser + // Create laser projectile this.cooldown = new Cooldown(500); } else { - // do nothing - it hasn't cooled down yet. + // Weapon is still cooling down } } } ``` -✅ Refer to lesson 1 in the space game series to refresh your memory about *cooldowns*. +**How the cooldown works:** +- When created, the weapon starts "hot" (can't fire yet) +- After the timeout period, it becomes "cool" (ready to fire) +- Before firing, we check: "Is the weapon cool?" +- This prevents spam-clicking while keeping controls responsive + +✅ Refer to lesson 1 in the space game series to remind yourself about cooldowns. + +## Building the collision system + +You'll extend your existing space game code to create a collision detection system. Like the International Space Station's automated collision avoidance system, your game will continuously monitor object positions and respond to intersections. + +Starting from your previous lesson's code, you'll add collision detection with specific rules that govern object interactions. + +> 💡 **Pro Tip**: The laser sprite is already included in your assets folder and referenced in your code, ready for implementation. + +### Collision rules to implement + +**Game mechanics to add:** +1. **Laser hits enemy**: Enemy object is destroyed when struck by a laser projectile +2. **Laser hits screen boundary**: Laser is removed when reaching the top edge of the screen +3. **Enemy and hero collision**: Both objects are destroyed when they intersect +4. **Enemy reaches bottom**: Game over condition when enemies reach the screen bottom -## What to build +### 🔄 **Pedagogical Check-in** +**Collision Detection Foundation**: Before implementing, ensure you understand: +- ✅ How rectangle boundaries define collision zones +- ✅ Why separation testing is more efficient than intersection calculation +- ✅ The importance of object lifecycle management in game loops +- ✅ How event-driven systems coordinate collision responses -You'll extend the existing code (which you should have cleaned up and refactored) from the previous lesson. You can either start with the code from part II or use the code from [Part III - starter](../../../../../../../../../your-work). +**Quick Self-Test**: What would happen if you deleted objects immediately instead of marking them? +*Answer: Mid-loop deletion could cause crashes or skip objects in iteration* -> tip: The laser you'll work with is already in your assets folder and referenced in your code. +**Physics Understanding**: You now grasp: +- **Coordinate Systems**: How position and dimensions create boundaries +- **Intersection Logic**: Mathematical principles behind collision detection +- **Performance Optimization**: Why efficient algorithms matter in real-time systems +- **Memory Management**: Safe object lifecycle patterns for stability -- **Add collision detection**: When a laser collides with something, the following rules should apply: - 1. **Laser hits enemy**: The enemy is destroyed if hit by a laser. - 2. **Laser hits top of the screen**: The laser is removed if it reaches the top of the screen. - 3. **Enemy and hero collision**: Both the enemy and the hero are destroyed if they collide. - 4. **Enemy reaches the bottom of the screen**: Both the enemy and the hero are destroyed if the enemy reaches the bottom of the screen. +## Setting up your development environment -## Recommended steps +Good news - we've already set up most of the groundwork for you! All your game assets and basic structure are waiting in the `your-work` subfolder, ready for you to add the cool collision features. -Locate the files created for you in the `your-work` subfolder. It should contain the following: +### Project structure ```bash -| assets @@ -137,161 +322,430 @@ Locate the files created for you in the `your-work` subfolder. It should contain -| package.json ``` -Start your project in the `your_work` folder by typing: +**Understanding the file structure:** +- **Contains** all sprite images needed for the game objects +- **Includes** the main HTML document and JavaScript application file +- **Provides** package configuration for local development server + +### Starting the development server + +Navigate to your project folder and start the local server: ```bash cd your-work npm start ``` -This will start an HTTP server at `http://localhost:5000`. Open a browser and navigate to that address. At this point, it should display the hero and all the enemies, but nothing is moving yet. +**This command sequence:** +- **Changes** directory to your working project folder +- **Starts** a local HTTP server on `http://localhost:5000` +- **Serves** your game files for testing and development +- **Enables** live development with automatic reloading + +Open your browser and navigate to `http://localhost:5000` to see your current game state with the hero and enemies rendered on screen. + +### Step-by-step implementation + +Like the systematic approach NASA used to program the Voyager spacecraft, we'll implement collision detection methodically, building each component step by step. + +```mermaid +flowchart TD + A["1. Rectangle Bounds"] --> B["2. Intersection Detection"] + B --> C["3. Laser System"] + C --> D["4. Event Handling"] + D --> E["5. Collision Rules"] + E --> F["6. Cooldown System"] + + G["Object Boundaries"] --> A + H["Physics Algorithm"] --> B + I["Projectile Creation"] --> C + J["Keyboard Input"] --> D + K["Game Logic"] --> E + L["Rate Limiting"] --> F + + F --> M["🎮 Complete Game"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 + style F fill:#fce4ec + style M fill:#e1f5fe +``` +#### 1. Add rectangle collision bounds + +First, let's teach our game objects how to describe their boundaries. Add this method to your `GameObject` class: + +```javascript +rectFromGameObject() { + return { + top: this.y, + left: this.x, + bottom: this.y + this.height, + right: this.x + this.width, + }; + } +``` + +**This method accomplishes:** +- **Creates** a rectangle object with precise boundary coordinates +- **Calculates** bottom and right edges using position plus dimensions +- **Returns** an object ready for collision detection algorithms +- **Provides** a standardized interface for all game objects + +#### 2. Implement intersection detection + +Now let's create our collision detective - a function that can tell when two rectangles are overlapping: + +```javascript +function intersectRect(r1, r2) { + return !( + r2.left > r1.right || + r2.right < r1.left || + r2.top > r1.bottom || + r2.bottom < r1.top + ); +} +``` + +**This algorithm works by:** +- **Tests** four separation conditions between rectangles +- **Returns** `false` if any separation condition is true +- **Indicates** collision when no separation exists +- **Uses** negation logic for efficient intersection testing + +#### 3. Implement laser firing system -### Add code +Here's where things get exciting! Let's set up the laser firing system. -1. **Set up a rectangle representation for your game objects to handle collisions**: The following code allows you to represent a `GameObject` as a rectangle. Edit your GameObject class to include this: +##### Message constants - ```javascript - rectFromGameObject() { - return { - top: this.y, - left: this.x, - bottom: this.y + this.height, - right: this.x + this.width, - }; +First, let's define some message types so different parts of our game can talk to each other: + +```javascript +KEY_EVENT_SPACE: "KEY_EVENT_SPACE", +COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER", +COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO", +``` + +**These constants provide:** +- **Standardizes** event names throughout the application +- **Enables** consistent communication between game systems +- **Prevents** typos in event handler registration + +##### Keyboard input handling + +Add space key detection to your key event listener: + +```javascript +} else if(evt.keyCode === 32) { + eventEmitter.emit(Messages.KEY_EVENT_SPACE); +} +``` + +**This input handler:** +- **Detects** space key presses using keyCode 32 +- **Emits** a standardized event message +- **Enables** decoupled firing logic + +##### Event listener setup + +Register firing behavior in your `initGame()` function: + +```javascript +eventEmitter.on(Messages.KEY_EVENT_SPACE, () => { + if (hero.canFire()) { + hero.fire(); + } +}); +``` + +**This event listener:** +- **Responds** to space key events +- **Checks** firing cooldown status +- **Triggers** laser creation when allowed + +Add collision handling for laser-enemy interactions: + +```javascript +eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { + first.dead = true; + second.dead = true; +}); +``` + +**This collision handler:** +- **Receives** collision event data with both objects +- **Marks** both objects for removal +- **Ensures** proper cleanup after collision + +#### 4. Create the Laser class + +Implement a laser projectile that moves upward and manages its own lifecycle: + +```javascript +class Laser extends GameObject { + constructor(x, y) { + super(x, y); + this.width = 9; + this.height = 33; + this.type = 'Laser'; + this.img = laserImg; + + let id = setInterval(() => { + if (this.y > 0) { + this.y -= 15; + } else { + this.dead = true; + clearInterval(id); } - ``` - -2. **Add code to check for collisions**: Create a new function to test whether two rectangles intersect: - - ```javascript - function intersectRect(r1, r2) { - return !( - r2.left > r1.right || - r2.right < r1.left || - r2.top > r1.bottom || - r2.bottom < r1.top - ); - } - ``` - -3. **Add laser firing capability**: - 1. **Add a key-event message**: The space bar should create a laser just above the hero's ship. Add three constants to the Messages object: - - ```javascript - KEY_EVENT_SPACE: "KEY_EVENT_SPACE", - COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER", - COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO", - ``` - - 2. **Handle the space bar key**: Edit the `window.addEventListener` keyup function to handle the space bar: - - ```javascript - } else if(evt.keyCode === 32) { - eventEmitter.emit(Messages.KEY_EVENT_SPACE); - } - ``` - - 3. **Add listeners**: Edit the `initGame()` function to ensure the hero can fire when the space bar is pressed: - - ```javascript - eventEmitter.on(Messages.KEY_EVENT_SPACE, () => { - if (hero.canFire()) { - hero.fire(); - } - ``` - - Add a new `eventEmitter.on()` function to define behavior when an enemy collides with a laser: - - ```javascript - eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { - first.dead = true; - second.dead = true; - }) - ``` - - 4. **Move the laser object**: Ensure the laser moves gradually toward the top of the screen. Create a new Laser class that extends `GameObject`, as you've done before: - - ```javascript - class Laser extends GameObject { - constructor(x, y) { - super(x,y); - (this.width = 9), (this.height = 33); - this.type = 'Laser'; - this.img = laserImg; - let id = setInterval(() => { - if (this.y > 0) { - this.y -= 15; - } else { - this.dead = true; - clearInterval(id); - } - }, 100) - } + }, 100); + } +} +``` + +**This class implementation:** +- **Extends** GameObject to inherit basic functionality +- **Sets** appropriate dimensions for the laser sprite +- **Creates** automatic upward movement using `setInterval()` +- **Handles** self-destruction when reaching screen top +- **Manages** its own animation timing and cleanup + +#### 5. Implement collision detection system + +Create a comprehensive collision detection function: + +```javascript +function updateGameObjects() { + const enemies = gameObjects.filter(go => go.type === 'Enemy'); + const lasers = gameObjects.filter(go => go.type === "Laser"); + + // Test laser-enemy collisions + lasers.forEach((laser) => { + enemies.forEach((enemy) => { + if (intersectRect(laser.rectFromGameObject(), enemy.rectFromGameObject())) { + eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, { + first: laser, + second: enemy, + }); } - ``` - - 5. **Handle collisions**: Implement collision rules for the laser. Add an `updateGameObjects()` function to test for collisions between objects: - - ```javascript - function updateGameObjects() { - const enemies = gameObjects.filter(go => go.type === 'Enemy'); - const lasers = gameObjects.filter((go) => go.type === "Laser"); - // laser hit something - lasers.forEach((l) => { - enemies.forEach((m) => { - if (intersectRect(l.rectFromGameObject(), m.rectFromGameObject())) { - eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, { - first: l, - second: m, - }); - } - }); - }); - - gameObjects = gameObjects.filter(go => !go.dead); - } - ``` - - Make sure to include `updateGameObjects()` in your game loop in `window.onload`. - - 6. **Implement cooldown** for the laser so it can only be fired at specific intervals. - - Finally, edit the Hero class to include a cooldown mechanism: - - ```javascript - class Hero extends GameObject { - constructor(x, y) { - super(x, y); - (this.width = 99), (this.height = 75); - this.type = "Hero"; - this.speed = { x: 0, y: 0 }; - this.cooldown = 0; - } - fire() { - gameObjects.push(new Laser(this.x + 45, this.y - 10)); - this.cooldown = 500; - - let id = setInterval(() => { - if (this.cooldown > 0) { - this.cooldown -= 100; - } else { - clearInterval(id); - } - }, 200); - } - canFire() { - return this.cooldown === 0; - } + }); + }); + + // Remove destroyed objects + gameObjects = gameObjects.filter(go => !go.dead); +} +``` + +**This collision system:** +- **Filters** game objects by type for efficient testing +- **Tests** every laser against every enemy for intersections +- **Emits** collision events when intersections are detected +- **Cleans** up destroyed objects after collision processing + +> ⚠️ **Important**: Add `updateGameObjects()` to your main game loop in `window.onload` to enable collision detection. + +#### 6. Add cooldown system to Hero class + +Enhance the Hero class with firing mechanics and rate limiting: + +```javascript +class Hero extends GameObject { + constructor(x, y) { + super(x, y); + this.width = 99; + this.height = 75; + this.type = "Hero"; + this.speed = { x: 0, y: 0 }; + this.cooldown = 0; + } + + fire() { + gameObjects.push(new Laser(this.x + 45, this.y - 10)); + this.cooldown = 500; + + let id = setInterval(() => { + if (this.cooldown > 0) { + this.cooldown -= 100; + } else { + clearInterval(id); } - ``` + }, 200); + } + + canFire() { + return this.cooldown === 0; + } +} +``` + +**Understanding the enhanced Hero class:** +- **Initializes** cooldown timer at zero (ready to fire) +- **Creates** laser objects positioned above the hero ship +- **Sets** cooldown period to prevent rapid firing +- **Decrements** cooldown timer using interval-based updates +- **Provides** firing status check through `canFire()` method + +### 🔄 **Pedagogical Check-in** +**Complete System Understanding**: Verify your mastery of the collision system: +- ✅ How do rectangle boundaries enable efficient collision detection? +- ✅ Why is object lifecycle management critical for game stability? +- ✅ How does the cooldown system prevent performance issues? +- ✅ What role does event-driven architecture play in collision handling? + +**System Integration**: Your collision detection demonstrates: +- **Mathematical Precision**: Rectangle intersection algorithms +- **Performance Optimization**: Efficient collision testing patterns +- **Memory Management**: Safe object creation and destruction +- **Event Coordination**: Decoupled system communication +- **Real-time Processing**: Frame-based update cycles + +**Professional Patterns**: You've implemented: +- **Separation of Concerns**: Physics, rendering, and input separated +- **Object-Oriented Design**: Inheritance and polymorphism +- **State Management**: Object lifecycle and game state tracking +- **Performance Optimization**: Efficient algorithms for real-time use + +### Testing your implementation + +Your space game now features complete collision detection and combat mechanics. 🚀 Test these new capabilities: +- **Navigate** with arrow keys to verify movement controls +- **Fire lasers** with the spacebar - notice how the cooldown prevents spam-clicking +- **Observe collisions** when lasers hit enemies, triggering removal +- **Verify cleanup** as destroyed objects disappear from the game + +You've successfully implemented a collision detection system using the same mathematical principles that guide spacecraft navigation and robotics. + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Open browser DevTools and set breakpoints in your collision detection function +- [ ] Try modifying the laser speed or enemy movement to see collision effects +- [ ] Experiment with different cooldown values to test firing rates +- [ ] Add `console.log` statements to track collision events in real-time + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and understand collision detection algorithms +- [ ] Add visual effects like explosions when collisions occur +- [ ] Implement different types of projectiles with varying properties +- [ ] Create power-ups that enhance player abilities temporarily +- [ ] Add sound effects to make collisions more satisfying + +### 📅 **Your Week-Long Physics Programming** +- [ ] Complete the full space game with polished collision systems +- [ ] Implement advanced collision shapes beyond rectangles (circles, polygons) +- [ ] Add particle systems for realistic explosion effects +- [ ] Create complex enemy behavior with collision avoidance +- [ ] Optimize collision detection for better performance with many objects +- [ ] Add physics simulation like momentum and realistic movement + +### 🌟 **Your Month-Long Game Physics Mastery** +- [ ] Build games with advanced physics engines and realistic simulations +- [ ] Learn 3D collision detection and spatial partitioning algorithms +- [ ] Contribute to open source physics libraries and game engines +- [ ] Master performance optimization for graphics-intensive applications +- [ ] Create educational content about game physics and collision detection +- [ ] Build a portfolio showcasing advanced physics programming skills + +## 🎯 Your Collision Detection Mastery Timeline + +```mermaid +timeline + title Collision Detection & Game Physics Learning Progression + + section Foundation (10 minutes) + Rectangle Math: Coordinate systems + : Boundary calculations + : Position tracking + : Dimension management + + section Algorithm Design (20 minutes) + Intersection Logic: Separation testing + : Overlap detection + : Performance optimization + : Edge case handling + + section Game Implementation (30 minutes) + Object Systems: Lifecycle management + : Event coordination + : State tracking + : Memory cleanup + + section Interactive Features (40 minutes) + Combat Mechanics: Projectile systems + : Weapon cooldowns + : Damage calculation + : Visual feedback + + section Advanced Physics (50 minutes) + Real-time Systems: Frame rate optimization + : Spatial partitioning + : Collision response + : Physics simulation + + section Professional Techniques (1 week) + Game Engine Concepts: Component systems + : Physics pipelines + : Performance profiling + : Cross-platform optimization + + section Industry Applications (1 month) + Production Skills: Large-scale optimization + : Team collaboration + : Engine development + : Platform deployment +``` +### 🛠️ Your Game Physics Toolkit Summary + +After completing this lesson, you now have mastered: +- **Collision Mathematics**: Rectangle intersection algorithms and coordinate systems +- **Performance Optimization**: Efficient collision detection for real-time applications +- **Object Lifecycle Management**: Safe creation, updating, and destruction patterns +- **Event-Driven Architecture**: Decoupled systems for collision response +- **Game Loop Integration**: Frame-based physics updates and rendering coordination +- **Input Systems**: Responsive controls with rate limiting and feedback +- **Memory Management**: Efficient object pooling and cleanup strategies + +**Real-World Applications**: Your collision detection skills apply directly to: +- **Interactive Simulations**: Scientific modeling and educational tools +- **User Interface Design**: Drag-and-drop interactions and touch detection +- **Data Visualization**: Interactive charts and clickable elements +- **Mobile Development**: Touch gesture recognition and collision handling +- **Robotics Programming**: Path planning and obstacle avoidance +- **Computer Graphics**: Ray tracing and spatial algorithms + +**Professional Skills Gained**: You can now: +- **Design** efficient algorithms for real-time collision detection +- **Implement** physics systems that scale with object complexity +- **Debug** complex interaction systems using mathematical principles +- **Optimize** performance for different hardware and browser capabilities +- **Architect** maintainable game systems using proven design patterns -At this point, your game has some functionality! You can navigate using the arrow keys, fire a laser with the space bar, and enemies disappear when you hit them. Great job! +**Game Development Concepts Mastered**: +- **Physics Simulation**: Real-time collision detection and response +- **Performance Engineering**: Optimized algorithms for interactive applications +- **Event Systems**: Decoupled communication between game components +- **Object Management**: Efficient lifecycle patterns for dynamic content +- **Input Handling**: Responsive controls with appropriate feedback + +**Next Level**: You're ready to explore advanced physics engines like Matter.js, implement 3D collision detection, or build complex particle systems! + +🌟 **Achievement Unlocked**: You've built a complete physics-based interaction system with professional-grade collision detection! + +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Enhance the collision detection system by implementing power-ups that spawn randomly and provide temporary abilities when collected by the hero ship. + +**Prompt:** Create a PowerUp class that extends GameObject and implement collision detection between the hero and power-ups. Add at least two types of power-ups: one that increases fire rate (reduces cooldown) and another that creates a temporary shield. Include spawn logic that creates power-ups at random intervals and positions. --- + + ## 🚀 Challenge -Add an explosion! Check out the game assets in [the Space Art repo](../../../../6-space-game/solution/spaceArt/readme.txt) and try to add an explosion effect when the laser hits an alien. +Add an explosion! Take a look at the game assets in [the Space Art repo](../../../../6-space-game/solution/spaceArt/readme.txt) and try to add an explosion when the laser hits an alien ## Post-Lecture Quiz @@ -299,7 +753,7 @@ Add an explosion! Check out the game assets in [the Space Art repo](../../../../ ## Review & Self Study -Experiment with the intervals in your game so far. What happens when you change them? Read more about [JavaScript timing events](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/). +Experiment with the intervals in your game thus far. What happens when you change them? Read more about [JavaScript timing events](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/). ## Assignment @@ -307,5 +761,7 @@ Experiment with the intervals in your game so far. What happens when you change --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/4-collision-detection/assignment.md b/translations/en/6-space-game/4-collision-detection/assignment.md index e4e9a153e..2c79bfabb 100644 --- a/translations/en/6-space-game/4-collision-detection/assignment.md +++ b/translations/en/6-space-game/4-collision-detection/assignment.md @@ -1,25 +1,55 @@ - # Explore Collisions ## Instructions -To gain a better understanding of how collisions work, create a small game with a few objects that collide. Make them move using key presses or mouse clicks, and ensure that something happens to one of the objects when it gets hit. For example, it could be a meteor crashing into the earth or bumper cars colliding. Be creative! +Apply your collision detection knowledge by creating a custom mini-game that demonstrates different types of object interactions. This assignment will help you understand collision mechanics through creative implementation and experimentation. + +### Project requirements + +**Create a small interactive game featuring:** +- **Multiple moving objects** that can be controlled via keyboard or mouse input +- **Collision detection system** using rectangle intersection principles from the lesson +- **Visual feedback** when collisions occur (object destruction, color changes, effects) +- **Game rules** that make collisions meaningful and engaging + +### Creative suggestions + +**Consider implementing one of these scenarios:** +- **Asteroid field**: Navigate a ship through dangerous space debris +- **Bumper cars**: Create a physics-based collision arena +- **Meteor defense**: Protect Earth from incoming space rocks +- **Collection game**: Gather items while avoiding obstacles +- **Territory control**: Competing objects trying to claim space + +### Technical implementation + +**Your solution should demonstrate:** +- Proper use of rectangle-based collision detection +- Event-driven programming for user input +- Object lifecycle management (creation and destruction) +- Clean code organization with appropriate class structure + +### Bonus challenges + +**Enhance your game with additional features:** +- **Particle effects** when collisions occur +- **Sound effects** for different collision types +- **Scoring system** based on collision outcomes +- **Multiple collision types** with different behaviors +- **Progressive difficulty** that increases over time ## Rubric -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | ----------------- | -| | A complete, functional code sample is provided, with objects drawn on the canvas, basic collisions occurring, and reactions implemented | Code is incomplete in some way | Code does not work | +| Criteria | Exemplary | Adequate | Needs Improvement | +|----------|-----------|----------|-------------------| +| **Collision Detection** | Implements accurate rectangle-based collision detection with multiple object types and sophisticated interaction rules | Basic collision detection works correctly with simple object interactions | Collision detection has issues or doesn't work consistently | +| **Code Quality** | Clean, well-organized code with proper class structure, meaningful variable names, and appropriate comments | Code works but could be better organized or documented | Code is difficult to understand or poorly structured | +| **User Interaction** | Responsive controls with smooth gameplay, clear visual feedback, and engaging mechanics | Basic controls work with adequate feedback | Controls are unresponsive or confusing | +| **Creativity** | Original concept with unique features, visual polish, and innovative collision behaviors | Standard implementation with some creative elements | Basic functionality without creative enhancements | --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/4-collision-detection/solution/README.md b/translations/en/6-space-game/4-collision-detection/solution/README.md index 85bbb7eb5..b78db64df 100644 --- a/translations/en/6-space-game/4-collision-detection/solution/README.md +++ b/translations/en/6-space-game/4-collision-detection/solution/README.md @@ -1,12 +1,3 @@ - This is a placeholder, left blank purposefully --- diff --git a/translations/en/6-space-game/4-collision-detection/your-work/README.md b/translations/en/6-space-game/4-collision-detection/your-work/README.md index a33d8c39f..b78db64df 100644 --- a/translations/en/6-space-game/4-collision-detection/your-work/README.md +++ b/translations/en/6-space-game/4-collision-detection/your-work/README.md @@ -1,12 +1,3 @@ - This is a placeholder, left blank purposefully --- diff --git a/translations/en/6-space-game/5-keeping-score/README.md b/translations/en/6-space-game/5-keeping-score/README.md index f86e864a1..bc1234fd6 100644 --- a/translations/en/6-space-game/5-keeping-score/README.md +++ b/translations/en/6-space-game/5-keeping-score/README.md @@ -1,23 +1,80 @@ - # Build a Space Game Part 5: Scoring and Lives +```mermaid +journey + title Your Game Design Journey + section Player Feedback + Understand scoring psychology: 3: Student + Learn visual communication: 4: Student + Design reward systems: 4: Student + section Technical Implementation + Canvas text rendering: 4: Student + State management: 5: Student + Event-driven updates: 5: Student + section Game Polish + User experience design: 5: Student + Balance challenge and reward: 5: Student + Create engaging gameplay: 5: Student +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/37) -In this lesson, you'll learn how to add scoring to a game and manage lives. +Ready to make your space game feel like a real game? Let's add scoring points and managing lives - the core mechanics that transformed early arcade games like Space Invaders from simple demonstrations into addictive entertainment. This is where your game becomes truly playable. + +```mermaid +mindmap + root((Game Feedback Systems)) + Visual Communication + Text Rendering + Icon Display + Color Psychology + Layout Design + Scoring Mechanics + Point Values + Reward Timing + Progress Tracking + Achievement Systems + Life Management + Risk vs Reward + Player Agency + Difficulty Balance + Recovery Mechanics + User Experience + Immediate Feedback + Clear Information + Emotional Response + Engagement Loops + Implementation + Canvas API + State Management + Event Systems + Performance +``` +## Drawing Text on Screen - Your Game's Voice -## Draw text on the screen +To display your score, we need to learn how to render text on the canvas. The `fillText()` method is your primary tool for this - it's the same technique used in classic arcade games to show scores and status information. -To display a game score on the screen, you need to know how to render text. The solution is using the `fillText()` method on the canvas object. You can also customize aspects like the font, text color, and alignment (left, right, center). Below is an example of code that draws text on the screen. +```mermaid +flowchart LR + A["📝 Text Content"] --> B["🎨 Styling"] + B --> C["📍 Positioning"] + C --> D["🖼️ Canvas Render"] + + E["Font Family"] --> B + F["Font Size"] --> B + G["Color"] --> B + H["Alignment"] --> B + + I["X Coordinate"] --> C + J["Y Coordinate"] --> C + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 +``` +You have complete control over the text appearance: ```javascript ctx.font = "30px Arial"; @@ -26,22 +83,74 @@ ctx.textAlign = "right"; ctx.fillText("show this on the screen", 0, 0); ``` -✅ Learn more about [how to add text to a canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text), and feel free to make your text look more stylish! +✅ Dive deeper into [adding text to a canvas](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) - you might be surprised at how creative you can get with fonts and styling! + +## Lives - More Than Just a Number -## Life, as a game concept +In game design, a "life" represents the player's margin for error. This concept dates back to pinball machines, where you'd get multiple balls to play with. In early video games like Asteroids, lives gave players permission to take risks and learn from mistakes. -In games, the concept of "life" is simply a number. In a space game, it's common to assign a set number of lives that decrease one by one when your ship takes damage. It's even better if you can visually represent this with icons like small ships or hearts instead of just a number. +```mermaid +flowchart TD + A["🎮 Player Action"] --> B{"Risk Assessment"} + + B --> C["High Risk, High Reward"] + B --> D["Safe Strategy"] + + C --> E{"Outcome"} + D --> F["Steady Progress"] + + E -->|Success| G["🏆 Big Points"] + E -->|Failure| H["💔 Lose Life"] + + H --> I{"Lives Remaining?"} + I -->|Yes| J["🔄 Try Again"] + I -->|No| K["💀 Game Over"] + + J --> B + G --> B + F --> B + + style C fill:#ffebee + style D fill:#e8f5e8 + style G fill:#e3f2fd + style H fill:#fff3e0 +``` +Visual representation matters significantly - displaying ship icons instead of just "Lives: 3" creates immediate visual recognition, similar to how early arcade cabinets used iconography to communicate across language barriers. -## What to build +## Building Your Game's Reward System -Let's add the following features to your game: +Now we'll implement the core feedback systems that keep players engaged: -- **Game score**: Award points for every enemy ship destroyed. We suggest 100 points per ship. The score should be displayed in the bottom left corner. -- **Life**: Your ship starts with three lives. You lose a life whenever an enemy ship collides with you. Lives should be displayed in the bottom right corner using the following graphic: ![life image](../../../../translated_images/en/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.png). +```mermaid +sequenceDiagram + participant Player + participant GameEngine + participant ScoreSystem + participant LifeSystem + participant Display + + Player->>GameEngine: Shoots Enemy + GameEngine->>ScoreSystem: Award Points + ScoreSystem->>ScoreSystem: +100 points + ScoreSystem->>Display: Update Score + + Player->>GameEngine: Collides with Enemy + GameEngine->>LifeSystem: Lose Life + LifeSystem->>LifeSystem: -1 life + LifeSystem->>Display: Update Lives + + alt Lives > 0 + LifeSystem->>Player: Continue Playing + else Lives = 0 + LifeSystem->>GameEngine: Game Over + end +``` +- **Scoring system**: Each destroyed enemy ship awards 100 points (round numbers are easier for players to calculate mentally). The score displays in the bottom left corner. +- **Life counter**: Your hero starts with three lives - a standard established by early arcade games to balance challenge with playability. Each collision with an enemy costs one life. We'll display remaining lives in the bottom right using ship icons ![life image](../../../../translated_images/en/life.6fb9f50d53ee0413.webp). -## Recommended steps +## Let's Get Building! -Locate the files provided in the `your-work` subfolder. It should contain the following: +First, set up your workspace. Navigate to the files in your `your-work` sub folder. You should see these files: ```bash -| assets @@ -53,24 +162,49 @@ Locate the files provided in the `your-work` subfolder. It should contain the fo -| package.json ``` -Start your project in the `your_work` folder by typing: +To test your game, start the development server from the `your_work` folder: ```bash cd your-work npm start ``` -This will start an HTTP server at `http://localhost:5000`. Open a browser and navigate to that address. At this point, you should see the hero and all the enemies. You can move the hero using the left and right arrow keys and shoot down enemies. +This runs a local server at `http://localhost:5000`. Open this address in your browser to see your game. Test the controls with arrow keys and try shooting enemies to verify everything works. -### Add code +```mermaid +flowchart TD + A["1. Asset Loading"] --> B["2. Game Variables"] + B --> C["3. Collision Detection"] + C --> D["4. Hero Enhancement"] + D --> E["5. Display Functions"] + E --> F["6. Event Handlers"] + + G["Life Icon Image"] --> A + H["Score & Lives Tracking"] --> B + I["Hero-Enemy Intersections"] --> C + J["Points & Life Methods"] --> D + K["Text & Icon Rendering"] --> E + L["Reward & Penalty Logic"] --> F + + F --> M["🎮 Complete Game"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 + style F fill:#fce4ec + style M fill:#e1f5fe +``` +### Time to Code! -1. **Copy the required assets** from the `solution/assets/` folder into the `your-work` folder. This includes the `life.png` asset. Add the `lifeImg` to the `window.onload` function: +1. **Grab the visual assets you'll need**. Copy the `life.png` asset from the `solution/assets/` folder into your `your-work` folder. Then add the lifeImg to your window.onload function: ```javascript lifeImg = await loadTexture("assets/life.png"); ``` -1. Add the `lifeImg` to the list of assets: +1. Don't forget to add the `lifeImg` to your assets list: ```javascript let heroImg, @@ -80,9 +214,9 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na eventEmitter = new EventEmitter(); ``` -2. **Add variables**. Create variables to represent the total score (starting at 0) and remaining lives (starting at 3). Display these values on the screen. +2. **Set up your game variables**. Add some code to track your total score (starting at 0) and remaining lives (starting at 3). We'll display these on screen so players always know where they stand. -3. **Extend the `updateGameObjects()` function**. Modify the `updateGameObjects()` function to handle collisions with enemies: +3. **Implement collision detection**. Extend your `updateGameObjects()` function to detect when enemies collide with your hero: ```javascript enemies.forEach(enemy => { @@ -93,15 +227,15 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na }) ``` -4. **Add `life` and `points`**. - 1. **Initialize variables**. In the `Hero` class, under `this.cooldown = 0`, initialize the life and points variables: +4. **Add life and point tracking to your Hero**. + 1. **Initialize the counters**. Under `this.cooldown = 0` in your `Hero` class, set up life and points: ```javascript this.life = 3; this.points = 0; ``` - 1. **Draw variables on the screen**. Render these values on the screen: + 1. **Show these values to the player**. Create functions to draw these values on screen: ```javascript function drawLife() { @@ -128,18 +262,34 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na ``` - 1. **Add methods to the game loop**. Ensure these functions are added to the `window.onload` function under `updateGameObjects()`: + 1. **Hook everything into your game loop**. Add these functions to your window.onload function right after `updateGameObjects()`: ```javascript drawPoints(); drawLife(); ``` -1. **Implement game rules**. Add the following rules to your game: +### 🔄 **Pedagogical Check-in** +**Game Design Understanding**: Before implementing consequences, ensure you understand: +- ✅ How visual feedback communicates game state to players +- ✅ Why consistent placement of UI elements improves usability +- ✅ The psychology behind point values and life management +- ✅ How canvas text rendering differs from HTML text + +**Quick Self-Test**: Why do arcade games typically use round numbers for point values? +*Answer: Round numbers are easier for players to calculate mentally and create satisfying psychological rewards* + +**User Experience Principles**: You're now applying: +- **Visual Hierarchy**: Important information positioned prominently +- **Immediate Feedback**: Real-time updates to player actions +- **Cognitive Load**: Simple, clear information presentation +- **Emotional Design**: Icons and colors that create player connection + +1. **Implement game consequences and rewards**. Now we'll add the feedback systems that make player actions meaningful: - 1. **Deduct a life for every collision between the hero and an enemy**. + 1. **Collisions cost lives**. Every time your hero crashes into an enemy, you should lose a life. - Extend the `Hero` class to handle life deduction: + Add this method to your `Hero` class: ```javascript decrementLife() { @@ -150,9 +300,9 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na } ``` - 2. **Increase the score by 100 points for every laser that hits an enemy**. + 2. **Shooting enemies earns points**. Each successful hit awards 100 points, providing immediate positive feedback for accurate shooting. - Extend the `Hero` class to handle score increments: + Extend your Hero class with this increment method: ```javascript incrementPoints() { @@ -160,7 +310,7 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na } ``` - Add these functions to your collision event emitters: + Now connect these functions to your collision events: ```javascript eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { @@ -175,15 +325,161 @@ This will start an HTTP server at `http://localhost:5000`. Open a browser and na }); ``` -✅ Explore other games built using JavaScript/Canvas. What common features do they share? - -By the end of this task, you should see small "life" icons in the bottom right corner, points displayed in the bottom left corner, and observe your life count decrease when colliding with enemies and your score increase when shooting enemies. Great job! Your game is almost finished. +✅ Curious about other games built with JavaScript and Canvas? Do some exploring - you might be amazed at what's possible! + +After implementing these features, test your game to see the complete feedback system in action. You should see life icons in the bottom right, your score in the bottom left, and watch as collisions reduce lives while successful shots increase your score. + +Your game now has the essential mechanics that made early arcade games so compelling - clear goals, immediate feedback, and meaningful consequences for player actions. + +### 🔄 **Pedagogical Check-in** +**Complete Game Design System**: Verify your mastery of player feedback systems: +- ✅ How do scoring mechanics create player motivation and engagement? +- ✅ Why is visual consistency important for user interface design? +- ✅ How does the life system balance challenge with player retention? +- ✅ What role does immediate feedback play in creating satisfying gameplay? + +**System Integration**: Your feedback system demonstrates: +- **User Experience Design**: Clear visual communication and information hierarchy +- **Event-Driven Architecture**: Responsive updates to player actions +- **State Management**: Tracking and displaying dynamic game data +- **Canvas Mastery**: Text rendering and sprite positioning +- **Game Psychology**: Understanding player motivation and engagement + +**Professional Patterns**: You've implemented: +- **MVC Architecture**: Separation of game logic, data, and presentation +- **Observer Pattern**: Event-driven updates for game state changes +- **Component Design**: Reusable functions for rendering and logic +- **Performance Optimization**: Efficient rendering in game loops + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Experiment with different font sizes and colors for the score display +- [ ] Try changing the point values and see how it affects gameplay feel +- [ ] Add console.log statements to track when points and lives change +- [ ] Test edge cases like running out of lives or achieving high scores + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and understand game design psychology +- [ ] Add sound effects for scoring and losing lives +- [ ] Implement a high score system using localStorage +- [ ] Create different point values for different enemy types +- [ ] Add visual effects like screen shake when losing a life + +### 📅 **Your Week-Long Game Design Journey** +- [ ] Complete the full space game with polished feedback systems +- [ ] Implement advanced scoring mechanics like combo multipliers +- [ ] Add achievements and unlockable content +- [ ] Create difficulty progression and balancing systems +- [ ] Design user interfaces for menus and game over screens +- [ ] Study other games to understand engagement mechanisms + +### 🌟 **Your Month-Long Game Development Mastery** +- [ ] Build complete games with sophisticated progression systems +- [ ] Learn game analytics and player behavior measurement +- [ ] Contribute to open source game development projects +- [ ] Master advanced game design patterns and monetization +- [ ] Create educational content about game design and user experience +- [ ] Build a portfolio showcasing game design and development skills + +## 🎯 Your Game Design Mastery Timeline + +```mermaid +timeline + title Game Design & Player Feedback Learning Progression + + section Foundation (10 minutes) + Visual Communication: Text rendering + : Icon design + : Layout principles + : Color psychology + + section Player Psychology (20 minutes) + Motivation Systems: Point values + : Risk vs reward + : Progress feedback + : Achievement design + + section Technical Implementation (30 minutes) + Canvas Mastery: Text positioning + : Sprite rendering + : State management + : Performance optimization + + section Game Balance (40 minutes) + Difficulty Design: Life management + : Scoring curves + : Player retention + : Accessibility + + section User Experience (50 minutes) + Interface Design: Information hierarchy + : Responsive feedback + : Emotional design + : Usability testing + + section Advanced Systems (1 week) + Game Mechanics: Progression systems + : Analytics integration + : Monetization design + : Community features + + section Industry Skills (1 month) + Professional Development: Team collaboration + : Design documentation + : Player research + : Platform optimization +``` +### 🛠️ Your Game Design Toolkit Summary + +After completing this lesson, you now have mastered: +- **Player Psychology**: Understanding motivation, risk/reward, and engagement loops +- **Visual Communication**: Effective UI design using text, icons, and layout +- **Feedback Systems**: Real-time response to player actions and game events +- **State Management**: Tracking and displaying dynamic game data efficiently +- **Canvas Text Rendering**: Professional text display with styling and positioning +- **Event Integration**: Connecting user actions to meaningful game consequences +- **Game Balance**: Designing difficulty curves and player progression systems + +**Real-World Applications**: Your game design skills apply directly to: +- **User Interface Design**: Creating engaging and intuitive interfaces +- **Product Development**: Understanding user motivation and feedback loops +- **Educational Technology**: Gamification and learning engagement systems +- **Data Visualization**: Making complex information accessible and engaging +- **Mobile App Development**: Retention mechanics and user experience design +- **Marketing Technology**: Understanding user behavior and conversion optimization + +**Professional Skills Gained**: You can now: +- **Design** user experiences that motivate and engage users +- **Implement** feedback systems that guide user behavior effectively +- **Balance** challenge and accessibility in interactive systems +- **Create** visual communication that works across different user groups +- **Analyze** user behavior and iterate on design improvements + +**Game Development Concepts Mastered**: +- **Player Motivation**: Understanding what drives engagement and retention +- **Visual Design**: Creating clear, attractive, and functional interfaces +- **System Integration**: Connecting multiple game systems for cohesive experience +- **Performance Optimization**: Efficient rendering and state management +- **Accessibility**: Designing for different skill levels and player needs + +**Next Level**: You're ready to explore advanced game design patterns, implement analytics systems, or study game monetization and player retention strategies! + +🌟 **Achievement Unlocked**: You've built a complete player feedback system with professional game design principles! --- +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Enhance the space game's scoring system by implementing a high score feature with persistent storage and bonus scoring mechanics. + +**Prompt:** Create a high score system that saves the player's best score to localStorage. Add bonus points for consecutive enemy kills (combo system) and implement different point values for different enemy types. Include a visual indicator when the player achieves a new high score and display the current high score on the game screen. + + + ## 🚀 Challenge -Your code is nearly complete. What do you think your next steps should be? +You now have a functional game with scoring and lives. Consider what additional features might enhance the player experience. ## Post-Lecture Quiz @@ -191,7 +487,7 @@ Your code is nearly complete. What do you think your next steps should be? ## Review & Self Study -Research different ways to increment and decrement game scores and lives. There are some interesting game engines like [PlayFab](https://playfab.com). How could using one of these enhance your game? +Want to explore more? Research different approaches to game scoring and life systems. There are fascinating game engines out there like [PlayFab](https://playfab.com) that handle scoring, leaderboards, and player progression. How might integrating something like that take your game to the next level? ## Assignment @@ -199,5 +495,7 @@ Research different ways to increment and decrement game scores and lives. There --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/5-keeping-score/assignment.md b/translations/en/6-space-game/5-keeping-score/assignment.md index 33eb35343..15402715c 100644 --- a/translations/en/6-space-game/5-keeping-score/assignment.md +++ b/translations/en/6-space-game/5-keeping-score/assignment.md @@ -1,12 +1,3 @@ - # Build a Scoring Game ## Instructions diff --git a/translations/en/6-space-game/5-keeping-score/solution/README.md b/translations/en/6-space-game/5-keeping-score/solution/README.md index ef65711ee..b78db64df 100644 --- a/translations/en/6-space-game/5-keeping-score/solution/README.md +++ b/translations/en/6-space-game/5-keeping-score/solution/README.md @@ -1,12 +1,3 @@ - This is a placeholder, left blank purposefully --- diff --git a/translations/en/6-space-game/5-keeping-score/your-work/README.md b/translations/en/6-space-game/5-keeping-score/your-work/README.md index 11b54d1ed..b78db64df 100644 --- a/translations/en/6-space-game/5-keeping-score/your-work/README.md +++ b/translations/en/6-space-game/5-keeping-score/your-work/README.md @@ -1,12 +1,3 @@ - This is a placeholder, left blank purposefully --- diff --git a/translations/en/6-space-game/6-end-condition/README.md b/translations/en/6-space-game/6-end-condition/README.md index 997a1c9c7..9f5ebde98 100644 --- a/translations/en/6-space-game/6-end-condition/README.md +++ b/translations/en/6-space-game/6-end-condition/README.md @@ -1,41 +1,154 @@ - # Build a Space Game Part 6: End and Restart +```mermaid +journey + title Your Game Completion Journey + section End Conditions + Define win/lose states: 3: Student + Implement condition checking: 4: Student + Handle state transitions: 4: Student + section Player Experience + Design feedback systems: 4: Student + Create restart mechanics: 5: Student + Polish user interface: 5: Student + section System Integration + Manage game lifecycle: 5: Student + Handle memory cleanup: 5: Student + Create complete experience: 5: Student +``` +Every great game needs clear end conditions and a smooth restart mechanism. You've built an impressive space game with movement, combat, and scoring - now it's time to add the final pieces that make it feel complete. + +Your game currently runs indefinitely, like the Voyager probes that NASA launched in 1977 - still traveling through space decades later. While that's fine for space exploration, games need defined endpoints to create satisfying experiences. + +Today, we'll implement proper win/lose conditions and a restart system. By the end of this lesson, you'll have a polished game that players can complete and replay, just like the classic arcade games that defined the medium. + +```mermaid +mindmap + root((Game Completion)) + End Conditions + Victory States + Defeat Conditions + Progress Tracking + State Validation + Player Feedback + Visual Messages + Color Psychology + Clear Communication + Emotional Response + State Management + Game Loop Control + Memory Cleanup + Object Lifecycle + Event Handling + Restart Systems + Input Handling + State Reset + Fresh Initialization + User Experience + Polish Elements + Message Display + Smooth Transitions + Error Prevention + Accessibility +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/39) -There are various ways to define an *end condition* in a game. As the creator, it's up to you to decide why the game ends. Here are some possible reasons, assuming we're talking about the space game you've been building so far: +## Understanding Game End Conditions -- **`N` Enemy ships have been destroyed**: It's common in games divided into levels to require the destruction of `N` enemy ships to complete a level. -- **Your ship has been destroyed**: In some games, you lose if your ship is destroyed. Another common approach is to introduce the concept of lives. Each time your ship is destroyed, you lose a life. Once all lives are gone, the game ends. -- **You've collected `N` points**: Another typical end condition is reaching a certain number of points. Points can be earned in various ways, such as destroying enemy ships or collecting items dropped when ships are destroyed. -- **Complete a level**: This might involve multiple conditions, such as destroying `X` enemy ships, collecting `Y` points, or obtaining a specific item. +When should your game end? This fundamental question has shaped game design since the early arcade era. Pac-Man ends when you're caught by ghosts or clear all dots, while Space Invaders ends when aliens reach the bottom or you destroy them all. -## Restarting +As the game creator, you define the victory and defeat conditions. For our space game, here are proven approaches that create engaging gameplay: -If players enjoy your game, they'll likely want to replay it. When the game ends for any reason, you should provide an option to restart. +```mermaid +flowchart TD + A["🎮 Game Start"] --> B{"Check Conditions"} + + B --> C["Enemy Count"] + B --> D["Hero Lives"] + B --> E["Score Threshold"] + B --> F["Level Progress"] + + C --> C1{"Enemies = 0?"} + D --> D1{"Lives = 0?"} + E --> E1{"Score ≥ Target?"} + F --> F1{"Objectives Complete?"} + + C1 -->|Yes| G["🏆 Victory"] + D1 -->|Yes| H["💀 Defeat"] + E1 -->|Yes| G + F1 -->|Yes| G + + C1 -->|No| B + D1 -->|No| B + E1 -->|No| B + F1 -->|No| B + + G --> I["🔄 Restart Option"] + H --> I + + style G fill:#e8f5e8 + style H fill:#ffebee + style I fill:#e3f2fd +``` +- **`N` Enemy ships have been destroyed**: It's quite common if you divide up a game into different levels that you need to destroy `N` Enemy ships to complete a level +- **Your ship has been destroyed**: There are definitely games where you lose the game if your ship is destroyed. Another common approach is that you have the concept of lives. Every time a your ship is destroyed it deducts a life. Once all lives have been lost then you lose the game. +- **You've collected `N` points**: Another common end condition is for you to collect points. How you get points is up to you but it's quite common to assign points to various activities like destroying an enemy ship or maybe collect items that items *drop* when they are destroyed. +- **Complete a level**: This might involve several conditions such as `X` enemy ships destroyed, `Y` points collected or maybe that a specific item has been collected. -✅ Take a moment to think about the conditions under which a game ends and how you're prompted to restart. +## Implementing Game Restart Functionality -## What to build +Good games encourage replayability through smooth restart mechanisms. When players complete a game (or meet defeat), they often want to try again immediately - whether to beat their score or improve their performance. -You will add the following rules to your game: +```mermaid +stateDiagram-v2 + [*] --> Playing: Game Start + Playing --> Victory: All enemies destroyed + Playing --> Defeat: Lives = 0 + + Victory --> MessageDisplay: Show win message + Defeat --> MessageDisplay: Show lose message + + MessageDisplay --> WaitingRestart: Press Enter prompt + WaitingRestart --> Resetting: Enter key pressed + + Resetting --> CleanupMemory: Clear intervals + CleanupMemory --> ClearEvents: Remove listeners + ClearEvents --> InitializeGame: Fresh start + InitializeGame --> Playing: New game begins + + note right of MessageDisplay + Color-coded feedback: + Green = Victory + Red = Defeat + end note + + note right of Resetting + Complete state reset + prevents memory leaks + end note +``` +Tetris exemplifies this perfectly: when your blocks reach the top, you can instantly start a new game without navigating complex menus. We'll build a similar restart system that cleanly resets the game state and gets players back into action quickly. + +✅ **Reflection**: Think about the games you've played. Under what conditions do they end, and how are you prompted to restart? What makes a restart experience feel smooth versus frustrating? + +## What You'll Build + +You'll implement the final features that transform your project into a complete game experience. These elements distinguish polished games from basic prototypes. + +**Here's what we're adding today:** + +1. **Victory condition**: Blast all the enemies and get a proper celebration (you've earned it!) +2. **Defeat condition**: Run out of lives and face the music with a defeat screen +3. **Restart mechanism**: Hit Enter to jump right back in - because one game is never enough +4. **State management**: Clean slate every time - no leftover enemies or weird glitches from the last game -1. **Winning the game**: When all enemy ships are destroyed, the player wins. Display a victory message to indicate this. -2. **Restart**: When all lives are lost or the game is won, provide an option to restart. Remember to reinitialize the game and clear the previous game state. +## Getting Started -## Recommended steps +Let's prepare your development environment. You should have all your space game files from the previous lessons ready. -Locate the files in the `your-work` subfolder. It should contain the following: +**Your project should look something like this:** ```bash -| assets @@ -48,175 +161,500 @@ Locate the files in the `your-work` subfolder. It should contain the following: -| package.json ``` -Start your project in the `your_work` folder by typing: +**Start your development server:** ```bash cd your-work npm start ``` -This will start an HTTP server at `http://localhost:5000`. Open a browser and navigate to that address. Your game should be in a playable state. +**This command:** +- Runs a local server on `http://localhost:5000` +- Serves your files properly +- Automatically refreshes when you make changes -> tip: To avoid warnings in Visual Studio Code, edit the `window.onload` function to call `gameLoopId` as is (without `let`), and declare `gameLoopId` at the top of the file independently: `let gameLoopId;` +Open `http://localhost:5000` in your browser and verify your game is running. You should be able to move, shoot, and interact with enemies. Once confirmed, we can proceed with the implementation. + +> 💡 **Pro Tip**: To avoid warnings in Visual Studio Code, declare `gameLoopId` at the top of your file as `let gameLoopId;` instead of declaring it inside the `window.onload` function. This follows modern JavaScript variable declaration best practices. + +```mermaid +flowchart TD + A["1. Condition Tracking"] --> B["2. Event Handlers"] + B --> C["3. Message Constants"] + C --> D["4. Restart Controls"] + D --> E["5. Message Display"] + E --> F["6. Reset System"] + + G["isHeroDead()\nisEnemiesDead()"] --> A + H["Collision Events\nEnd Game Events"] --> B + I["GAME_END_WIN\nGAME_END_LOSS"] --> C + J["Enter Key\nRestart Trigger"] --> D + K["Victory/Defeat\nColor-coded Text"] --> E + L["State Cleanup\nFresh Initialization"] --> F + + F --> M["🎮 Complete Game"] + + style A fill:#e3f2fd + style B fill:#e8f5e8 + style C fill:#fff3e0 + style D fill:#f3e5f5 + style E fill:#e0f2f1 + style F fill:#fce4ec + style M fill:#e1f5fe +``` +## Implementation Steps -### Add code +### Step 1: Create End Condition Tracking Functions -1. **Track end condition**: Add code to track the number of enemies or whether the hero ship has been destroyed by adding these two functions: +We need functions to monitor when the game should end. Like sensors on the International Space Station that constantly monitor critical systems, these functions will continuously check the game state. - ```javascript - function isHeroDead() { - return hero.life <= 0; +```javascript +function isHeroDead() { + return hero.life <= 0; +} + +function isEnemiesDead() { + const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead); + return enemies.length === 0; +} +``` + +**Here's what's happening under the hood:** +- **Checks** if our hero is out of lives (ouch!) +- **Counts** how many enemies are still alive and kicking +- **Returns** `true` when the battlefield is clear of enemies +- **Uses** simple true/false logic to keep things straightforward +- **Filters** through all game objects to find the survivors + +### Step 2: Update Event Handlers for End Conditions + +Now we'll connect these condition checks to the game's event system. Every time a collision occurs, the game will evaluate whether it triggers an end condition. This creates immediate feedback for critical game events. + +```mermaid +sequenceDiagram + participant Collision + participant GameLogic + participant Conditions + participant EventSystem + participant Display + + Collision->>GameLogic: Laser hits enemy + GameLogic->>GameLogic: Destroy objects + GameLogic->>Conditions: Check isEnemiesDead() + + alt All enemies defeated + Conditions->>EventSystem: Emit GAME_END_WIN + EventSystem->>Display: Show victory message + else Enemies remain + Conditions->>GameLogic: Continue game + end + + Collision->>GameLogic: Enemy hits hero + GameLogic->>GameLogic: Decrease lives + GameLogic->>Conditions: Check isHeroDead() + + alt Lives = 0 + Conditions->>EventSystem: Emit GAME_END_LOSS + EventSystem->>Display: Show defeat message + else Lives remain + GameLogic->>Conditions: Check isEnemiesDead() + alt All enemies defeated + Conditions->>EventSystem: Emit GAME_END_WIN + end + end +``` +```javascript +eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { + first.dead = true; + second.dead = true; + hero.incrementPoints(); + + if (isEnemiesDead()) { + eventEmitter.emit(Messages.GAME_END_WIN); } +}); + +eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => { + enemy.dead = true; + hero.decrementLife(); + if (isHeroDead()) { + eventEmitter.emit(Messages.GAME_END_LOSS); + return; // loss before victory + } + if (isEnemiesDead()) { + eventEmitter.emit(Messages.GAME_END_WIN); + } +}); + +eventEmitter.on(Messages.GAME_END_WIN, () => { + endGame(true); +}); + +eventEmitter.on(Messages.GAME_END_LOSS, () => { + endGame(false); +}); +``` + +**What's going on here:** +- **Laser hits enemy**: Both disappear, you get points, and we check if you've won +- **Enemy hits you**: You lose a life, and we check if you're still breathing +- **Smart ordering**: We check for defeat first (nobody wants to win and lose at the same time!) +- **Instant reactions**: As soon as something important happens, the game knows about it + +### Step 3: Add New Message Constants + +You'll need to add new message types to your `Messages` constant object. These constants help maintain consistency and prevent typos in your event system. + +```javascript +GAME_END_LOSS: "GAME_END_LOSS", +GAME_END_WIN: "GAME_END_WIN", +``` + +**In the above, we've:** +- **Added** constants for game end events to maintain consistency +- **Used** descriptive names that clearly indicate the event purpose +- **Followed** the existing naming convention for message types + +### Step 4: Implement Restart Controls + +Now you'll add keyboard controls that allow players to restart the game. The Enter key is a natural choice since it's commonly associated with confirming actions and starting new games. + +**Add Enter key detection to your existing keydown event listener:** + +```javascript +else if(evt.key === "Enter") { + eventEmitter.emit(Messages.KEY_EVENT_ENTER); +} +``` + +**Add the new message constant:** + +```javascript +KEY_EVENT_ENTER: "KEY_EVENT_ENTER", +``` + +**What you need to know:** +- **Extends** your existing keyboard event handling system +- **Uses** the Enter key as the restart trigger for intuitive user experience +- **Emits** a custom event that other parts of your game can listen for +- **Maintains** the same pattern as your other keyboard controls + +### Step 5: Create the Message Display System - function isEnemiesDead() { - const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead); - return enemies.length === 0; +Your game needs to communicate results clearly to players. We'll create a message system that displays victory and defeat states using color-coded text, similar to the terminal interfaces of early computer systems where green indicated success and red signaled errors. + +**Create the `displayMessage()` function:** + +```javascript +function displayMessage(message, color = "red") { + ctx.font = "30px Arial"; + ctx.fillStyle = color; + ctx.textAlign = "center"; + ctx.fillText(message, canvas.width / 2, canvas.height / 2); +} +``` + +**Step by step, here's what's happening:** +- **Sets** the font size and family for clear, readable text +- **Applies** a color parameter with "red" as the default for warnings +- **Centers** the text horizontally and vertically on the canvas +- **Uses** modern JavaScript default parameters for flexible color options +- **Leverages** the canvas 2D context for direct text rendering + +**Create the `endGame()` function:** + +```javascript +function endGame(win) { + clearInterval(gameLoopId); + + // Set a delay to ensure any pending renders complete + setTimeout(() => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + if (win) { + displayMessage( + "Victory!!! Pew Pew... - Press [Enter] to start a new game Captain Pew Pew", + "green" + ); + } else { + displayMessage( + "You died !!! Press [Enter] to start a new game Captain Pew Pew" + ); } - ``` - -2. **Add logic to message handlers**: Update the `eventEmitter` to handle these conditions: - - ```javascript - eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { - first.dead = true; - second.dead = true; - hero.incrementPoints(); - - if (isEnemiesDead()) { - eventEmitter.emit(Messages.GAME_END_WIN); - } - }); - - eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => { - enemy.dead = true; - hero.decrementLife(); - if (isHeroDead()) { - eventEmitter.emit(Messages.GAME_END_LOSS); - return; // loss before victory - } - if (isEnemiesDead()) { - eventEmitter.emit(Messages.GAME_END_WIN); - } - }); - - eventEmitter.on(Messages.GAME_END_WIN, () => { - endGame(true); - }); - - eventEmitter.on(Messages.GAME_END_LOSS, () => { - endGame(false); - }); - ``` - -3. **Add new message types**: Add these messages to the constants object: - - ```javascript - GAME_END_LOSS: "GAME_END_LOSS", - GAME_END_WIN: "GAME_END_WIN", - ``` - -4. **Add restart code**: Implement code to restart the game when a specific button is pressed. - - 1. **Listen for the `Enter` key press**: Update your window's eventListener to detect this key press: - - ```javascript - else if(evt.key === "Enter") { - eventEmitter.emit(Messages.KEY_EVENT_ENTER); - } - ``` - - 2. **Add a restart message**: Add this message to your Messages constant: - - ```javascript - KEY_EVENT_ENTER: "KEY_EVENT_ENTER", - ``` - -5. **Implement game rules**: Add the following game rules: - - 1. **Player win condition**: When all enemy ships are destroyed, display a victory message. - - 1. First, create a `displayMessage()` function: - - ```javascript - function displayMessage(message, color = "red") { - ctx.font = "30px Arial"; - ctx.fillStyle = color; - ctx.textAlign = "center"; - ctx.fillText(message, canvas.width / 2, canvas.height / 2); - } - ``` - - 2. Then, create an `endGame()` function: - - ```javascript - function endGame(win) { - clearInterval(gameLoopId); + }, 200) +} +``` + +**What this function does:** +- **Freezes** everything in place - no more moving ships or lasers +- **Takes** a tiny pause (200ms) to let the last frame finish drawing +- **Wipes** the screen clean and paints it black for dramatic effect +- **Shows** different messages for winners and losers +- **Color codes** the news - green for good, red for... well, not so good +- **Tells** players exactly how to jump back in + +### 🔄 **Pedagogical Check-in** +**Game State Management**: Before implementing reset functionality, ensure you understand: +- ✅ How end conditions create clear gameplay objectives +- ✅ Why visual feedback is essential for player understanding +- ✅ The importance of proper cleanup in preventing memory leaks +- ✅ How event-driven architecture enables clean state transitions + +**Quick Self-Test**: What would happen if you didn't clear event listeners during reset? +*Answer: Memory leaks and duplicate event handlers causing unpredictable behavior* + +**Game Design Principles**: You're now implementing: +- **Clear Objectives**: Players know exactly what defines success and failure +- **Immediate Feedback**: Game state changes are communicated instantly +- **User Control**: Players can restart when they're ready +- **System Reliability**: Proper cleanup prevents bugs and performance issues + +### Step 6: Implement Game Reset Functionality + +The reset system needs to completely clean up the current game state and initialize a fresh game session. This ensures players get a clean start without any leftover data from the previous game. + +**Create the `resetGame()` function:** + +```javascript +function resetGame() { + if (gameLoopId) { + clearInterval(gameLoopId); + eventEmitter.clear(); + initGame(); + gameLoopId = setInterval(() => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + drawPoints(); + drawLife(); + updateGameObjects(); + drawGameObjects(ctx); + }, 100); + } +} +``` + +**Let's understand each part:** +- **Checks** if a game loop is currently running before resetting +- **Clears** the existing game loop to stop all current game activity +- **Removes** all event listeners to prevent memory leaks +- **Reinitializes** the game state with fresh objects and variables +- **Starts** a new game loop with all the essential game functions +- **Maintains** the same 100ms interval for consistent game performance + +**Add the Enter key event handler to your `initGame()` function:** + +```javascript +eventEmitter.on(Messages.KEY_EVENT_ENTER, () => { + resetGame(); +}); +``` + +**Add the `clear()` method to your EventEmitter class:** + +```javascript +clear() { + this.listeners = {}; +} +``` + +**Key points to remember:** +- **Connects** the Enter key press to the reset game functionality +- **Registers** this event listener during game initialization +- **Provides** a clean way to remove all event listeners when resetting +- **Prevents** memory leaks by clearing event handlers between games +- **Resets** the listeners object to an empty state for fresh initialization + +## Congratulations! 🎉 + +👽 💥 🚀 You've successfully built a complete game from the ground up. Like the programmers who created the first video games in the 1970s, you've transformed lines of code into an interactive experience with proper game mechanics and user feedback. 🚀 💥 👽 + +**You've accomplished:** +- **Implemented** complete win and lose conditions with user feedback +- **Created** a seamless restart system for continuous gameplay +- **Designed** clear visual communication for game states +- **Managed** complex game state transitions and cleanup +- **Assembled** all components into a cohesive, playable game + +### 🔄 **Pedagogical Check-in** +**Complete Game Development System**: Celebrate your mastery of the full game development cycle: +- ✅ How do end conditions create satisfying player experiences? +- ✅ Why is proper state management critical for game stability? +- ✅ How does visual feedback enhance player understanding? +- ✅ What role does the restart system play in player retention? + +**System Mastery**: Your complete game demonstrates: +- **Full-Stack Game Development**: From graphics to input to state management +- **Professional Architecture**: Event-driven systems with proper cleanup +- **User Experience Design**: Clear feedback and intuitive controls +- **Performance Optimization**: Efficient rendering and memory management +- **Polish and Completeness**: All the details that make a game feel finished + +**Industry-Ready Skills**: You've implemented: +- **Game Loop Architecture**: Real-time systems with consistent performance +- **Event-Driven Programming**: Decoupled systems that scale effectively +- **State Management**: Complex data handling and lifecycle management +- **User Interface Design**: Clear communication and responsive controls +- **Testing and Debugging**: Iterative development and problem-solving + +### ⚡ **What You Can Do in the Next 5 Minutes** +- [ ] Play your complete game and test all victory and defeat conditions +- [ ] Experiment with different end condition parameters +- [ ] Try adding console.log statements to track game state changes +- [ ] Share your game with friends and gather feedback + +### 🎯 **What You Can Accomplish This Hour** +- [ ] Complete the post-lesson quiz and reflect on your game development journey +- [ ] Add audio effects for victory and defeat states +- [ ] Implement additional end conditions like time limits or bonus objectives +- [ ] Create different difficulty levels with varying enemy counts +- [ ] Polish the visual presentation with better fonts and colors + +### 📅 **Your Week-Long Game Development Mastery** +- [ ] Complete the enhanced space game with multiple levels and progression +- [ ] Add advanced features like power-ups, different enemy types, and special weapons +- [ ] Create a high score system with persistent storage +- [ ] Design user interfaces for menus, settings, and game options +- [ ] Optimize performance for different devices and browsers +- [ ] Deploy your game online and share it with the community + +### 🌟 **Your Month-Long Game Development Career** +- [ ] Build multiple complete games exploring different genres and mechanics +- [ ] Learn advanced game development frameworks like Phaser or Three.js +- [ ] Contribute to open source game development projects +- [ ] Study game design principles and player psychology +- [ ] Create a portfolio showcasing your game development skills +- [ ] Connect with the game development community and continue learning + +## 🎯 Your Complete Game Development Mastery Timeline + +```mermaid +timeline + title Complete Game Development Learning Progression + + section Foundation (Lessons 1-2) + Game Architecture: Project structure + : Asset management + : Canvas basics + : Event systems - // set a delay so we are sure any paints have finished - setTimeout(() => { - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = "black"; - ctx.fillRect(0, 0, canvas.width, canvas.height); - if (win) { - displayMessage( - "Victory!!! Pew Pew... - Press [Enter] to start a new game Captain Pew Pew", - "green" - ); - } else { - displayMessage( - "You died !!! Press [Enter] to start a new game Captain Pew Pew" - ); - } - }, 200) - } - ``` - - 2. **Restart logic**: When all lives are lost or the player wins, display a message indicating the game can be restarted. Restart the game when the restart key is pressed (you can choose which key to use). - - 1. Create the `resetGame()` function: - - ```javascript - function resetGame() { - if (gameLoopId) { - clearInterval(gameLoopId); - eventEmitter.clear(); - initGame(); - gameLoopId = setInterval(() => { - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = "black"; - ctx.fillRect(0, 0, canvas.width, canvas.height); - drawPoints(); - drawLife(); - updateGameObjects(); - drawGameObjects(ctx); - }, 100); - } - } - ``` - - 2. Add a call to the `eventEmitter` to reset the game in `initGame()`: - - ```javascript - eventEmitter.on(Messages.KEY_EVENT_ENTER, () => { - resetGame(); - }); - ``` - - 3. Add a `clear()` function to the EventEmitter: - - ```javascript - clear() { - this.listeners = {}; - } - ``` - -👽 💥 🚀 Congratulations, Captain! Your game is complete! Well done! 🚀 💥 👽 + section Interaction Systems (Lessons 3-4) + Player Control: Input handling + : Movement mechanics + : Collision detection + : Physics simulation + + section Game Mechanics (Lesson 5) + Feedback Systems: Scoring mechanisms + : Life management + : Visual communication + : Player motivation + + section Game Completion (Lesson 6) + Polish & Flow: End conditions + : State management + : Restart systems + : User experience + + section Advanced Features (1 week) + Enhancement Skills: Audio integration + : Visual effects + : Level progression + : Performance optimization + + section Professional Development (1 month) + Industry Readiness: Framework mastery + : Team collaboration + : Portfolio development + : Community engagement + + section Career Advancement (3 months) + Specialization: Advanced game engines + : Platform deployment + : Monetization strategies + : Industry networking +``` +### 🛠️ Your Complete Game Development Toolkit Summary ---- +After completing this entire space game series, you now have mastered: +- **Game Architecture**: Event-driven systems, game loops, and state management +- **Graphics Programming**: Canvas API, sprite rendering, and visual effects +- **Input Systems**: Keyboard handling, collision detection, and responsive controls +- **Game Design**: Player feedback, progression systems, and engagement mechanics +- **Performance Optimization**: Efficient rendering, memory management, and frame rate control +- **User Experience**: Clear communication, intuitive controls, and polish details +- **Professional Patterns**: Clean code, debugging techniques, and project organization + +**Real-World Applications**: Your game development skills apply directly to: +- **Interactive Web Applications**: Dynamic interfaces and real-time systems +- **Data Visualization**: Animated charts and interactive graphics +- **Educational Technology**: Gamification and engaging learning experiences +- **Mobile Development**: Touch-based interactions and performance optimization +- **Simulation Software**: Physics engines and real-time modeling +- **Creative Industries**: Interactive art, entertainment, and digital experiences + +**Professional Skills Gained**: You can now: +- **Architect** complex interactive systems from scratch +- **Debug** real-time applications using systematic approaches +- **Optimize** performance for smooth user experiences +- **Design** engaging user interfaces and interaction patterns +- **Collaborate** effectively on technical projects with proper code organization + +**Game Development Concepts Mastered**: +- **Real-time Systems**: Game loops, frame rate management, and performance +- **Event-Driven Architecture**: Decoupled systems and message passing +- **State Management**: Complex data handling and lifecycle management +- **User Interface Programming**: Canvas graphics and responsive design +- **Game Design Theory**: Player psychology and engagement mechanics + +**Next Level**: You're ready to explore advanced game frameworks, 3D graphics, multiplayer systems, or transition into professional game development roles! + +🌟 **Achievement Unlocked**: You've completed a full game development journey and built a professional-quality interactive experience from scratch! + +**Welcome to the game development community!** 🎮✨ + +## GitHub Copilot Agent Challenge 🚀 + +Use the Agent mode to complete the following challenge: + +**Description:** Enhance the space game by implementing a level progression system with increasing difficulty and bonus features. + +**Prompt:** Create a multi-level space game system where each level has more enemy ships with increased speed and health. Add a scoring multiplier that increases with each level, and implement power-ups (like rapid fire or shield) that randomly appear when enemies are destroyed. Include a level completion bonus and display the current level on screen alongside the existing score and lives. + +Learn more about [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) here. + +## 🚀 Optional Enhancement Challenge + +**Add Audio to Your Game**: Enhance your gameplay experience by implementing sound effects! Consider adding audio for: + +- **Laser shots** when the player fires +- **Enemy destruction** when ships are hit +- **Hero damage** when the player takes hits +- **Victory music** when the game is won +- **Defeat sound** when the game is lost + +**Audio implementation example:** + +```javascript +// Create audio objects +const laserSound = new Audio('assets/laser.wav'); +const explosionSound = new Audio('assets/explosion.wav'); + +// Play sounds during game events +function playLaserSound() { + laserSound.currentTime = 0; // Reset to beginning + laserSound.play(); +} +``` -## 🚀 Challenge +**What you need to know:** +- **Creates** Audio objects for different sound effects +- **Resets** the `currentTime` to allow rapid-fire sound effects +- **Handles** browser autoplay policies by triggering sounds from user interactions +- **Manages** audio volume and timing for better game experience -Add sound! Can you enhance your gameplay by adding sound effects, such as for laser hits, the hero's death, or a victory? Check out this [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) to learn how to play sound using JavaScript. +> 💡 **Learning Resource**: Explore this [audio sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) to learn more about implementing audio in JavaScript games. ## Post-Lecture Quiz @@ -224,7 +662,7 @@ Add sound! Can you enhance your gameplay by adding sound effects, such as for la ## Review & Self Study -Your assignment is to create a new sample game. Explore some interesting games to get inspiration for the type of game you might want to build. +Your assignment is to create a fresh sample game, so explore some of the interesting games out there to see what type of game you might build. ## Assignment @@ -232,5 +670,7 @@ Your assignment is to create a new sample game. Explore some interesting games t --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please note that automated translations may contain errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is recommended. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/6-end-condition/assignment.md b/translations/en/6-space-game/6-end-condition/assignment.md index a36073c75..23ee82181 100644 --- a/translations/en/6-space-game/6-end-condition/assignment.md +++ b/translations/en/6-space-game/6-end-condition/assignment.md @@ -1,33 +1,164 @@ - # Build a Sample Game -## Instructions +## Assignment Overview -Try creating a small game to practice different end conditions. Experiment with scenarios like reaching a certain number of points, the hero losing all lives, or defeating all monsters. Build something simple, such as a console-based adventure game. Use the game flow below as inspiration: +Now that you've mastered game end conditions and restart functionality in your space game, it's time to apply these concepts to a completely new gaming experience. You'll design and build your own game that demonstrates different end condition patterns and restart mechanics. + +This assignment challenges you to think creatively about game design while practicing the technical skills you've learned. You'll explore different victory and defeat scenarios, implement player progression, and create engaging restart experiences. + +## Project Requirements + +### Core Game Features + +Your game must include the following essential elements: + +**End Condition Variety**: Implement at least two different ways the game can end: +- **Point-based victory**: Player reaches a target score or collects specific items +- **Life-based defeat**: Player loses all available lives or health points +- **Objective completion**: All enemies defeated, specific items collected, or goals achieved +- **Time-based**: Game ends after a set duration or countdown reaches zero + +**Restart Functionality**: +- **Clear game state**: Remove all previous game objects and reset variables +- **Reinitialize systems**: Start fresh with new player stats, enemies, and objectives +- **User-friendly controls**: Provide clear instructions for restarting the game + +**Player Feedback**: +- **Victory messages**: Celebrate player achievements with positive feedback +- **Defeat messages**: Provide encouraging messages that motivate replay +- **Progress indicators**: Show current score, lives, or objective status + +### Game Ideas and Inspiration + +Choose one of these game concepts or create your own: + +#### 1. Console Adventure Game +Create a text-based adventure with combat mechanics: ``` Hero> Strikes with broadsword - orc takes 3p damage -Orc> Hits with club - hero takes 2p damage +Orc> Hits with club - hero takes 2p damage Hero> Kicks - orc takes 1p damage Game> Orc is defeated - Hero collects 2 coins Game> ****No more monsters, you have conquered the evil fortress**** ``` -## Rubric +**Key features to implement:** +- **Turn-based combat** with different attack options +- **Health points** for both player and enemies +- **Inventory system** for collecting coins or items +- **Multiple enemy types** with varying difficulty +- **Victory condition** when all enemies are defeated + +#### 2. Collection Game +- **Objective**: Collect specific items while avoiding obstacles +- **End conditions**: Reach target collection count or lose all lives +- **Progression**: Items become harder to reach as game continues + +#### 3. Puzzle Game +- **Objective**: Solve increasingly difficult puzzles +- **End conditions**: Complete all levels or run out of moves/time +- **Restart**: Reset to first level with cleared progress + +#### 4. Defense Game +- **Objective**: Protect your base from waves of enemies +- **End conditions**: Survive all waves (victory) or base is destroyed (defeat) +- **Progression**: Enemy waves increase in difficulty and number + +## Implementation Guidelines + +### Getting Started + +1. **Plan your game design**: + - Sketch the basic gameplay loop + - Define your end conditions clearly + - Identify what data needs to be reset on restart + +2. **Set up your project structure**: + ``` + my-game/ + ├── index.html + ├── style.css + ├── game.js + └── README.md + ``` + +3. **Create your core game loop**: + - Initialize game state + - Handle user input + - Update game logic + - Check end conditions + - Render current state + +### Technical Requirements + +**Use Modern JavaScript**: +- Apply `const` and `let` for variable declarations +- Use arrow functions where appropriate +- Implement ES6+ features like template literals and destructuring + +**Event-Driven Architecture**: +- Create event handlers for user interactions +- Implement game state changes through events +- Use event listeners for restart functionality + +**Clean Code Practices**: +- Write functions with single responsibilities +- Use descriptive variable and function names +- Add comments explaining game logic and rules +- Organize code into logical sections + +## Submission Requirements + +### Deliverables + +1. **Complete game files**: All HTML, CSS, and JavaScript files needed to run your game +2. **README.md**: Documentation explaining: + - How to play your game + - What end conditions you implemented + - Instructions for restarting + - Any special features or mechanics +3. **Code comments**: Clear explanations of your game logic and algorithms + +### Testing Checklist + +Before submitting, verify that your game: + +- [ ] **Runs without errors** in the browser console +- [ ] **Implements multiple end conditions** as specified +- [ ] **Restarts properly** with clean state reset +- [ ] **Provides clear feedback** to players about game status +- [ ] **Uses modern JavaScript** syntax and best practices +- [ ] **Includes comprehensive documentation** in README.md + +## Assessment Rubric + +| Criteria | Exemplary (4) | Proficient (3) | Developing (2) | Beginning (1) | +|----------|---------------|----------------|----------------|--------------| +| **Game Functionality** | Complete game with multiple end conditions, smooth restart, and polished gameplay experience | Full game with basic end conditions and functional restart mechanism | Partial game with some end conditions implemented, restart may have minor issues | Incomplete game with limited functionality and significant bugs | +| **Code Quality** | Clean, well-organized code using modern JavaScript practices, comprehensive comments, and excellent structure | Good code organization with modern syntax, adequate comments, and clear structure | Basic code organization with some modern practices, minimal comments | Poor code organization, outdated syntax, lacking comments and structure | +| **User Experience** | Intuitive gameplay with clear instructions, excellent feedback, and engaging end/restart experience | Good gameplay with adequate instructions and feedback, functional end/restart | Basic gameplay with minimal instructions, limited feedback on game state | Confusing gameplay with unclear instructions and poor user feedback | +| **Technical Implementation** | Demonstrates mastery of game development concepts, event handling, and state management | Shows solid understanding of game concepts with good implementation | Basic understanding with acceptable implementation | Limited understanding with poor implementation | +| **Documentation** | Comprehensive README with clear instructions, well-documented code, and thorough testing evidence | Good documentation with clear instructions and adequate code comments | Basic documentation with minimal instructions | Poor or missing documentation | + +### Grading Scale +- **Exemplary (16-20 points)**: Exceeds expectations with creative features and polished implementation +- **Proficient (12-15 points)**: Meets all requirements with solid execution +- **Developing (8-11 points)**: Meets most requirements with minor issues +- **Beginning (4-7 points)**: Meets some requirements but needs significant improvement + +## Additional Learning Resources + +- [MDN Game Development Guide](https://developer.mozilla.org/en-US/docs/Games) +- [JavaScript Game Development Tutorials](https://developer.mozilla.org/en-US/docs/Games/Tutorials) +- [Canvas API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) +- [Game Design Principles](https://www.gamasutra.com/blogs/) -| Criteria | Outstanding | Satisfactory | Needs Improvement | -| -------- | ---------------------- | --------------------------- | -------------------------- | -| | complete game provided | partial game provided | partial game has bugs | +> 💡 **Pro Tip**: Start simple and add features incrementally. A well-polished simple game is better than a complex game with bugs! --- -**Disclaimer**: -This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation. \ No newline at end of file + +**Disclaimer**: +This document has been translated using the AI translation service [Co-op Translator](https://github.com/Azure/co-op-translator). While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation. + \ No newline at end of file diff --git a/translations/en/6-space-game/6-end-condition/solution/README.md b/translations/en/6-space-game/6-end-condition/solution/README.md index 0679a7993..b78db64df 100644 --- a/translations/en/6-space-game/6-end-condition/solution/README.md +++ b/translations/en/6-space-game/6-end-condition/solution/README.md @@ -1,12 +1,3 @@ - This is a placeholder, left blank purposefully --- diff --git a/translations/en/6-space-game/6-end-condition/your-work/README.md b/translations/en/6-space-game/6-end-condition/your-work/README.md index 3d6cee0cd..b78db64df 100644 --- a/translations/en/6-space-game/6-end-condition/your-work/README.md +++ b/translations/en/6-space-game/6-end-condition/your-work/README.md @@ -1,12 +1,3 @@ - This is a placeholder, left blank purposefully --- diff --git a/translations/en/6-space-game/README.md b/translations/en/6-space-game/README.md index 9765c7f1d..01957c7c0 100644 --- a/translations/en/6-space-game/README.md +++ b/translations/en/6-space-game/README.md @@ -1,12 +1,3 @@ - # Build a Space Game A space game to teach advanced JavaScript fundamentals diff --git a/translations/en/6-space-game/solution/README.md b/translations/en/6-space-game/solution/README.md index 502125829..84d147c9a 100644 --- a/translations/en/6-space-game/solution/README.md +++ b/translations/en/6-space-game/solution/README.md @@ -1,12 +1,3 @@ - This is a placeholder, left blank purposefully --- diff --git a/translations/en/7-bank-project/1-template-route/README.md b/translations/en/7-bank-project/1-template-route/README.md index 55f1292bf..b987990cd 100644 --- a/translations/en/7-bank-project/1-template-route/README.md +++ b/translations/en/7-bank-project/1-template-route/README.md @@ -1,31 +1,87 @@ - # Build a Banking App Part 1: HTML Templates and Routes in a Web App +```mermaid +journey + title Your Banking App Development Journey + section SPA Fundamentals + Understand single-page apps: 3: Student + Learn template concepts: 4: Student + Master DOM manipulation: 4: Student + section Routing Systems + Implement client-side routing: 4: Student + Handle browser history: 5: Student + Create navigation systems: 5: Student + section Professional Patterns + Build modular architecture: 5: Student + Apply best practices: 5: Student + Create user experiences: 5: Student +``` +When Apollo 11's guidance computer navigated to the moon in 1969, it had to switch between different programs without restarting the entire system. Modern web applications work similarly – they change what you see without reloading everything from scratch. This creates the smooth, responsive experience users expect today. + +Unlike traditional websites that reload entire pages for every interaction, modern web apps update only the parts that need changing. This approach, much like how mission control switches between different displays while maintaining constant communication, creates that fluid experience we've come to expect. + +Here's what makes the difference so dramatic: + +| Traditional Multi-Page Apps | Modern Single-Page Apps | +|----------------------------|-------------------------| +| **Navigation** | Full page reload for each screen | Instant content switching | +| **Performance** | Slower due to complete HTML downloads | Faster with partial updates | +| **User Experience** | Jarring page flashes | Smooth, app-like transitions | +| **Data Sharing** | Difficult between pages | Easy state management | +| **Development** | Multiple HTML files to maintain | Single HTML with dynamic templates | + +**Understanding the evolution:** +- **Traditional apps** require server requests for every navigation action +- **Modern SPAs** load once and update content dynamically using JavaScript +- **User expectations** now favor instant, seamless interactions +- **Performance benefits** include reduced bandwidth and faster responses + +In this lesson, we'll build a banking app with multiple screens that flow together seamlessly. Like how scientists use modular instruments that can be reconfigured for different experiments, we'll use HTML templates as reusable components that can be displayed as needed. + +You'll work with HTML templates (reusable blueprints for different screens), JavaScript routing (the system that switches between screens), and the browser's history API (which keeps the back button working as expected). These are the same fundamental techniques used by frameworks like React, Vue, and Angular. + +By the end, you'll have a working banking app that demonstrates professional single-page application principles. + +```mermaid +mindmap + root((Single-Page Applications)) + Architecture + Template System + Client-side Routing + State Management + Event Handling + Templates + Reusable Components + Dynamic Content + DOM Manipulation + Content Switching + Routing + URL Management + History API + Navigation Logic + Browser Integration + User Experience + Fast Navigation + Smooth Transitions + Consistent State + Modern Interactions + Performance + Reduced Server Requests + Faster Page Transitions + Efficient Resource Usage + Better Responsiveness +``` ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/41) -### Introduction - -Since JavaScript was introduced in browsers, websites have become more interactive and complex than ever. Web technologies are now often used to create fully functional applications that run directly in a browser, known as [web applications](https://en.wikipedia.org/wiki/Web_application). Because web apps are highly interactive, users don't want to wait for a full page reload every time they perform an action. This is why JavaScript is used to update the HTML directly via the DOM, providing a smoother user experience. +### What You'll Need -In this lesson, we’ll lay the groundwork for creating a banking web app. We’ll use HTML templates to create multiple screens that can be displayed and updated without reloading the entire HTML page. - -### Prerequisite - -You’ll need a local web server to test the web app we’ll build in this lesson. If you don’t have one, you can install [Node.js](https://nodejs.org) and use the command `npx lite-server` from your project folder. This will create a local web server and open your app in a browser. +We'll need a local web server to test our banking app – don't worry, it's easier than it sounds! If you don't already have one set up, just install [Node.js](https://nodejs.org) and run `npx lite-server` from your project folder. This handy command spins up a local server and automatically opens your app in the browser. ### Preparation -On your computer, create a folder named `bank` with a file named `index.html` inside it. We’ll start with this HTML [boilerplate](https://en.wikipedia.org/wiki/Boilerplate_code): +On your computer, create a folder named `bank` with a file named `index.html` inside it. We'll start from this HTML [boilerplate](https://en.wikipedia.org/wiki/Boilerplate_code): ```html @@ -41,30 +97,77 @@ On your computer, create a folder named `bank` with a file named `index.html` in ``` +**Here's what this boilerplate provides:** +- **Establishes** the HTML5 document structure with proper DOCTYPE declaration +- **Configures** character encoding as UTF-8 for international text support +- **Enables** responsive design with the viewport meta tag for mobile compatibility +- **Sets** a descriptive title that appears in the browser tab +- **Creates** a clean body section where we'll build our application + +> 📁 **Project Structure Preview** +> +> **By the end of this lesson, your project will contain:** +> ``` +> bank/ +> ├── index.html +> ├── app.js +> └── style.css +> ``` +> +> **File responsibilities:** +> - **index.html**: Contains all templates and provides the app structure +> - **app.js**: Handles routing, navigation, and template management +> - **Templates**: Define the UI for login, dashboard, and other screens + --- -## HTML templates +## HTML Templates + +Templates solve a fundamental problem in web development. When Gutenberg invented movable type printing in the 1440s, he realized that instead of carving entire pages, he could create reusable letter blocks and arrange them as needed. HTML templates work on the same principle – instead of creating separate HTML files for each screen, you define reusable structures that can be displayed when needed. + +```mermaid +flowchart TD + A["📋 Template Definition"] --> B["💬 Hidden in DOM"] + B --> C["🔍 JavaScript Finds Template"] + C --> D["📋 Clone Template Content"] + D --> E["🔗 Attach to Visible DOM"] + E --> F["👁️ User Sees Content"] + + G["Login Template"] --> A + H["Dashboard Template"] --> A + I["Future Templates"] --> A + + style A fill:#e3f2fd + style D fill:#e8f5e8 + style F fill:#fff3e0 + style B fill:#f3e5f5 +``` +Think of templates as blueprints for different parts of your app. Just as an architect creates one blueprint and uses it multiple times rather than redrawing identical rooms, we create templates once and instantiate them as needed. The browser keeps these templates hidden until JavaScript activates them. -If you want to create multiple screens for a web page, one solution is to create a separate HTML file for each screen you want to display. However, this approach has some drawbacks: +If you want to create multiple screens for a web page, one solution would be to create one HTML file for every screen you want to display. However, this solution comes with some inconvenience: -- The entire HTML has to reload when switching screens, which can be slow. -- Sharing data between different screens becomes difficult. +- You have to reload the entire HTML when switching screen, which can be slow. +- It's difficult to share data between the different screens. -An alternative approach is to use a single HTML file and define multiple [HTML templates](https://developer.mozilla.org/docs/Web/HTML/Element/template) using the `