From 8fcd95775f05fd8d48b6a3b49555bf138d8d065c Mon Sep 17 00:00:00 2001 From: DanielRosa74 <58576743+DanielRosa74@users.noreply.github.com> Date: Thu, 8 Oct 2026 15:59:00 -0300 Subject: [PATCH] feat(i18n, learn): add latest translations --- client/arabic/intro.json | 369 ++++++++++++++++- client/chinese-traditional/intro.json | 371 +++++++++++++++++- client/chinese/intro.json | 371 +++++++++++++++++- client/espanol/intro.json | 367 ++++++++++++++++- client/german/intro.json | 369 ++++++++++++++++- client/italian/intro.json | 369 ++++++++++++++++- client/japanese/intro.json | 371 +++++++++++++++++- client/korean/intro.json | 371 +++++++++++++++++- client/portuguese/intro.json | 371 +++++++++++++++++- client/swahili/intro.json | 369 ++++++++++++++++- client/ukrainian/intro.json | 367 ++++++++++++++++- .../587d78b2367417b2b2512b0e.md | 2 +- .../587d78b2367417b2b2512b0f.md | 2 +- .../587d78b2367417b2b2512b10.md | 2 +- .../587d78b3367417b2b2512b11.md | 2 +- .../587d7b7a367417b2b2512b12.md | 2 +- .../587d7b7b367417b2b2512b14.md | 2 +- .../587d7b7d367417b2b2512b1e.md | 2 +- .../bootstrap/bad87fee1348bd9aedf08845.md | 4 +- .../bootstrap/bad87fee1348cd8acef08812.md | 2 +- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 15 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 32 +- .../68adce01c0e1144d0a90295e.md | 8 +- .../68af0687ef34c76c28ffa54b.md | 4 +- .../68b06e589bf2273243814777.md | 8 +- .../6939b873185d8e00d453563c.md | 4 +- .../69d03e549613fbdbe21d11e0.md | 10 +- .../681cb05adab50c87ddb2e513.md | 31 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../681cb1afdab50c87ddb2e517.md | 12 +- .../68adce01c0e1144d0a902958.md | 45 +++ .../68b06e589bf2273243814777.md | 6 +- .../68f6587287ad1f4ad39b0c7f.md | 4 +- .../6939b873185d8e00d453563c.md | 2 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 4 +- .../587d8255367417b2b2512c73.md | 2 +- .../587d8247367417b2b2512c37.md | 2 +- .../587d8247367417b2b2512c38.md | 2 +- .../587d8247367417b2b2512c39.md | 2 +- .../587d8248367417b2b2512c3a.md | 2 +- .../587d8248367417b2b2512c3b.md | 2 +- .../587d8248367417b2b2512c3c.md | 2 +- .../587d8248367417b2b2512c3d.md | 2 +- .../587d8249367417b2b2512c3e.md | 2 +- .../587d8249367417b2b2512c3f.md | 2 +- .../587d8249367417b2b2512c40.md | 2 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 25 +- .../686b9720ee1d032bd77a480a.md | 43 +- .../66c06fad3475cd92421b9ac2.md | 25 +- .../6842a6cd9836f0114a5b7a8a.md | 12 +- .../67d83df6f82eda3868dd2a84.md | 64 +-- .../694acade1d4afdbce71e5840.md | 112 +++++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 2 +- .../65a35429c637c13540c9be80.md | 2 +- .../65a35c7b9d642f478d6cabba.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 8 + .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 10 + .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../6732b758194c97257d23fc72.md | 2 +- .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../672d49c4e899345f5b33c24c.md | 2 +- .../67fe8567f141d632afaeb71b.md | 16 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 16 + .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 16 + .../673407be6af21d6766ed4b96.md | 2 +- .../672d49d93b54b85faa4dbad7.md | 67 +++- .../672d49e65a1c855fe7bb3fdb.md | 4 +- .../67d1ec87b34cee1d9219f7e9.md | 8 + .../6733d3a33abdd27cd562bdf2.md | 2 +- .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 20 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 16 + .../6a89c69c2abed81397a6c99e.md | 12 + .../69a918497b6424e132898217.md | 2 +- .../69a9184b42ae3947e4925016.md | 9 + .../6a3b86e9f96f6bbcd0ed8c45.md | 2 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 26 +- .../687e9437536d762823fefab3.md | 36 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 12 + .../67db30fedfa0b22a1a2a570c.md | 14 + .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 2 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../6a03f5d143c8688a9265c0a0.md | 2 +- .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 12 + .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 12 + .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 8 + .../672bd658c0e190f674a5e057.md | 1 + .../673226a62eb2121da41a3d68.md | 2 +- .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 14 + .../67d1a99d10fd509c88faf3bf.md | 16 + .../67d2f4ddb4a4306fdf5bbaee.md | 10 + .../6734e3ceee2da4b0301719b7.md | 12 + .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 14 + .../673362e43d57b51f1ad2d466.md | 2 +- .../672a511bb408ec81c592eb68.md | 4 + .../6732b79c6aa77826855a3f11.md | 2 +- .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 20 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 10 + .../683d6a3fe8c1060ffb1f9b78.md | 8 + .../6732c05595ca7d422b9e55ff.md | 12 + .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 4 +- .../6732808f3221720adc833e81.md | 2 +- .../673280a1c29d0a0b17316e56.md | 2 +- .../687ea8757080091969f07122.md | 14 + .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../672bb851b068e3954a05b9b1.md | 2 +- .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 6 + .../67d1a3fea729e274dc33d04d.md | 18 +- .../67d1eaf77f510e15dfed7c14.md | 10 + .../67d1eb6929e68117faa6717f.md | 6 + .../672d266034b5242126271995.md | 2 +- .../673263f4a5899da8124542fd.md | 2 +- .../673368b1cf26253212a3cfb2.md | 2 +- .../673368c0161e6b326a7e03f0.md | 2 +- .../673368d97e8ce232cdcd6b68.md | 2 +- .../673368f272706633516e4873.md | 2 +- .../673369067f824d33a90a0534.md | 12 + .../67336956340e8a34fbd5d9f3.md | 2 +- .../6732c68f4520d160584a6fd2.md | 2 +- .../6732c69d82814160951b1aa7.md | 2 +- .../587d7fb7367417b2b2512c0a.md | 2 +- .../587d7fb7367417b2b2512c0b.md | 2 +- .../587d7fb7367417b2b2512c0c.md | 2 +- .../587d7fb7367417b2b2512c0d.md | 2 +- .../587d7fb8367417b2b2512c0f.md | 2 +- .../587d7fb8367417b2b2512c11.md | 2 +- .../66ed9010f45ce3ece4053eb8.md | 6 +- .../69fd84e01123960e15bb8455.md | 14 +- .../blocks/react/5a24c314108439a4d403618a.md | 2 +- .../blocks/react/5a24c314108439a4d403618c.md | 2 +- .../6a439658bfbe59fcf4b221c7.md | 6 +- .../698c302951ac746466349fd9.md | 153 +++++--- .../67f39e06b8a11b2de9ccd361.md | 56 +-- .../6a02da945706a3ddc2e44348.md | 4 +- .../67f39b40deaec81a3e40e0c5.md | 32 +- .../598eea87e5cf4b116c3ff81a.md | 4 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 98 ++--- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818ed1adc249bb91d373729.md | 2 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 4 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 12 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 4 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 4 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 10 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 8 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 8 + .../6852db755c9c1274d75aae9a.md | 4 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 19 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 6 +- .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 6 +- .../bootstrap/bad87fee1348bd9aedf08845.md | 4 +- .../647e21ba8acb466c97ccbee6.md | 39 -- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 25 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 2 +- .../68af0687ef34c76c28ffa54b.md | 2 +- .../68b06e589bf2273243814777.md | 8 +- .../6939b873185d8e00d453563c.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 6 +- .../681cb05adab50c87ddb2e513.md | 31 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../681cb1afdab50c87ddb2e517.md | 12 +- .../68adce01c0e1144d0a902958.md | 45 +++ .../68b06e589bf2273243814777.md | 8 +- .../68f6587287ad1f4ad39b0c7f.md | 4 +- .../6939b873185d8e00d453563c.md | 2 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 4 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 37 +- .../686b9720ee1d032bd77a480a.md | 62 +-- .../66c06fad3475cd92421b9ac2.md | 21 +- .../6842a6cd9836f0114a5b7a8a.md | 10 +- .../67d83df6f82eda3868dd2a84.md | 62 +-- .../694acade1d4afdbce71e5840.md | 108 ++++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 10 +- .../65a35429c637c13540c9be80.md | 2 +- .../65a35c7b9d642f478d6cabba.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 10 +- .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 10 + .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 20 +- .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 18 +- .../672d49d93b54b85faa4dbad7.md | 67 +++- .../672d49e65a1c855fe7bb3fdb.md | 6 +- .../67d1ec87b34cee1d9219f7e9.md | 10 +- .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 24 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 16 + .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 13 +- .../6a3b86e9f96f6bbcd0ed8c45.md | 6 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 26 +- .../687e9437536d762823fefab3.md | 36 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 12 + .../67db30fedfa0b22a1a2a570c.md | 14 + .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 8 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 14 +- .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 18 +- .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 12 +- .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 28 +- .../672bccebe1fc82d911c3f078.md | 26 +- .../67d1a99d10fd509c88faf3bf.md | 18 +- .../67d2f4ddb4a4306fdf5bbaee.md | 12 +- .../6734e3ceee2da4b0301719b7.md | 18 +- .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 14 + .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 20 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 10 + .../683d6a3fe8c1060ffb1f9b78.md | 8 + .../6732c05595ca7d422b9e55ff.md | 12 + .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 6 +- .../687ea8757080091969f07122.md | 14 + .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 6 + .../67d1a3fea729e274dc33d04d.md | 12 +- .../67d1eaf77f510e15dfed7c14.md | 12 +- .../67d1eb6929e68117faa6717f.md | 6 + .../673369067f824d33a90a0534.md | 18 +- .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 2 +- .../698c302951ac746466349fd9.md | 189 +++++---- .../67f39e06b8a11b2de9ccd361.md | 100 ++--- .../6a02da945706a3ddc2e44348.md | 4 +- .../67f39b40deaec81a3e40e0c5.md | 28 +- .../598eea87e5cf4b116c3ff81a.md | 8 +- .../599d1566a02b571412643b84.md | 16 +- .../63ee35450d8d4841c3a70920.md | 6 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818ed1adc249bb91d373729.md | 2 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 4 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 10 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 10 +- .../6852db755c9c1274d75aae9a.md | 6 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 17 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 39 ++ .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 8 +- .../bootstrap/bad87fee1348bd9aedf08845.md | 4 +- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 25 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 2 +- .../68af0687ef34c76c28ffa54b.md | 2 +- .../68b06e589bf2273243814777.md | 8 +- .../6939b873185d8e00d453563c.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 6 +- .../681cb05adab50c87ddb2e513.md | 31 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../681cb1afdab50c87ddb2e517.md | 12 +- .../68adce01c0e1144d0a902958.md | 45 +++ .../68b06e589bf2273243814777.md | 8 +- .../68f6587287ad1f4ad39b0c7f.md | 4 +- .../6939b873185d8e00d453563c.md | 2 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 2 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 29 +- .../686b9720ee1d032bd77a480a.md | 68 ++-- .../66c06fad3475cd92421b9ac2.md | 23 +- .../6842a6cd9836f0114a5b7a8a.md | 10 +- .../67d83df6f82eda3868dd2a84.md | 42 +- .../694acade1d4afdbce71e5840.md | 104 ++++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 10 +- .../65a35429c637c13540c9be80.md | 2 +- .../65a35c7b9d642f478d6cabba.md | 2 +- .../660f4934fb48f63abd5ae371.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 10 +- .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 24 +- .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 20 +- .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 18 +- .../672d49d93b54b85faa4dbad7.md | 67 +++- .../672d49e65a1c855fe7bb3fdb.md | 6 +- .../67d1ec87b34cee1d9219f7e9.md | 10 +- .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 28 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 16 + .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 15 +- .../6a3b86e9f96f6bbcd0ed8c45.md | 2 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 26 +- .../687e9437536d762823fefab3.md | 36 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 12 + .../67db30fedfa0b22a1a2a570c.md | 14 + .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 8 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 12 + .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 18 +- .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 12 +- .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 26 +- .../67d1a99d10fd509c88faf3bf.md | 18 +- .../67d2f4ddb4a4306fdf5bbaee.md | 12 +- .../6734e3ceee2da4b0301719b7.md | 18 +- .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 14 + .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 20 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 10 + .../683d6a3fe8c1060ffb1f9b78.md | 8 + .../6732c05595ca7d422b9e55ff.md | 12 + .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 6 +- .../687ea8757080091969f07122.md | 14 + .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 6 + .../67d1a3fea729e274dc33d04d.md | 10 + .../67d1eaf77f510e15dfed7c14.md | 12 +- .../67d1eb6929e68117faa6717f.md | 6 + .../673369067f824d33a90a0534.md | 14 +- .../5900f5471000cf542c510059.md | 2 +- .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 16 +- .../698c302951ac746466349fd9.md | 175 ++++++--- .../67f39e06b8a11b2de9ccd361.md | 94 ++--- .../6a02da945706a3ddc2e44348.md | 4 +- .../67f39b40deaec81a3e40e0c5.md | 26 +- .../598eea87e5cf4b116c3ff81a.md | 10 +- .../599d1566a02b571412643b84.md | 16 +- .../5a23c84252665b21eecc7edf.md | 2 +- .../5eb3e4b20aa93c437f9e9717.md | 2 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 6 +- .../6818ed1adc249bb91d373729.md | 2 +- .../6818fcb250f34e62cab32c39.md | 12 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 4 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 8 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 10 +- .../6852db755c9c1274d75aae9a.md | 6 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 19 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 8 +- .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 6 +- .../bootstrap/bad87fee1348bd9aedf08845.md | 4 +- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 13 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 2 +- .../68af0687ef34c76c28ffa54b.md | 2 +- .../68b06e589bf2273243814777.md | 6 +- .../6939b873185d8e00d453563c.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 4 +- .../681cb05adab50c87ddb2e513.md | 19 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../681cb1afdab50c87ddb2e517.md | 12 +- .../68adce01c0e1144d0a902958.md | 45 +++ .../68b06e589bf2273243814777.md | 6 +- .../68f6587287ad1f4ad39b0c7f.md | 4 +- .../6939b873185d8e00d453563c.md | 2 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 2 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 25 +- .../686b9720ee1d032bd77a480a.md | 67 ++-- .../66c06fad3475cd92421b9ac2.md | 19 +- .../6842a6cd9836f0114a5b7a8a.md | 6 +- .../67d83df6f82eda3868dd2a84.md | 44 +-- .../694acade1d4afdbce71e5840.md | 100 ++++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 10 +- .../65a35429c637c13540c9be80.md | 2 +- .../65a35c7b9d642f478d6cabba.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 10 +- .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 24 +- .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 20 +- .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 18 +- .../672d49d93b54b85faa4dbad7.md | 67 +++- .../672d49e65a1c855fe7bb3fdb.md | 6 +- .../67d1ec87b34cee1d9219f7e9.md | 10 +- .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 22 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 16 + .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 9 + .../6a3b86e9f96f6bbcd0ed8c45.md | 6 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 26 +- .../687e9437536d762823fefab3.md | 34 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 12 + .../67db30fedfa0b22a1a2a570c.md | 14 + .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 4 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 14 +- .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 20 +- .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 12 +- .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 26 +- .../67d1a99d10fd509c88faf3bf.md | 18 +- .../67d2f4ddb4a4306fdf5bbaee.md | 12 +- .../6734e3ceee2da4b0301719b7.md | 12 + .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 14 + .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 20 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 10 + .../683d6a3fe8c1060ffb1f9b78.md | 8 + .../6732c05595ca7d422b9e55ff.md | 12 + .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 6 +- .../687ea8757080091969f07122.md | 14 + .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 6 + .../67d1a3fea729e274dc33d04d.md | 12 +- .../67d1eaf77f510e15dfed7c14.md | 12 +- .../67d1eb6929e68117faa6717f.md | 6 + .../673369067f824d33a90a0534.md | 16 +- .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 2 +- .../698c302951ac746466349fd9.md | 169 +++++--- .../67f39e06b8a11b2de9ccd361.md | 80 ++-- .../6a02da945706a3ddc2e44348.md | 2 +- .../67f39b40deaec81a3e40e0c5.md | 28 +- .../598eea87e5cf4b116c3ff81a.md | 6 +- .../599d1566a02b571412643b84.md | 16 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818ed1adc249bb91d373729.md | 2 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 4 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 10 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 8 + .../6852db755c9c1274d75aae9a.md | 4 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 17 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 8 +- .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 8 +- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 11 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 2 +- .../68af0687ef34c76c28ffa54b.md | 2 +- .../68b06e589bf2273243814777.md | 6 +- .../6939b873185d8e00d453563c.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 4 +- .../681cb05adab50c87ddb2e513.md | 51 ++- .../681cb1afdab50c87ddb2e515.md | 12 +- .../681cb1afdab50c87ddb2e517.md | 14 +- .../68adce01c0e1144d0a902958.md | 61 ++- .../68b06e589bf2273243814777.md | 18 +- .../68f6587287ad1f4ad39b0c7f.md | 18 +- .../6939b873185d8e00d453563c.md | 10 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 18 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 21 +- .../686b9720ee1d032bd77a480a.md | 29 +- .../66c06fad3475cd92421b9ac2.md | 23 +- .../6842a6cd9836f0114a5b7a8a.md | 4 +- .../67d83df6f82eda3868dd2a84.md | 30 +- .../694acade1d4afdbce71e5840.md | 98 ++++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 2 +- .../65a35429c637c13540c9be80.md | 2 +- .../65a35c7b9d642f478d6cabba.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 8 + .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 14 +- .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 16 + .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 16 + .../672d49d93b54b85faa4dbad7.md | 67 +++- .../672d49e65a1c855fe7bb3fdb.md | 6 +- .../67d1ec87b34cee1d9219f7e9.md | 8 + .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 22 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 16 + .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 11 +- .../6a3b86e9f96f6bbcd0ed8c45.md | 4 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 24 +- .../687e9437536d762823fefab3.md | 36 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 12 + .../67db30fedfa0b22a1a2a570c.md | 20 +- .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 4 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 12 + .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 12 + .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 8 + .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 14 + .../67d1a99d10fd509c88faf3bf.md | 16 + .../67d2f4ddb4a4306fdf5bbaee.md | 10 + .../6734e3ceee2da4b0301719b7.md | 12 + .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 18 +- .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 20 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 10 + .../683d6a3fe8c1060ffb1f9b78.md | 8 + .../6732c05595ca7d422b9e55ff.md | 12 + .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 4 +- .../687ea8757080091969f07122.md | 14 + .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 8 +- .../67d1a3fea729e274dc33d04d.md | 14 +- .../67d1eaf77f510e15dfed7c14.md | 20 +- .../67d1eb6929e68117faa6717f.md | 8 +- .../673369067f824d33a90a0534.md | 14 +- .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 2 +- .../698c302951ac746466349fd9.md | 147 ++++--- .../67f39e06b8a11b2de9ccd361.md | 42 +- .../6a02da945706a3ddc2e44348.md | 2 +- .../67f39b40deaec81a3e40e0c5.md | 24 +- .../598eea87e5cf4b116c3ff81a.md | 4 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818ed1adc249bb91d373729.md | 2 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 4 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 8 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 8 + .../6852db755c9c1274d75aae9a.md | 4 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 17 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 6 +- .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 6 +- .../bootstrap/bad87fee1348cd8acef08812.md | 2 +- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 13 +- .../681cb1afdab50c87ddb2e515.md | 4 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 4 +- .../68af0687ef34c76c28ffa54b.md | 4 +- .../68b06e589bf2273243814777.md | 6 +- .../6939b873185d8e00d453563c.md | 4 +- .../69d03e549613fbdbe21d11e0.md | 8 +- .../681cb05adab50c87ddb2e513.md | 19 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../681cb1afdab50c87ddb2e517.md | 12 +- .../68adce01c0e1144d0a902958.md | 45 +++ .../68b06e589bf2273243814777.md | 6 +- .../68f6587287ad1f4ad39b0c7f.md | 4 +- .../6939b873185d8e00d453563c.md | 2 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 2 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 23 +- .../686b9720ee1d032bd77a480a.md | 47 +-- .../66c06fad3475cd92421b9ac2.md | 23 +- .../6842a6cd9836f0114a5b7a8a.md | 8 +- .../67d83df6f82eda3868dd2a84.md | 46 +-- .../694acade1d4afdbce71e5840.md | 96 ++++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 2 +- .../65a35429c637c13540c9be80.md | 2 +- .../65a35c7b9d642f478d6cabba.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 9 + .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 12 +- .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 18 +- .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 16 + .../672d49d93b54b85faa4dbad7.md | 69 +++- .../672d49e65a1c855fe7bb3fdb.md | 4 +- .../67d1ec87b34cee1d9219f7e9.md | 8 + .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 28 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 16 + .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 13 +- .../6a3b86e9f96f6bbcd0ed8c45.md | 4 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 26 +- .../687e9437536d762823fefab3.md | 38 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 20 +- .../67db30fedfa0b22a1a2a570c.md | 20 +- .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 6 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 12 + .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 12 + .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 8 + .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 14 + .../67d1a99d10fd509c88faf3bf.md | 16 + .../67d2f4ddb4a4306fdf5bbaee.md | 10 + .../6734e3ceee2da4b0301719b7.md | 12 + .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 16 +- .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 28 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 10 + .../683d6a3fe8c1060ffb1f9b78.md | 14 +- .../6732c05595ca7d422b9e55ff.md | 14 +- .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 4 +- .../687ea8757080091969f07122.md | 24 +- .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 6 + .../67d1a3fea729e274dc33d04d.md | 20 +- .../67d1eaf77f510e15dfed7c14.md | 14 +- .../67d1eb6929e68117faa6717f.md | 16 +- .../673369067f824d33a90a0534.md | 14 +- .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 2 +- .../698c302951ac746466349fd9.md | 151 ++++--- .../67f39e06b8a11b2de9ccd361.md | 35 +- .../6a02da945706a3ddc2e44348.md | 2 +- .../67f39b40deaec81a3e40e0c5.md | 26 +- .../598eea87e5cf4b116c3ff81a.md | 4 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 4 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 8 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 8 + .../6852db755c9c1274d75aae9a.md | 4 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 19 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 6 +- .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 6 +- .../bootstrap/bad87fee1348cd8acef08812.md | 2 +- .../647e21ba8acb466c97ccbee6.md | 39 -- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 55 +-- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 2 +- .../68af0687ef34c76c28ffa54b.md | 2 +- .../68b06e589bf2273243814777.md | 8 +- .../6939b873185d8e00d453563c.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 4 +- .../681cb05adab50c87ddb2e513.md | 63 +-- .../681cb1afdab50c87ddb2e515.md | 12 +- .../681cb1afdab50c87ddb2e517.md | 14 +- .../68adce01c0e1144d0a902958.md | 61 ++- .../68b06e589bf2273243814777.md | 20 +- .../68f6587287ad1f4ad39b0c7f.md | 18 +- .../6939b873185d8e00d453563c.md | 10 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 18 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 35 +- .../686b9720ee1d032bd77a480a.md | 41 +- .../66c06fad3475cd92421b9ac2.md | 23 +- .../6842a6cd9836f0114a5b7a8a.md | 16 +- .../67d83df6f82eda3868dd2a84.md | 70 ++-- .../694acade1d4afdbce71e5840.md | 102 ++++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 4 +- .../65a35429c637c13540c9be80.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 11 +- .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 14 +- .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 16 + .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 16 + .../672d49d93b54b85faa4dbad7.md | 69 +++- .../672d49e65a1c855fe7bb3fdb.md | 6 +- .../67d1ec87b34cee1d9219f7e9.md | 8 + .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 20 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 16 + .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 15 +- .../6a3b86e9f96f6bbcd0ed8c45.md | 8 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 26 +- .../687e9437536d762823fefab3.md | 38 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 12 + .../67db30fedfa0b22a1a2a570c.md | 20 +- .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 8 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 14 +- .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 12 + .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 8 + .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 14 + .../67d1a99d10fd509c88faf3bf.md | 18 +- .../67d2f4ddb4a4306fdf5bbaee.md | 10 + .../6734e3ceee2da4b0301719b7.md | 12 + .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 16 +- .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 34 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 16 +- .../683d6a3fe8c1060ffb1f9b78.md | 16 +- .../6732c05595ca7d422b9e55ff.md | 12 + .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 4 +- .../687ea8757080091969f07122.md | 14 + .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 8 +- .../67d1a3fea729e274dc33d04d.md | 20 +- .../67d1eaf77f510e15dfed7c14.md | 14 +- .../67d1eb6929e68117faa6717f.md | 8 +- .../673369067f824d33a90a0534.md | 20 +- .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 2 +- .../698c302951ac746466349fd9.md | 161 +++++--- .../67f39e06b8a11b2de9ccd361.md | 67 ++-- .../6a02da945706a3ddc2e44348.md | 2 +- .../67f39b40deaec81a3e40e0c5.md | 32 +- .../598eea87e5cf4b116c3ff81a.md | 4 +- .../63ee35450d8d4841c3a70920.md | 6 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818ed1adc249bb91d373729.md | 2 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 10 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 8 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 8 + .../6852db755c9c1274d75aae9a.md | 4 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 19 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 39 ++ .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 8 +- .../647e21ba8acb466c97ccbee6.md | 39 -- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 23 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 2 +- .../68af0687ef34c76c28ffa54b.md | 2 +- .../68b06e589bf2273243814777.md | 8 +- .../6939b873185d8e00d453563c.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 6 +- .../681cb05adab50c87ddb2e513.md | 63 +-- .../681cb1afdab50c87ddb2e515.md | 12 +- .../681cb1afdab50c87ddb2e517.md | 14 +- .../68adce01c0e1144d0a902958.md | 61 ++- .../68b06e589bf2273243814777.md | 20 +- .../68f6587287ad1f4ad39b0c7f.md | 18 +- .../6939b873185d8e00d453563c.md | 10 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 4 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 27 +- .../686b9720ee1d032bd77a480a.md | 61 +-- .../66c06fad3475cd92421b9ac2.md | 23 +- .../6842a6cd9836f0114a5b7a8a.md | 12 +- .../67d83df6f82eda3868dd2a84.md | 48 +-- .../694acade1d4afdbce71e5840.md | 96 ++++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 2 +- .../65a35429c637c13540c9be80.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 9 + .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 12 +- .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 18 +- .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 20 +- .../672d49d93b54b85faa4dbad7.md | 71 +++- .../672d49e65a1c855fe7bb3fdb.md | 4 +- .../67d1ec87b34cee1d9219f7e9.md | 8 + .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 26 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 16 + .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 15 +- .../6a3b86e9f96f6bbcd0ed8c45.md | 4 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 26 +- .../687e9437536d762823fefab3.md | 34 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 12 + .../67db30fedfa0b22a1a2a570c.md | 20 +- .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 6 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 12 + .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 14 +- .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 8 + .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 14 + .../67d1a99d10fd509c88faf3bf.md | 16 + .../67d2f4ddb4a4306fdf5bbaee.md | 10 + .../6734e3ceee2da4b0301719b7.md | 12 + .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 16 +- .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 22 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 16 +- .../683d6a3fe8c1060ffb1f9b78.md | 16 +- .../6732c05595ca7d422b9e55ff.md | 14 +- .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 4 +- .../687ea8757080091969f07122.md | 14 + .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 8 +- .../67d1a3fea729e274dc33d04d.md | 18 +- .../67d1eaf77f510e15dfed7c14.md | 14 +- .../67d1eb6929e68117faa6717f.md | 8 +- .../673369067f824d33a90a0534.md | 18 +- .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 2 +- .../698c302951ac746466349fd9.md | 161 +++++--- .../67f39e06b8a11b2de9ccd361.md | 71 ++-- .../6a02da945706a3ddc2e44348.md | 4 +- .../67f39b40deaec81a3e40e0c5.md | 26 +- .../598eea87e5cf4b116c3ff81a.md | 4 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 8 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 8 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 8 + .../6852db755c9c1274d75aae9a.md | 4 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 19 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 39 ++ .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 10 +- .../bootstrap/bad87fee1348bd9aedf08845.md | 4 +- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 13 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 2 +- .../68af0687ef34c76c28ffa54b.md | 2 +- .../68b06e589bf2273243814777.md | 6 +- .../6939b873185d8e00d453563c.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 2 +- .../681cb05adab50c87ddb2e513.md | 19 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../681cb1afdab50c87ddb2e517.md | 12 +- .../68adce01c0e1144d0a902958.md | 45 +++ .../68b06e589bf2273243814777.md | 6 +- .../68f6587287ad1f4ad39b0c7f.md | 4 +- .../6939b873185d8e00d453563c.md | 2 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 2 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 23 +- .../686b9720ee1d032bd77a480a.md | 65 +-- .../66c06fad3475cd92421b9ac2.md | 19 +- .../6842a6cd9836f0114a5b7a8a.md | 8 +- .../67d83df6f82eda3868dd2a84.md | 52 +-- .../694acade1d4afdbce71e5840.md | 100 ++++- .../684aaf9ec670c68d20efd0d0.md | 8 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 10 +- .../65a35429c637c13540c9be80.md | 2 +- .../65a35c7b9d642f478d6cabba.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 12 +- .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 10 + .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 16 + .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 18 +- .../672d49d93b54b85faa4dbad7.md | 67 +++- .../672d49e65a1c855fe7bb3fdb.md | 6 +- .../67d1ec87b34cee1d9219f7e9.md | 10 +- .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 22 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 18 +- .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 9 + .../6a3b86e9f96f6bbcd0ed8c45.md | 4 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 24 +- .../687e9437536d762823fefab3.md | 36 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 12 + .../67db30fedfa0b22a1a2a570c.md | 14 + .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 8 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 12 + .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 20 +- .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 12 +- .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 26 +- .../67d1a99d10fd509c88faf3bf.md | 18 +- .../67d2f4ddb4a4306fdf5bbaee.md | 12 +- .../6734e3ceee2da4b0301719b7.md | 12 + .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 14 + .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 20 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 10 + .../683d6a3fe8c1060ffb1f9b78.md | 8 + .../6732c05595ca7d422b9e55ff.md | 12 + .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 6 +- .../687ea8757080091969f07122.md | 14 + .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 6 + .../67d1a3fea729e274dc33d04d.md | 12 +- .../67d1eaf77f510e15dfed7c14.md | 12 +- .../67d1eb6929e68117faa6717f.md | 6 + .../673369067f824d33a90a0534.md | 12 + .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 2 +- .../698c302951ac746466349fd9.md | 167 +++++--- .../67f39e06b8a11b2de9ccd361.md | 72 ++-- .../6a02da945706a3ddc2e44348.md | 2 +- .../67f39b40deaec81a3e40e0c5.md | 24 +- .../598eea87e5cf4b116c3ff81a.md | 10 +- .../599d1566a02b571412643b84.md | 16 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818ed1adc249bb91d373729.md | 2 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 4 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 10 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 8 + .../6852db755c9c1274d75aae9a.md | 4 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 17 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 6 +- .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 8 +- .../647e21ba8acb466c97ccbee6.md | 39 -- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 47 ++- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 2 +- .../68af0687ef34c76c28ffa54b.md | 2 +- .../68b06e589bf2273243814777.md | 6 +- .../6939b873185d8e00d453563c.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 4 +- .../681cb05adab50c87ddb2e513.md | 55 +-- .../681cb1afdab50c87ddb2e515.md | 12 +- .../681cb1afdab50c87ddb2e517.md | 14 +- .../68adce01c0e1144d0a902958.md | 61 ++- .../68b06e589bf2273243814777.md | 18 +- .../68f6587287ad1f4ad39b0c7f.md | 18 +- .../6939b873185d8e00d453563c.md | 10 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 18 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 23 +- .../686b9720ee1d032bd77a480a.md | 43 +- .../66c06fad3475cd92421b9ac2.md | 21 +- .../6842a6cd9836f0114a5b7a8a.md | 12 +- .../67d83df6f82eda3868dd2a84.md | 42 +- .../694acade1d4afdbce71e5840.md | 101 ++++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 4 +- .../658147bb3dbda824437fd6f9.md | 2 +- .../65a35429c637c13540c9be80.md | 2 +- .../65a35c7b9d642f478d6cabba.md | 2 +- .../660f34626216270c682e2f7b.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 9 + .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 10 + .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 18 +- .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 16 + .../672d49d93b54b85faa4dbad7.md | 71 +++- .../672d49e65a1c855fe7bb3fdb.md | 6 +- .../67d1ec87b34cee1d9219f7e9.md | 8 + .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 24 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 20 +- .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 11 +- .../6a3b86e9f96f6bbcd0ed8c45.md | 6 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 26 +- .../687e9437536d762823fefab3.md | 38 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 12 + .../67db30fedfa0b22a1a2a570c.md | 20 +- .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 4 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 12 + .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 14 +- .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 8 + .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 14 + .../67d1a99d10fd509c88faf3bf.md | 16 + .../67d2f4ddb4a4306fdf5bbaee.md | 12 +- .../6734e3ceee2da4b0301719b7.md | 12 + .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 16 +- .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 26 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 16 +- .../683d6a3fe8c1060ffb1f9b78.md | 18 +- .../6732c05595ca7d422b9e55ff.md | 14 +- .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 4 +- .../687ea8757080091969f07122.md | 14 + .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 6 + .../67d1a3fea729e274dc33d04d.md | 12 +- .../67d1eaf77f510e15dfed7c14.md | 20 +- .../67d1eb6929e68117faa6717f.md | 10 +- .../673369067f824d33a90a0534.md | 12 + .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 2 +- .../698c302951ac746466349fd9.md | 149 ++++--- .../67f39e06b8a11b2de9ccd361.md | 49 +-- .../6a02da945706a3ddc2e44348.md | 2 +- .../67f39b40deaec81a3e40e0c5.md | 28 +- .../598eea87e5cf4b116c3ff81a.md | 2 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818ed1adc249bb91d373729.md | 2 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 10 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 8 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 8 + .../6852db755c9c1274d75aae9a.md | 4 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 19 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 39 ++ .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 8 +- .../bootstrap/bad87fee1348cd8acef08812.md | 2 +- .../647e21ba8acb466c97ccbee6.md | 39 -- .../647e21c48acb466c97ccbee7.md | 39 -- .../647e21d08acb466c97ccbee8.md | 39 -- .../647e21df8acb466c97ccbee9.md | 39 -- .../647e21eb8acb466c97ccbeea.md | 39 -- .../647e22058acb466c97ccbeec.md | 40 -- .../6ac3f7679fd5ceb2af42aa67.md | 39 ++ .../6ac3f76d9fd5ceb2af42aa68.md | 39 ++ .../6ac3f7739fd5ceb2af42aa69.md | 39 ++ .../6ac3f77a9fd5ceb2af42aa6a.md | 39 ++ .../681cb05adab50c87ddb2e513.md | 13 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../68adce01c0e1144d0a902958.md | 30 ++ .../68adce01c0e1144d0a90295e.md | 12 +- .../68af0687ef34c76c28ffa54b.md | 2 +- .../68b06e589bf2273243814777.md | 6 +- .../6939b873185d8e00d453563c.md | 4 +- .../69d03e549613fbdbe21d11e0.md | 4 +- .../681cb05adab50c87ddb2e513.md | 17 +- .../681cb1afdab50c87ddb2e515.md | 2 +- .../681cb1afdab50c87ddb2e517.md | 12 +- .../68adce01c0e1144d0a902958.md | 45 +++ .../68b06e589bf2273243814777.md | 6 +- .../68f6587287ad1f4ad39b0c7f.md | 4 +- .../6939b873185d8e00d453563c.md | 2 +- .../697a49e9860d24853adef680.md | 2 +- .../69d03e549613fbdbe21d11e0.md | 18 +- .../6690e10ebe2181212abc9652.md | 48 ++- .../69f0a37c3bf194a7c9c62492.md | 24 +- .../69a92f0b9cc04bb0d5327bb5.md | 25 +- .../686b9720ee1d032bd77a480a.md | 55 +-- .../66c06fad3475cd92421b9ac2.md | 21 +- .../6842a6cd9836f0114a5b7a8a.md | 12 +- .../67d83df6f82eda3868dd2a84.md | 50 +-- .../694acade1d4afdbce71e5840.md | 86 +++- .../684aaf9ec670c68d20efd0d0.md | 10 +- .../67eea33bbc314f248d210c93.md | 2 +- .../658147bb3dbda824437fd6f9.md | 2 +- .../65a35429c637c13540c9be80.md | 2 +- .../65a35c7b9d642f478d6cabba.md | 2 +- .../672ac9705b07a64439b73b59.md | 12 + .../68420bd261d0d35f61922d4b.md | 9 + .../6874b7d3b286c538b39d0c25.md | 10 + .../6908d38f7cccc31602743340.md | 10 + .../6882904fd7063f7258c0aef3.md | 10 + .../6734e3a9cc78faaf4248d335.md | 8 + .../6734e879c78ee6c61db25b90.md | 10 + .../674ba6876f7ada867135bb95.md | 8 + .../67fe81c9c6fd3714343a45ad.md | 54 ++- .../67fe8567f141d632afaeb71b.md | 17 + .../69fd6b21fcaa14b089c27182.md | 8 + .../67d2f5b78609f97400923f7f.md | 18 +- .../67d2f5dacd5e0c749e5d534c.md | 8 + .../67d2f5f19a0f0b75343f1905.md | 8 + .../67d1ab248317a5a29058a763.md | 14 + .../68420c70e4bfe26d52b780dc.md | 12 + .../672b951b1bf78038b1a2a0e7.md | 8 + .../68c3bc80f67363a31791fe1c.md | 16 + .../672d49d93b54b85faa4dbad7.md | 69 +++- .../672d49e65a1c855fe7bb3fdb.md | 6 +- .../67d1ec87b34cee1d9219f7e9.md | 8 + .../67fe859f55cd33356e322fd3.md | 8 + .../69661d2fc36411aa9e25ea64.md | 22 +- .../68420be9af9d89620af7944a.md | 14 + .../68c128cbd77e4ba9ed671937.md | 16 + .../6a89c69c2abed81397a6c99e.md | 12 + .../69a9184b42ae3947e4925016.md | 11 +- .../6a3b86e9f96f6bbcd0ed8c45.md | 6 +- .../6a3b86eac73558aaa2679c15.md | 10 + .../687e910842f3322350bc8d93.md | 26 +- .../687e9437536d762823fefab3.md | 34 +- .../687e944b821130283dc83b2e.md | 10 + .../687e947ae3ea7d2867c3d0e1.md | 28 +- .../687f0a1d5b7c4f21a9d8e123.md | 10 +- .../67d2ff1996e4ae9e67170502.md | 20 +- .../67db30fedfa0b22a1a2a570c.md | 20 +- .../67db31349f3ace2c5c803c33.md | 10 + .../68dd97fbd18ede5ae983e342.md | 2 +- .../69fc757399f4066e674a5161.md | 32 +- .../67fe8597975ea634042cad8f.md | 8 + .../672acc03c257524d6a5151e8.md | 10 + .../672aa669960f6a596081fcad.md | 12 + .../672d26269456511aa3db614d.md | 10 + .../672d456f4ac35950b300e93f.md | 8 + .../6732c6c72d3738614e1230a2.md | 12 + .../688291b65db00473e1136725.md | 14 + .../672bc51370c789be459186b4.md | 8 + .../672bd658c0e190f674a5e057.md | 1 + .../672bcc9c4a6dd6d7dd3e6357.md | 12 +- .../672bccebe1fc82d911c3f078.md | 14 + .../67d1a99d10fd509c88faf3bf.md | 16 + .../67d2f4ddb4a4306fdf5bbaee.md | 10 + .../6734e3ceee2da4b0301719b7.md | 12 + .../673500b41af8500191febedc.md | 12 + .../672ac3c5d0e9fd31835ff772.md | 64 ++- .../672ac3f129efbf327742eb33.md | 34 +- .../672ac403a9ba7732b31c6480.md | 2 + .../672a4cd3d59756726657efb8.md | 8 + .../672a4ce6dab9eb735828b48b.md | 8 + .../67d301a5f536d1a9e5df1a8c.md | 14 + .../672a511bb408ec81c592eb68.md | 4 + .../6839e38cdf93ee5a00c79676.md | 16 + .../6839e3a99ba37f09b9d0059b.md | 26 +- .../6839e4b003571c149bcda122.md | 6 + .../6839e4d62ae09d1661e4cf9b.md | 18 +- .../683d6a3fe8c1060ffb1f9b78.md | 16 +- .../6732c05595ca7d422b9e55ff.md | 14 +- .../688170ebc58d8d3b1ae493a2.md | 10 + .../695cc6a5eefd305381ec90bc.md | 10 +- .../695cc8f280fef0cc3bed02ca.md | 4 +- .../687ea8757080091969f07122.md | 22 +- .../687ea899461e37199cf03cf9.md | 12 + .../687ea8e0cab41019dc8a728a.md | 10 + .../687ea8eba2a8b119f2ad9f8c.md | 18 + .../68817041f57ce139bef36541.md | 8 + .../6881705cd9860639e98d639d.md | 6 + .../67d1a3fea729e274dc33d04d.md | 20 +- .../67d1eaf77f510e15dfed7c14.md | 18 +- .../67d1eb6929e68117faa6717f.md | 8 +- .../673369067f824d33a90a0534.md | 12 + .../66ed9010f45ce3ece4053eb8.md | 2 +- .../69fd84e01123960e15bb8455.md | 14 +- .../6a439658bfbe59fcf4b221c7.md | 2 +- .../698c302951ac746466349fd9.md | 155 +++++--- .../67f39e06b8a11b2de9ccd361.md | 61 +-- .../6a02da945706a3ddc2e44348.md | 4 +- .../67f39b40deaec81a3e40e0c5.md | 22 +- .../598eea87e5cf4b116c3ff81a.md | 4 +- .../6996c675b599baa7b103192d.md | 2 +- .../6996c7363a4a437839f1f15d.md | 2 +- .../6996c796385b6ea4e222d5e8.md | 2 +- .../6996c8375f4301004459ee85.md | 4 +- .../6996c8f94fe6b250f11a2a1e.md | 6 +- .../6996c95e5bede03bdf2937a2.md | 6 +- .../6996ca21a74104721f2c7e5d.md | 6 +- .../6996cb5869acf58de751ae81.md | 6 +- .../6996ccadf9048c79b857bb15.md | 8 +- .../6996cdf1f60cbc30eeeae1c9.md | 6 +- .../6996cfb6c01e9a802add38be.md | 6 +- .../6996d0a2c2ac55041145a13f.md | 6 +- .../6996d1032feed88e2957dc8e.md | 6 +- .../6996d18b31aab5cbbffbc731.md | 12 +- .../6810891bd6de8a87a833df42.md | 4 +- .../6818ed1adc249bb91d373729.md | 2 +- .../6818fcb250f34e62cab32c39.md | 10 +- .../681a2a6cf95e82ca30866364.md | 4 +- .../681a44f4c3235f7d8f428545.md | 2 +- .../6853f4584f508e95cc7a9f4d.md | 12 +- .../685cdfd1932d8ac6ad986813.md | 2 +- .../69de4308e652aaeb5ccdb03e.md | 40 ++ .../69e20876baed33de636b989a.md | 66 ++++ .../69e20a0451c7a3ef189514d3.md | 70 ++++ .../69e6284f3b7659c5a05c2a79.md | 72 ++++ .../69e6299710319e7cb8ebdc37.md | 75 ++++ .../69e62ce96df237884da25282.md | 128 ++++++ .../69e736c39dfa403496e8071e.md | 88 +++++ .../69e73a141addc6f442924b0d.md | 121 ++++++ .../69e73f4f5f986657647bbd63.md | 97 +++++ .../69e75dc335b6ec9903a87d3e.md | 135 +++++++ .../69e76d1997661be7f0040e2d.md | 122 ++++++ .../69e76e91402d7850510a5f18.md | 109 +++++ .../69e774b82fe0bfdb684f95b4.md | 114 ++++++ .../69e7766b93d27261775d1cf1.md | 141 +++++++ .../69eb3158c33d9a229a79951c.md | 120 ++++++ .../6a71a8df10e823e77358d896.md | 66 ++++ .../6a71b3e49668c3be461257b5.md | 64 +++ .../6a73427af41619a909fb21b4.md | 190 +++++++++ .../6a86b9e64da746838e67fb13.md | 80 ++++ .../6a86be3e8cc29e9ae239e70a.md | 101 +++++ .../6a870cc60c23f0332a2fe788.md | 46 +++ .../6ac09f8420b4b67e075d2cd2.md | 45 +++ .../6ac0a4463662d9738c393e21.md | 45 +++ .../6ac0aaba914d81b32567c076.md | 44 +++ .../6ac0ae563f6de70930f47ef7.md | 42 ++ .../6ac0b35f3b29a27f7e207295.md | 44 +++ .../6a3e4ae26f2b7e4b5b026cf8.md | 2 +- .../6a3e5475c35dbc138d77c6f4.md | 9 +- .../6a3e67fc5ef4045201c28219.md | 2 - .../6a3e6fd08125dfa615cb431b.md | 2 + .../6a3e7284e89ce3367e709331.md | 2 +- .../684fdb4386b473631d8e27ca.md | 25 +- .../684fde383e4b1298310927b9.md | 10 +- .../684fe1be09b05ad785832546.md | 10 +- .../685081f42afaba3a60bdf94f.md | 2 +- .../6851051b0da0e34840f3919f.md | 2 +- .../685106fab1f801691d8f58a0.md | 2 +- .../685118ddcad14fa5d62faaef.md | 2 +- .../68511abf14415dc7c27fbea7.md | 2 +- .../68511bdce9282edbef75ca48.md | 2 +- .../68516ab0ba81759b1ff864e3.md | 2 +- .../68516d0c0cb162c7578616ad.md | 2 +- .../68516e3c627b43de8c138ea9.md | 23 +- .../6851719eee78621daa093a00.md | 10 +- .../68517af94b02d6cc2bc08280.md | 4 +- .../68529393dcd6a5c80de570fc.md | 4 +- .../685294b4a1ccb3de0e40410c.md | 4 +- .../68529fb26c581f13e901de3a.md | 8 +- .../6852c7f62711efe79f8a4219.md | 4 +- .../6958de0d773289a89515a6b8.md | 8 + .../6852db755c9c1274d75aae9a.md | 4 +- .../6740495ba48aa94e5667b436.md | 15 +- .../67457ff2dc531fbed928a0f0.md | 11 +- .../6745c732dbeb7c04f346e6f7.md | 11 +- .../6745c7b06a0b530602cb63fa.md | 11 +- .../6745c89fba004707ded84453.md | 17 +- .../6745cebbf97ef2129f3b9bab.md | 17 +- .../6745d799beeb822076a4da9d.md | 11 +- .../6745d9df333efe2543a1f457.md | 17 +- .../6745dce846995b2a466594be.md | 11 +- .../6745de9ce925b92d72df713a.md | 19 +- .../6745e2aca895c935168e7d91.md | 79 ++-- .../647e21ba8acb466c97ccbee6.md | 39 ++ .../647e235a8acb466c97ccbf00.md | 44 --- .../647e236d8acb466c97ccbf01.md | 41 -- .../647e23828acb466c97ccbf03.md | 39 -- .../647e238f8acb466c97ccbf04.md | 8 +- 2444 files changed, 51128 insertions(+), 11253 deletions(-) delete mode 100644 curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md rename curriculum/challenges/arabic/blocks/{create-and-run-simple-c-sharp-console-applications => write-your-first-code-using-c-sharp}/647e21ba8acb466c97ccbee6.md (62%) delete mode 100644 curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md create mode 100644 curriculum/challenges/chinese-traditional/blocks/write-your-first-code-using-c-sharp/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/chinese-traditional/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/chinese-traditional/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/chinese-traditional/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/chinese/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/chinese/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/chinese/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/chinese/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/chinese/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/chinese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/chinese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/chinese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/chinese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/chinese/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md rename curriculum/challenges/chinese/blocks/{create-and-run-simple-c-sharp-console-applications => write-your-first-code-using-c-sharp}/647e21ba8acb466c97ccbee6.md (58%) delete mode 100644 curriculum/challenges/chinese/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/chinese/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/chinese/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/espanol/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/espanol/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/espanol/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/espanol/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/espanol/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/espanol/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/espanol/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/espanol/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/espanol/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/espanol/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md rename curriculum/challenges/espanol/blocks/{create-and-run-simple-c-sharp-console-applications => write-your-first-code-using-c-sharp}/647e21ba8acb466c97ccbee6.md (55%) delete mode 100644 curriculum/challenges/espanol/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/espanol/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/espanol/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/german/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/german/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/german/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/german/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/german/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/german/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/german/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/german/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/german/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/german/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/german/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/german/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/german/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/german/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/german/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md rename curriculum/challenges/german/blocks/{create-and-run-simple-c-sharp-console-applications => write-your-first-code-using-c-sharp}/647e21ba8acb466c97ccbee6.md (51%) delete mode 100644 curriculum/challenges/german/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/german/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/german/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/italian/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/italian/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/italian/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/italian/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/italian/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/italian/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/italian/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/italian/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/italian/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/italian/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/italian/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/italian/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/italian/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/italian/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/italian/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md rename curriculum/challenges/italian/blocks/{create-and-run-simple-c-sharp-console-applications => write-your-first-code-using-c-sharp}/647e21ba8acb466c97ccbee6.md (62%) delete mode 100644 curriculum/challenges/italian/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/italian/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/italian/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/japanese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/japanese/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md create mode 100644 curriculum/challenges/japanese/blocks/write-your-first-code-using-c-sharp/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/japanese/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/japanese/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/japanese/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/korean/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/korean/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/korean/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/korean/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/korean/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/korean/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/korean/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md create mode 100644 curriculum/challenges/korean/blocks/write-your-first-code-using-c-sharp/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/korean/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/korean/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/korean/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/portuguese/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/portuguese/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/portuguese/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/portuguese/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/portuguese/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/portuguese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/portuguese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/portuguese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/portuguese/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/portuguese/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md rename curriculum/challenges/portuguese/blocks/{create-and-run-simple-c-sharp-console-applications => write-your-first-code-using-c-sharp}/647e21ba8acb466c97ccbee6.md (59%) delete mode 100644 curriculum/challenges/portuguese/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/portuguese/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/portuguese/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/swahili/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/swahili/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md create mode 100644 curriculum/challenges/swahili/blocks/write-your-first-code-using-c-sharp/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/swahili/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/swahili/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/swahili/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md delete mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md delete mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md delete mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md delete mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md delete mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md create mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md create mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md create mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md create mode 100644 curriculum/challenges/ukrainian/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md create mode 100644 curriculum/challenges/ukrainian/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md create mode 100644 curriculum/challenges/ukrainian/blocks/write-your-first-code-using-c-sharp/647e21ba8acb466c97ccbee6.md delete mode 100644 curriculum/challenges/ukrainian/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md delete mode 100644 curriculum/challenges/ukrainian/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md delete mode 100644 curriculum/challenges/ukrainian/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md diff --git a/client/arabic/intro.json b/client/arabic/intro.json index bcb5afcd2d4..fefcd4a7304 100644 --- a/client/arabic/intro.json +++ b/client/arabic/intro.json @@ -1517,6 +1517,12 @@ "في ورشة العمل هذه، ستتمرن على أساسيات معالجة السلاسل النصية في Python من خلال بناء أداة تولد بطاقات موظفين منسقة وتحلل رموز الموظفين." ] }, + "workshop-employee-profile-validator": { + "title": "بناء مدقق ملف موظف", + "intro": [ + "في ورشة العمل هذه، ستستخدم طرق السلاسل النصية في Python للتحقق من صحة البيانات وتنسيقها من ملف موظف." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "الأرقام والعمليات الرياضية", "intro": [ @@ -6478,6 +6484,12 @@ "في ورشة العمل هذه، ستتمرن على أساسيات معالجة السلاسل النصية في Python من خلال بناء أداة تولد شارات موظفين منسقة وتحلل رموز الموظفين." ] }, + "workshop-employee-profile-validator": { + "title": "بناء مدقق ملف موظف", + "intro": [ + "في ورشة العمل هذه، ستستخدم طرق السلاسل النصية في Python للتحقق من صحة البيانات وتنسيقها من ملف موظف." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "الأرقام والعمليات الرياضية", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "بناء شخصية لعبة تقمص الأدوار", "intro": [ - "في هذا المختبر، ستتمرن على أساسيات Python من خلال بناء شخصية لعبة تقمص الأدوار." + "في هذا المختبر، ستتمرن على أساسيات Python ببناء شخصية لعبة تقمص أدوار (RPG)." ] }, "review-python-basics": { @@ -7006,7 +7018,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "فهم سطر الأوامر والعمل مع باش", "intro": [ - "تعلم عن سطر الأوامر والعمل مع باش في هذه الدروس." + "تعلم عن سطر الأوامر والعمل مع Bash في هذه الدروس." ] }, "workshop-bash-boilerplate": { @@ -10407,6 +10419,359 @@ "english-only": "الدورات في هذا القسم متاحة فقط باللغة الإنجليزية. يمكننا ترجمة العناوين والمقدمات فقط في الوقت الحالي، وليس الدروس نفسها.", "exam-english-only": "يرجى ملاحظة أن اختبار الشهادة متاح حاليًا فقط باللغة الإنجليزية. بقية الدورات متاحة ببعض اللغات." }, + "python-programming-fundamentals": { + "title": "أساسيات برمجة Python", + "intro": [ + "هذا المساق يعلّم أساسيات برمجة Python.", + "أكمل المشاريع المطلوبة ونجح في الاختبار لتحصل على شهادة أساسيات برمجة Python." + ], + "chapters": { + "python-programming-fundamentals": "أساسيات برمجة Python" + }, + "modules": { + "python-basics": "أساسيات Python", + "python-installation": "تثبيت Python", + "python-loops-and-sequences": "الحلقات والمتتاليات", + "python-dictionaries-and-sets": "القواميس والمجموعات", + "lab-user-configuration-manager": "بناء مدير تكوين المستخدم", + "python-error-handling": "معالجة الأخطاء", + "python-classes-and-objects": "الأصناف والكائنات", + "lab-budget-app": "بناء تطبيق ميزانية", + "python-object-oriented-programming": "البرمجة كائنية التوجه (OOP)", + "lab-polygon-area-calculator": "بناء حاسبة مساحة مضلع", + "review-python-programming-fundamentals": "مراجعة Python" + }, + "blocks": { + "workshop-first-python-program": { + "title": "بناء أول برنامج Python", + "intro": [ + "في ورشة العمل هذه، ستبني أول برنامج لك بلغة Python." + ] + }, + "lecture-introduction-to-python": { + "title": "مقدمة إلى Python", + "intro": [ + "في هذه الدروس، ستتعلم ما هي Python والاستخدامات الشائعة لها في الصناعة." + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "فهم المتغيرات وأنواع البيانات", + "intro": [ + "في هذه الدروس، ستتعلم عن المتغيرات وأنواع البيانات في Python." + ] + }, + "workshop-report-card-printer": { + "title": "بناء طابعة بطاقة تقرير", + "intro": [ + "في ورشة العمل هذه، ستتمرن على العمل مع أنواع البيانات الأولية في Python بإنشاء وطباعة بيانات بطاقة تقرير بسيطة." + ] + }, + "lecture-introduction-to-python-strings": { + "title": "مقدمة إلى السلاسل النصية", + "intro": ["في هذه الدروس، ستتعلم عن السلاسل النصية في Python."] + }, + "workshop-employee-profile-generator": { + "title": "بناء مولد ملف موظف", + "intro": [ + "في ورشة العمل هذه، ستتمرن على أساسيات معالجة السلاسل النصية في Python ببناء أداة تولد بطاقات موظفين منسقة وتحلل رموز الموظفين." + ] + }, + "workshop-employee-profile-validator": { + "title": "بناء مدقق ملف موظف", + "intro": [ + "في ورشة العمل هذه، ستستخدم طرق السلاسل النصية في Python للتحقق من صحة البيانات وتنسيقها من ملف موظف." + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "الأرقام والعمليات الرياضية", + "intro": [ + "في هذه الدروس، ستتعلم عن الأرقام والعمليات الرياضية في Python." + ] + }, + "workshop-bill-splitter": { + "title": "بناء مقسم فاتورة", + "intro": [ + "في ورشة العمل هذه، ستبني مقسم فاتورة لتتمرن على العمل مع الأرقام والعمليات الرياضية في Python." + ] + }, + "lecture-booleans-and-conditionals": { + "title": "القيم المنطقية والشرطيات", + "intro": [ + "في هذه الدروس، ستتعلم عن القيم المنطقية والشرطيات في Python." + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "بناء حاسبة حجز تذاكر الأفلام", + "intro": [ + "في ورشة العمل هذه، ستتمرن على استخدام القيم المنطقية وعبارات الشرط في Python ببناء حاسبة حجز تذاكر الأفلام." + ] + }, + "lab-travel-weather-planner": { + "title": "بناء مخطط طقس السفر", + "intro": [ + "في هذا المختبر، ستبني مخطط طقس للسفر باستخدام الشرطيات." + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "فهم الدوال والنطاق", + "intro": [ + "في هذه الدروس، ستتعلم عن الدوال والنطاق في Python." + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "بناء متتبع مخزون المطبخ", + "intro": [ + "في ورشة العمل هذه، ستتمرن على العمل مع الدوال والنطاق في Python ببناء متتبع مخزون المطبخ." + ] + }, + "lab-discount-calculator": { + "title": "بناء دالة تطبيق الخصم", + "intro": [ + "في هذا المختبر، ستتمرن على أساسيات Python ببناء حاسبة لتطبيق خصم على سعر." + ] + }, + "workshop-caesar-cipher": { + "title": "بناء تشفير قيصر", + "intro": [ + "في ورشة العمل هذه، ستبني تشفير قيصر باستخدام مفاهيم Python الأساسية مثل السلاسل النصية، الشرطيات، الدوال، والمزيد." + ] + }, + "lab-rpg-character": { + "title": "بناء شخصية لعبة تقمص أدوار (RPG)", + "intro": [ + "في هذا المختبر، ستتمرن على أساسيات Python ببناء شخصية لعبة تقمص أدوار (RPG)." + ] + }, + "review-python-basics": { + "title": "مراجعة أساسيات Python", + "intro": [ + "قبل أن تخضع لاختبار أساسيات Python، يجب أن تراجع ما تعلمته عنها.", + "في صفحة المراجعة هذه، ستراجع العمل مع السلاسل النصية، الدوال، عوامل المقارنة، والمزيد." + ] + }, + "quiz-python-basics": { + "title": "اختبار أساسيات Python", + "intro": [ + "اختبر ما تعلمته عن أساسيات Python بهذا الاختبار." + ] + }, + "lecture-python-installation": { + "title": "تثبيت Python وتشغيل الكود محليًا", + "intro": [ + "في هذه الدروس، ستتعلم كيفية تثبيت Python على جهازك المحلي وتشغيل الكود محليًا." + ] + }, + "review-python-installation": { + "title": "مراجعة تثبيت Python", + "intro": [ + "قبل أن تخضع لاختبار العمل مع Python محليًا، يجب أن تراجع المفاهيم التي غطتها الدروس." + ] + }, + "quiz-python-installation": { + "title": "اختبار تثبيت Python", + "intro": [ + "اختبر ما تعلمته عن تثبيت Python محليًا بهذا الاختبار." + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "العمل مع الحلقات والمتتاليات", + "intro": [ + "تعلم عن العمل مع الحلقات والمتتاليات في هذه الدروس." + ] + }, + "workshop-pin-extractor": { + "title": "بناء مستخرج رموز سرية", + "intro": [ + "في ورشة العمل هذه، ستبني دالة لاستخراج الرموز السرية المخفية في القصائد." + ] + }, + "lab-number-pattern-generator": { + "title": "بناء مولد نمط أرقام", + "intro": ["في هذا المختبر، ستبني مولد نمط أرقام."] + }, + "review-loops-and-sequences": { + "title": "مراجعة الحلقات والمتتاليات", + "intro": [ + "قبل أن تخضع لاختبار الحلقات والمتتاليات، يجب أن تراجع ما تعلمته عنها.", + "افتح هذه الصفحة لمراجعة المفاهيم حول الحلقات، القوائم، الصفوف المرتبة وبعض طرقها الشائعة." + ] + }, + "quiz-loops-and-sequences": { + "title": "اختبار الحلقات والمتتاليات", + "intro": [ + "اختبر ما تعلمته عن الحلقات والمتتاليات في Python بهذا الاختبار." + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "العمل مع القواميس والمجموعات", + "intro": [ + "تعلم عن العمل مع القواميس والمجموعات في هذه الدروس." + ] + }, + "lecture-working-with-modules": { + "title": "العمل مع الوحدات", + "intro": ["تعلم العمل مع الوحدات في هذه الدروس."] + }, + "workshop-medical-data-validator": { + "title": "بناء مدقق بيانات طبية", + "intro": [ + "في ورشة العمل هذه، ستتمرن على التعامل مع القواميس والمجموعات أثناء التحقق من صحة مجموعة من البيانات الطبية." + ] + }, + "review-dictionaries-and-sets": { + "title": "مراجعة القواميس والمجموعات", + "intro": [ + "قبل أن تخضع لاختبار حول القواميس والمجموعات، يجب أن تراجع ما تعلمته عنها.", + "افتح هذه الصفحة لمراجعة مفاهيم القواميس والمجموعات وكيفية استيراد الوحدات." + ] + }, + "quiz-dictionaries-and-sets": { + "title": "اختبار القواميس والمجموعات", + "intro": [ + "اختبر ما تعلمته عن القواميس والمجموعات في بايثون بهذا الاختبار." + ] + }, + "lab-user-configuration-manager": { + "title": "بناء مدير تكوين المستخدم", + "intro": [ + "في هذا المختبر، ستتمرن على التعامل مع القواميس في بايثون." + ] + }, + "lecture-understanding-error-handling": { + "title": "فهم معالجة الأخطاء", + "intro": [ + "في هذه الدروس، ستتعلم عن معالجة الأخطاء في بايثون. ستتعرف على أنواع الأخطاء المختلفة، وبعض ممارسات تصحيح الأخطاء الجيدة، ما هي الاستثناءات، وكيفية التعامل معها." + ] + }, + "lab-isbn-validator": { + "title": "تصحيح مدقق ISBN", + "intro": [ + "في هذا المختبر، ستبدأ بتطبيق يحتوي على أخطاء برمجية، وستحتاج إلى تصحيح هذه الأخطاء حتى يعمل التطبيق بشكل صحيح." + ] + }, + "review-error-handling": { + "title": "مراجعة معالجة الأخطاء", + "intro": [ + "قبل أن تخضع لاختبار معالجة الأخطاء، يجب أن تراجع ما تعلمته عنها." + ] + }, + "quiz-error-handling": { + "title": "اختبار معالجة الأخطاء", + "intro": [ + "اختبر ما تعلمته عن معالجة الأخطاء في بايثون بهذا الاختبار." + ] + }, + "lecture-classes-and-objects": { + "title": "الصنف والكائنات", + "intro": ["تعلم عن الأصناف والكائنات في هذه الدروس."] + }, + "workshop-musical-instrument-inventory": { + "title": "بناء جرد الآلات الموسيقية", + "intro": [ + "في ورشة العمل هذه، ستتعلم عن الأصناف والكائنات والطرق في بايثون من خلال بناء جرد بسيط للآلات الموسيقية." + ] + }, + "lab-planet-class": { + "title": "بناء صنف كوكب", + "intro": [ + "في هذا المختبر، ستنشئ صنفًا يمثل كوكبًا." + ] + }, + "workshop-email-simulator": { + "title": "بناء محاكي بريد إلكتروني", + "intro": [ + "في ورشة العمل هذه، ستنفذ الأصناف والكائنات من خلال بناء محاكي بريد إلكتروني يحاكي إرسال واستقبال وإدارة الرسائل بين المستخدمين المختلفين." + ] + }, + "review-classes-and-objects": { + "title": "مراجعة الأصناف والكائنات", + "intro": [ + "قبل أن تخضع لاختبار الأصناف والكائنات، يجب أن تراجع ما تعلمته عنها.", + "افتح هذه الصفحة لمراجعة مفاهيم مثل كيفية عمل الأصناف، ما هي الكائنات، الطرق، الخصائص، الطرق الخاصة والمزيد." + ] + }, + "quiz-classes-and-objects": { + "title": "اختبار الأصناف والكائنات", + "intro": [ + "اختبر ما تعلمته عن الأصناف والكائنات في بايثون بهذا الاختبار." + ] + }, + "lab-budget-app": { + "title": "بناء تطبيق ميزانية", + "intro": [ + "في هذا المختبر، ستبني تطبيق ميزانية وتتمرن على إنشاء صنف وطرق لذلك الصنف." + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "فهم البرمجة كائنية التوجه والتغليف", + "intro": [ + "تعلم عن فهم البرمجة كائنية التوجه والتغليف في هذه الدروس." + ] + }, + "workshop-salary-tracker": { + "title": "بناء متتبع رواتب", + "intro": [ + "في ورشة العمل هذه، ستتمرن على التغليف والخصائص ومفاهيم أخرى في البرمجة كائنية التوجه من خلال بناء نظام تتبع رواتب للموظفين." + ] + }, + "lab-game-character-stats": { + "title": "بناء متتبع إحصائيات شخصية لعبة", + "intro": [ + "في هذا المختبر، ستبني شخصية لعبة مع إحصائيات مختلفة باستخدام البرمجة كائنية التوجه." + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "فهم الوراثة وتعدد الأشكال", + "intro": [ + "تعلم عن فهم الوراثة وتعدد الأشكال في هذه الدروس." + ] + }, + "workshop-media-catalogue": { + "title": "بناء كتالوج وسائط", + "intro": [ + "في ورشة العمل هذه، ستنشئ تطبيق كتالوج وسائط باستخدام مبادئ البرمجة كائنية التوجه." + ] + }, + "lecture-understanding-abstraction": { + "title": "فهم التجريد", + "intro": ["تعلم عن فهم التجريد في هذه الدروس."] + }, + "workshop-discount-calculator": { + "title": "بناء حاسبة خصم", + "intro": [ + "في ورشة العمل هذه، ستبني حاسبة أسعار خصم مرنة من خلال الأصناف الأساسية المجردة، مما يسمح بتطبيق خوارزميات خصم متعددة بالتبادل دون تعديل المنطق الأساسي." + ] + }, + "lab-player-interface": { + "title": "بناء واجهة لاعب", + "intro": [ + "في هذا المختبر، ستستخدم وحدة abc لبناء واجهة لاعب." + ] + }, + "review-object-oriented-programming": { + "title": "مراجعة البرمجة كائنية التوجه", + "intro": [ + "قبل أن تخضع لاختبار البرمجة كائنية التوجه، يجب أن تراجع ما تعلمته عنها." + ] + }, + "quiz-object-oriented-programming": { + "title": "اختبار البرمجة كائنية التوجه", + "intro": [ + "اختبر ما تعلمته عن البرمجة كائنية التوجه في بايثون بهذا الاختبار." + ] + }, + "lab-polygon-area-calculator": { + "title": "بناء حاسبة مساحة مضلع", + "intro": [ + "في هذا المختبر، ستستخدم البرمجة كائنية التوجه لحساب مساحات مضلعات مختلفة مثل المربعات والمستطيلات." + ] + }, + "review-python": { + "title": "مراجعة أساسيات برمجة بايثون", + "intro": ["راجع مفاهيم بايثون للتحضير للاختبار القادم."] + } + } + }, "algorithms-and-data-structure": { "title": "شهادة الخوارزميات وهيكل البيانات", "intro": [ diff --git a/client/chinese-traditional/intro.json b/client/chinese-traditional/intro.json index f3ce205a76d..3f5e3d5e18d 100644 --- a/client/chinese-traditional/intro.json +++ b/client/chinese-traditional/intro.json @@ -1221,7 +1221,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "理解命令列與使用 Bash", "intro": [ - "在這些課程中學習命令列與使用 Bash。" + "在這些課程中學習命令列和使用 Bash。" ] }, "workshop-bash-boilerplate": { @@ -1517,6 +1517,12 @@ "在這個工作坊中,你將透過建造一個產生格式化員工證件並分析員工代碼的工具,練習 Python 字串操作的基礎。" ] }, + "workshop-employee-profile-validator": { + "title": "建置員工資料驗證器", + "intro": [ + "在這個工作坊中,你將使用 Python 字串方法來驗證和格式化員工資料。" + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "數字與數學運算", "intro": [ @@ -6478,6 +6484,12 @@ "在這個工作坊中,你將透過建置一個產生格式化員工證件並分析員工代碼的工具,練習 Python 字串操作的基礎。" ] }, + "workshop-employee-profile-validator": { + "title": "建置員工資料驗證器", + "intro": [ + "在這個工作坊中,你將使用 Python 字串方法來驗證和格式化員工資料。" + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "數字與數學運算", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "建置一個 RPG 角色", "intro": [ - "在這個實驗中,你將透過建置一個 RPG 角色來練習基本的 Python。" + "在這個實驗中,你將透過建置一個 RPG 角色來練習 Python 基礎。" ] }, "review-python-basics": { @@ -7006,7 +7018,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "理解命令列與使用 Bash", "intro": [ - "在這些課程中學習命令列與使用 Bash。" + "在這些課程中學習命令列和使用 Bash。" ] }, "workshop-bash-boilerplate": { @@ -10407,6 +10419,359 @@ "english-only": "本區的課程僅提供英文版本。目前我們只能翻譯標題和介紹,課程內容尚未翻譯。", "exam-english-only": "請注意,認證考試目前僅提供英文版本。其他課程則有部分語言版本。" }, + "python-programming-fundamentals": { + "title": "Python 程式設計基礎", + "intro": [ + "本課程教授 Python 程式設計的基礎。", + "完成指定專案並通過考試,即可獲得 Python 程式設計基礎認證。" + ], + "chapters": { + "python-programming-fundamentals": "Python 程式設計基礎" + }, + "modules": { + "python-basics": "Python 基礎", + "python-installation": "安裝 Python", + "python-loops-and-sequences": "迴圈與序列", + "python-dictionaries-and-sets": "字典與集合", + "lab-user-configuration-manager": "建置使用者設定管理器", + "python-error-handling": "錯誤處理", + "python-classes-and-objects": "類別與物件", + "lab-budget-app": "建置預算應用程式", + "python-object-oriented-programming": "物件導向程式設計(OOP)", + "lab-polygon-area-calculator": "建置多邊形面積計算器", + "review-python-programming-fundamentals": "Python 複習" + }, + "blocks": { + "workshop-first-python-program": { + "title": "建置你的第一個 Python 程式", + "intro": [ + "在這個工作坊中,你將建置你的第一個 Python 程式。" + ] + }, + "lecture-introduction-to-python": { + "title": "Python 簡介", + "intro": [ + "在這些課程中,你將了解 Python 是什麼以及其在業界的常見應用。" + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "理解變數與資料型別", + "intro": [ + "在這些課程中,你將學習 Python 中的變數與資料型別。" + ] + }, + "workshop-report-card-printer": { + "title": "建置成績單列印器", + "intro": [ + "在這個工作坊中,你將透過建立並列印簡單成績單的資料,練習使用 Python 的原始資料型別。" + ] + }, + "lecture-introduction-to-python-strings": { + "title": "字串簡介", + "intro": ["在這些課程中,你將學習 Python 中的字串。"] + }, + "workshop-employee-profile-generator": { + "title": "建置員工資料產生器", + "intro": [ + "在這個工作坊中,你將透過建置一個產生格式化員工證件並分析員工代碼的工具,練習 Python 字串操作基礎。" + ] + }, + "workshop-employee-profile-validator": { + "title": "建置員工資料驗證器", + "intro": [ + "在這個工作坊中,你將使用 Python 字串方法來驗證和格式化員工資料。" + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "數字與數學運算", + "intro": [ + "在這些課程中,你將學習 Python 中的數字與數學運算。" + ] + }, + "workshop-bill-splitter": { + "title": "建置帳單分攤器", + "intro": [ + "在這個工作坊中,你將建置一個帳單分攤器,練習使用 Python 處理數字與數學運算。" + ] + }, + "lecture-booleans-and-conditionals": { + "title": "布林值與條件判斷", + "intro": [ + "在這些課程中,你將學習 Python 中的布林值與條件判斷。" + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "建置電影票訂票計算器", + "intro": [ + "在這個工作坊中,你將透過建置電影票訂票計算器,練習使用 Python 的布林值與條件敘述。" + ] + }, + "lab-travel-weather-planner": { + "title": "建置旅遊天氣規劃器", + "intro": [ + "在這個實驗中,你將使用條件判斷建置旅遊天氣規劃器。" + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "理解函式與作用域", + "intro": [ + "在這些課程中,你將學習 Python 中的函式與作用域。" + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "建置廚房庫存追蹤器", + "intro": [ + "在這個工作坊中,你將透過建置廚房庫存追蹤器,練習使用 Python 的函式與作用域。" + ] + }, + "lab-discount-calculator": { + "title": "建置折扣套用函式", + "intro": [ + "在這個實驗中,你將透過建置一個折扣計算器來練習 Python 基礎。" + ] + }, + "workshop-caesar-cipher": { + "title": "建置凱薩密碼", + "intro": [ + "在這個工作坊中,你將使用字串、條件判斷、函式等 Python 基礎概念建置凱薩密碼。" + ] + }, + "lab-rpg-character": { + "title": "建置 RPG 角色", + "intro": [ + "在這個實驗中,你將透過建置一個 RPG 角色來練習 Python 基礎。" + ] + }, + "review-python-basics": { + "title": "Python 基礎複習", + "intro": [ + "在接受 Python 基礎測驗前,你應該先複習所學內容。", + "在這個複習頁面中,你將複習字串、函式、比較運算子等內容。" + ] + }, + "quiz-python-basics": { + "title": "Python 基礎測驗", + "intro": [ + "透過此測驗檢驗你對 Python 基礎的理解。" + ] + }, + "lecture-python-installation": { + "title": "安裝 Python 並在本機執行程式碼", + "intro": [ + "在這些課程中,你將學習如何在本機裝置安裝 Python 並執行程式碼。" + ] + }, + "review-python-installation": { + "title": "Python 安裝複習", + "intro": [ + "在接受本機 Python 操作測驗前,你應該先複習課程涵蓋的概念。" + ] + }, + "quiz-python-installation": { + "title": "Python 安裝測驗", + "intro": [ + "透過此測驗檢驗你對本機安裝 Python 的理解。" + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "使用迴圈與序列", + "intro": [ + "在這些課程中,學習如何使用迴圈與序列。" + ] + }, + "workshop-pin-extractor": { + "title": "建置密碼提取器", + "intro": [ + "在這個工作坊中,你將建置一個函式來提取詩中隱藏的秘密密碼。" + ] + }, + "lab-number-pattern-generator": { + "title": "建置數字樣式產生器", + "intro": ["在這個實驗中,你將建置一個數字樣式產生器。"] + }, + "review-loops-and-sequences": { + "title": "迴圈與序列複習", + "intro": [ + "在接受迴圈與序列測驗前,你應該先複習所學內容。", + "打開此頁面複習迴圈、列表、元組及其常用方法的概念。" + ] + }, + "quiz-loops-and-sequences": { + "title": "迴圈與序列測驗", + "intro": [ + "透過此測驗檢驗你對 Python 迴圈與序列的理解。" + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "使用字典與集合", + "intro": [ + "在這些課程中,學習如何使用字典與集合。" + ] + }, + "lecture-working-with-modules": { + "title": "模組操作", + "intro": ["在這些課程中學習如何操作模組。"] + }, + "workshop-medical-data-validator": { + "title": "建置醫療資料驗證器", + "intro": [ + "在這個工作坊中,你將練習操作字典和集合,同時驗證一組醫療資料。" + ] + }, + "review-dictionaries-and-sets": { + "title": "字典與集合複習", + "intro": [ + "在接受字典與集合測驗前,你應該先複習相關內容。", + "打開此頁面複習字典、集合以及如何匯入模組的概念。" + ] + }, + "quiz-dictionaries-and-sets": { + "title": "字典與集合測驗", + "intro": [ + "透過此測驗檢驗你對 Python 中字典與集合的理解。" + ] + }, + "lab-user-configuration-manager": { + "title": "建置使用者設定管理器", + "intro": [ + "在此實驗中,你將練習在 Python 中操作字典。" + ] + }, + "lecture-understanding-error-handling": { + "title": "理解錯誤處理", + "intro": [ + "在這些課程中,你將學習 Python 的錯誤處理。你會了解不同類型的錯誤、良好的偵錯習慣、什麼是例外,以及如何處理例外。" + ] + }, + "lab-isbn-validator": { + "title": "除錯 ISBN 驗證器", + "intro": [ + "在此實驗中,你將從一個有錯誤的應用程式開始,並需要除錯修正錯誤直到它正常運作。" + ] + }, + "review-error-handling": { + "title": "錯誤處理複習", + "intro": [ + "在接受錯誤處理測驗前,你應該先複習相關內容。" + ] + }, + "quiz-error-handling": { + "title": "錯誤處理測驗", + "intro": [ + "透過此測驗檢驗你對 Python 中錯誤處理的理解。" + ] + }, + "lecture-classes-and-objects": { + "title": "類別與物件", + "intro": ["在這些課程中學習類別與物件。"] + }, + "workshop-musical-instrument-inventory": { + "title": "建置樂器庫存系統", + "intro": [ + "在這個工作坊中,你將透過建置簡單的樂器庫存系統,學習 Python 中的類別、物件和方法。" + ] + }, + "lab-planet-class": { + "title": "建置行星類別", + "intro": [ + "在此實驗中,你將創建一個代表行星的類別。" + ] + }, + "workshop-email-simulator": { + "title": "建置電子郵件模擬器", + "intro": [ + "在這個工作坊中,你將透過建置一個模擬不同使用者間發送、接收和管理電子郵件的模擬器,實作類別與物件。" + ] + }, + "review-classes-and-objects": { + "title": "類別與物件複習", + "intro": [ + "在接受類別與物件測驗前,你應該先複習相關內容。", + "打開此頁面複習類別如何運作、什麼是物件、方法、屬性、特殊方法等概念。" + ] + }, + "quiz-classes-and-objects": { + "title": "類別與物件測驗", + "intro": [ + "透過此測驗檢驗你對 Python 中類別與物件的理解。" + ] + }, + "lab-budget-app": { + "title": "建置預算應用程式", + "intro": [ + "在此實驗中,你將建置一個預算應用程式,並練習為該類別創建類別和方法。" + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "理解物件導向程式設計與封裝", + "intro": [ + "在這些課程中學習理解物件導向程式設計與封裝。" + ] + }, + "workshop-salary-tracker": { + "title": "建置薪資追蹤系統", + "intro": [ + "在這個工作坊中,你將透過建置員工薪資追蹤系統,練習封裝、屬性和其他物件導向程式設計概念。" + ] + }, + "lab-game-character-stats": { + "title": "建置遊戲角色屬性追蹤器", + "intro": [ + "在此實驗中,你將使用物件導向程式設計建置一個具有不同屬性的遊戲角色。" + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "理解繼承與多型", + "intro": [ + "在這些課程中學習理解繼承與多型。" + ] + }, + "workshop-media-catalogue": { + "title": "建置媒體目錄", + "intro": [ + "在這個工作坊中,你將使用物件導向程式設計原則創建一個媒體目錄應用程式。" + ] + }, + "lecture-understanding-abstraction": { + "title": "理解抽象性", + "intro": ["在這些課程中學習理解抽象性。"] + }, + "workshop-discount-calculator": { + "title": "建置折扣計算器", + "intro": [ + "在這個工作坊中,你將透過抽象基礎類別建置一個靈活的折扣定價計算器,允許多種折扣演算法可互換使用,而無需修改核心邏輯。" + ] + }, + "lab-player-interface": { + "title": "建置播放器介面", + "intro": [ + "在此實驗中,你將使用 abc 模組建置播放器介面。" + ] + }, + "review-object-oriented-programming": { + "title": "物件導向程式設計複習", + "intro": [ + "在接受物件導向程式設計測驗前,你應該先複習相關內容。" + ] + }, + "quiz-object-oriented-programming": { + "title": "物件導向程式設計測驗", + "intro": [ + "透過此測驗檢驗你對 Python 中物件導向程式設計的理解。" + ] + }, + "lab-polygon-area-calculator": { + "title": "建置多邊形面積計算器", + "intro": [ + "在此實驗中,你將使用物件導向程式設計計算不同多邊形(如正方形和長方形)的面積。" + ] + }, + "review-python": { + "title": "Python 程式設計基礎複習", + "intro": ["複習 Python 概念以準備即將到來的考試。"] + } + } + }, "algorithms-and-data-structure": { "title": "演算法與資料結構認證", "intro": [ diff --git a/client/chinese/intro.json b/client/chinese/intro.json index 7ae51a468b6..ca6161edf60 100644 --- a/client/chinese/intro.json +++ b/client/chinese/intro.json @@ -1221,7 +1221,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "理解命令行与 Bash 操作", "intro": [ - "在这些课程中学习命令行和 Bash 的使用。" + "在这些课程中了解命令行和使用 Bash。" ] }, "workshop-bash-boilerplate": { @@ -1517,6 +1517,12 @@ "在本工作坊中,你将通过构建一个生成格式化员工徽章并分析员工代码的工具,练习 Python 字串操作基础。" ] }, + "workshop-employee-profile-validator": { + "title": "创建员工资料验证器", + "intro": [ + "在本工作坊中,你将使用 Python 字串方法来验证和格式化员工资料中的数据。" + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "数字与数学运算", "intro": [ @@ -6478,6 +6484,12 @@ "在本工作坊中,你将通过创建一个生成格式化员工徽章并分析员工代码的工具来练习 Python 字串操作的基础。" ] }, + "workshop-employee-profile-validator": { + "title": "创建员工资料验证器", + "intro": [ + "在本工作坊中,你将使用 Python 字串方法来验证和格式化员工资料中的数据。" + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "数字和数学运算", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "创建一个 RPG 角色", "intro": [ - "在本实验中,你将通过创建一个 RPG 角色来练习基本的 Python。" + "在本实验中,你将通过创建一个 RPG 角色来练习基础 Python。" ] }, "review-python-basics": { @@ -7006,7 +7018,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "理解命令行和使用 Bash", "intro": [ - "在这些课程中学习命令行和 Bash 的使用。" + "在这些课程中了解命令行和使用 Bash。" ] }, "workshop-bash-boilerplate": { @@ -10407,6 +10419,359 @@ "english-only": "本节课程仅提供英文版本。目前我们只能翻译标题和介绍,课程内容暂未翻译。", "exam-english-only": "请注意,认证考试目前仅提供英文版本。其他课程则有部分语言版本。" }, + "python-programming-fundamentals": { + "title": "Python 编程基础", + "intro": [ + "本课程教授 Python 编程的基础知识。", + "完成必修项目并通过考试即可获得 Python 编程基础认证。" + ], + "chapters": { + "python-programming-fundamentals": "Python 编程基础" + }, + "modules": { + "python-basics": "Python 基础", + "python-installation": "安装 Python", + "python-loops-and-sequences": "循环和序列", + "python-dictionaries-and-sets": "字典和集合", + "lab-user-configuration-manager": "创建用户配置管理器", + "python-error-handling": "误差处理", + "python-classes-and-objects": "类和对象", + "lab-budget-app": "创建预算应用", + "python-object-oriented-programming": "面向对象编程(OOP)", + "lab-polygon-area-calculator": "创建多边形面积计算器", + "review-python-programming-fundamentals": "Python 复习" + }, + "blocks": { + "workshop-first-python-program": { + "title": "创建你的第一个 Python 程序", + "intro": [ + "在本工作坊中,你将创建你的第一个 Python 程序。" + ] + }, + "lecture-introduction-to-python": { + "title": "Python 入门", + "intro": [ + "在这些课程中,你将了解 Python 是什么以及其在行业中的常见用途。" + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "理解变量和数据类型", + "intro": [ + "在这些课程中,你将学习 Python 中的变量和数据类型。" + ] + }, + "workshop-report-card-printer": { + "title": "创建成绩单打印器", + "intro": [ + "在本工作坊中,你将通过创建和打印简单成绩单的数据来练习使用 Python 的原语数据类型。" + ] + }, + "lecture-introduction-to-python-strings": { + "title": "字串入门", + "intro": ["在这些课程中,你将学习 Python 中的字串。"] + }, + "workshop-employee-profile-generator": { + "title": "创建员工资料生成器", + "intro": [ + "在本工作坊中,你将通过创建一个生成格式化员工徽章并分析员工代码的工具,练习 Python 字串操作的基础知识。" + ] + }, + "workshop-employee-profile-validator": { + "title": "创建员工资料验证器", + "intro": [ + "在本工作坊中,你将使用 Python 字串方法来验证和格式化员工资料中的数据。" + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "数字和数学运算", + "intro": [ + "在这些课程中,你将学习 Python 中的数字和数学运算。" + ] + }, + "workshop-bill-splitter": { + "title": "创建账单分摊器", + "intro": [ + "在本工作坊中,你将创建一个账单分摊器,练习使用 Python 处理数字和数学运算。" + ] + }, + "lecture-booleans-and-conditionals": { + "title": "布尔值和条件式", + "intro": [ + "在这些课程中,你将学习 Python 中的布尔值和条件式。" + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "创建电影票预订计算器", + "intro": [ + "在本工作坊中,你将通过创建电影票预订计算器,练习使用 Python 的布尔值和条件语句。" + ] + }, + "lab-travel-weather-planner": { + "title": "创建旅行天气规划器", + "intro": [ + "在本实验中,你将使用条件式创建一个旅行天气规划器。" + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "理解函数和作用域", + "intro": [ + "在这些课程中,你将学习 Python 中的函数和作用域。" + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "创建厨房库存追踪器", + "intro": [ + "在本工作坊中,你将通过创建厨房库存追踪器,练习使用 Python 的函数和作用域。" + ] + }, + "lab-discount-calculator": { + "title": "创建应用折扣函数", + "intro": [ + "在本实验中,你将通过创建一个计算器来应用价格折扣,练习基础 Python。" + ] + }, + "workshop-caesar-cipher": { + "title": "创建凯撒密码", + "intro": [ + "在本工作坊中,你将使用基础 Python 概念如字串、条件式、函数等,创建一个凯撒密码。" + ] + }, + "lab-rpg-character": { + "title": "创建 RPG 角色", + "intro": [ + "在本实验中,你将通过创建一个 RPG 角色来练习基础 Python。" + ] + }, + "review-python-basics": { + "title": "Python 基础复习", + "intro": [ + "在进行 Python 基础测验前,你应该复习已学内容。", + "在此复习页面中,你将复习字串、函数、比较操作符等内容。" + ] + }, + "quiz-python-basics": { + "title": "Python 基础测验", + "intro": [ + "通过此测验测试你对 Python 基础的掌握。" + ] + }, + "lecture-python-installation": { + "title": "安装 Python 并在本地运行代码", + "intro": [ + "在这些课程中,你将学习如何在本地设备安装 Python 并运行代码。" + ] + }, + "review-python-installation": { + "title": "Python 安装复习", + "intro": [ + "在进行本地 Python 操作测验前,你应该复习课程中涵盖的概念。" + ] + }, + "quiz-python-installation": { + "title": "Python 安装测验", + "intro": [ + "通过此测验测试你对本地安装 Python 的掌握。" + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "使用循环和序列", + "intro": [ + "在这些课程中,学习如何使用循环和序列。" + ] + }, + "workshop-pin-extractor": { + "title": "创建密码提取器", + "intro": [ + "在本工作坊中,你将创建一个函数来提取隐藏在诗歌中的秘密密码。" + ] + }, + "lab-number-pattern-generator": { + "title": "创建数字模式生成器", + "intro": ["在本实验中,你将创建一个数字模式生成器。"] + }, + "review-loops-and-sequences": { + "title": "循环和序列复习", + "intro": [ + "在进行循环和序列测验前,你应该复习已学内容。", + "打开此页面复习循环、列表、元组及其常用方法的相关概念。" + ] + }, + "quiz-loops-and-sequences": { + "title": "循环和序列测验", + "intro": [ + "通过此测验测试你对 Python 中循环和序列的掌握。" + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "使用字典和集合", + "intro": [ + "在这些课程中,学习如何使用字典和集合。" + ] + }, + "lecture-working-with-modules": { + "title": "使用模块", + "intro": ["在这些课程中学习如何使用模块。"] + }, + "workshop-medical-data-validator": { + "title": "创建医疗数据验证器", + "intro": [ + "在本工作坊中,你将练习使用字典和集合,同时验证一组医疗数据。" + ] + }, + "review-dictionaries-and-sets": { + "title": "字典和集合复习", + "intro": [ + "在进行字典和集合测验之前,你应该复习相关内容。", + "打开此页面复习有关字典、集合以及如何导入模块的概念。" + ] + }, + "quiz-dictionaries-and-sets": { + "title": "字典和集合测验", + "intro": [ + "通过此测验测试你对 Python 中字典和集合的理解。" + ] + }, + "lab-user-configuration-manager": { + "title": "创建用户配置管理器", + "intro": [ + "在本实验中,你将练习使用 Python 中的字典。" + ] + }, + "lecture-understanding-error-handling": { + "title": "理解错误处理", + "intro": [ + "在这些课程中,你将学习 Python 中的错误处理。你将了解不同类型的错误、一些良好的调试实践、什么是异常以及如何处理它们。" + ] + }, + "lab-isbn-validator": { + "title": "调试 ISBN 验证器", + "intro": [ + "在本实验中,你将从一个有错误的应用开始,调试并修复错误,直到它正常工作。" + ] + }, + "review-error-handling": { + "title": "错误处理复习", + "intro": [ + "在进行错误处理测验之前,你应该复习相关内容。" + ] + }, + "quiz-error-handling": { + "title": "错误处理测验", + "intro": [ + "通过此测验测试你对 Python 中错误处理的理解。" + ] + }, + "lecture-classes-and-objects": { + "title": "类和对象", + "intro": ["在这些课程中学习类和对象。"] + }, + "workshop-musical-instrument-inventory": { + "title": "创建乐器库存", + "intro": [ + "在本工作坊中,你将通过创建一个简单的乐器库存,学习 Python 中的类、对象和方法。" + ] + }, + "lab-planet-class": { + "title": "创建行星类", + "intro": [ + "在本实验中,你将创建一个表现行星的类。" + ] + }, + "workshop-email-simulator": { + "title": "创建电子邮件模拟器", + "intro": [ + "在本工作坊中,你将通过构建一个模拟不同用户之间发送、接收和管理电子邮件的电子邮件模拟器,来实现类和对象。" + ] + }, + "review-classes-and-objects": { + "title": "类和对象复习", + "intro": [ + "在进行类和对象测验之前,你应该复习相关内容。", + "打开此页面复习类的工作原理、对象、方法、属性、特殊方法等概念。" + ] + }, + "quiz-classes-and-objects": { + "title": "类和对象测验", + "intro": [ + "通过此测验测试你对 Python 中类和对象的理解。" + ] + }, + "lab-budget-app": { + "title": "创建预算应用", + "intro": [ + "在本实验中,你将创建一个预算应用,并练习为该类创建类和方法。" + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "理解面向对象编程和封装", + "intro": [ + "在这些课程中学习理解面向对象编程和封装。" + ] + }, + "workshop-salary-tracker": { + "title": "创建薪资跟踪器", + "intro": [ + "在本工作坊中,你将通过创建一个员工薪资跟踪系统,练习封装、属性和其他面向对象编程概念。" + ] + }, + "lab-game-character-stats": { + "title": "创建游戏角色属性跟踪器", + "intro": [ + "在本实验中,你将使用面向对象编程创建一个具有不同属性的游戏角色。" + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "理解继承和多态", + "intro": [ + "在这些课程中学习理解继承和多态。" + ] + }, + "workshop-media-catalogue": { + "title": "创建媒体目录", + "intro": [ + "在本工作坊中,你将使用面向对象编程原则创建一个媒体目录应用。" + ] + }, + "lecture-understanding-abstraction": { + "title": "理解抽象", + "intro": ["在这些课程中学习理解抽象。"] + }, + "workshop-discount-calculator": { + "title": "创建折扣计算器", + "intro": [ + "在本工作坊中,你将通过抽象基类创建一个灵活的折扣定价计算器,允许多种折扣算法可互换应用而无需修改核心逻辑。" + ] + }, + "lab-player-interface": { + "title": "创建播放器接口", + "intro": [ + "在本实验中,你将使用 abc 模块创建一个播放器接口。" + ] + }, + "review-object-oriented-programming": { + "title": "面向对象编程复习", + "intro": [ + "在进行面向对象编程测验之前,你应该复习相关内容。" + ] + }, + "quiz-object-oriented-programming": { + "title": "面向对象编程测验", + "intro": [ + "通过此测验测试你对 Python 中面向对象编程的理解。" + ] + }, + "lab-polygon-area-calculator": { + "title": "创建多边形面积计算器", + "intro": [ + "在本实验中,你将使用面向对象编程计算不同多边形(如正方形和矩形)的面积。" + ] + }, + "review-python": { + "title": "Python 编程基础复习", + "intro": ["复习 Python 概念,为即将到来的考试做准备。"] + } + } + }, "algorithms-and-data-structure": { "title": "算法与数据结构认证", "intro": [ diff --git a/client/espanol/intro.json b/client/espanol/intro.json index c5b728f34ec..892fb23e55f 100644 --- a/client/espanol/intro.json +++ b/client/espanol/intro.json @@ -1517,6 +1517,12 @@ "En este taller, practicarás los fundamentos de manipulación de cadenas en Python construyendo una herramienta que genera credenciales formateadas para empleados y analiza códigos de empleados." ] }, + "workshop-employee-profile-validator": { + "title": "Construye un validador de perfil de empleado", + "intro": [ + "En este taller, usarás métodos de cadenas en Python para validar y formatear datos de un perfil de empleado." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Números y operaciones matemáticas", "intro": [ @@ -6478,6 +6484,12 @@ "En este taller, practicarás los fundamentos de manipulación de cadenas en Python construyendo una herramienta que genera credenciales formateadas para empleados y analiza códigos de empleados." ] }, + "workshop-employee-profile-validator": { + "title": "Construye un validador de perfil de empleado", + "intro": [ + "En este taller, usarás métodos de cadenas en Python para validar y formatear datos de un perfil de empleado." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Números y operaciones matemáticas", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "Crear un personaje de RPG", "intro": [ - "En este laboratorio practicarás Python básico creando un personaje de RPG." + "En este laboratorio practicarás Python básico construyendo un personaje de RPG." ] }, "review-python-basics": { @@ -10407,6 +10419,359 @@ "english-only": "Los cursos en esta sección solo están disponibles en inglés. Por ahora solo podemos traducir los títulos y las introducciones, no las lecciones.", "exam-english-only": "Ten en cuenta que el examen de certificación está disponible solo en inglés. El resto de los cursos están disponibles en algunos idiomas." }, + "python-programming-fundamentals": { + "title": "Fundamentos de programación en Python", + "intro": [ + "Este curso enseña los fundamentos de la programación en Python.", + "Completa los proyectos requeridos y aprueba el examen para obtener la certificación en fundamentos de programación en Python." + ], + "chapters": { + "python-programming-fundamentals": "Fundamentos de programación en Python" + }, + "modules": { + "python-basics": "Conceptos básicos de Python", + "python-installation": "Instalar Python", + "python-loops-and-sequences": "Ciclos y secuencias", + "python-dictionaries-and-sets": "Diccionarios y conjuntos", + "lab-user-configuration-manager": "Construye un gestor de configuración de usuario", + "python-error-handling": "Manejo de errores", + "python-classes-and-objects": "Clases y objetos", + "lab-budget-app": "Construye una app de presupuesto", + "python-object-oriented-programming": "Programación orientada a objetos (POO)", + "lab-polygon-area-calculator": "Construye un calculador de área de polígonos", + "review-python-programming-fundamentals": "Revisión de Python" + }, + "blocks": { + "workshop-first-python-program": { + "title": "Construye tu primer programa en Python", + "intro": [ + "Para este taller, construirás tu primer programa en Python." + ] + }, + "lecture-introduction-to-python": { + "title": "Introducción a Python", + "intro": [ + "En estas lecciones aprenderás qué es Python y sus usos comunes en la industria." + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "Entendiendo variables y tipos de datos", + "intro": [ + "En estas lecciones aprenderás sobre variables y tipos de datos en Python." + ] + }, + "workshop-report-card-printer": { + "title": "Construye una impresora de boletas de calificaciones", + "intro": [ + "En este taller practicarás con tipos de datos primitivos en Python creando e imprimiendo datos para una boleta de calificaciones simple." + ] + }, + "lecture-introduction-to-python-strings": { + "title": "Introducción a las cadenas", + "intro": ["En estas lecciones aprenderás sobre cadenas en Python."] + }, + "workshop-employee-profile-generator": { + "title": "Construye un generador de perfiles de empleado", + "intro": [ + "En este taller practicarás los fundamentos de manipulación de cadenas en Python construyendo una herramienta que genera credenciales formateadas y analiza códigos de empleados." + ] + }, + "workshop-employee-profile-validator": { + "title": "Construye un validador de perfil de empleado", + "intro": [ + "En este taller, usarás métodos de cadenas en Python para validar y formatear datos de un perfil de empleado." + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "Números y operaciones matemáticas", + "intro": [ + "En estas lecciones aprenderás sobre números y operaciones matemáticas en Python." + ] + }, + "workshop-bill-splitter": { + "title": "Construye un divisor de cuentas", + "intro": [ + "En este taller construirás un divisor de cuentas para practicar con números y operaciones matemáticas en Python." + ] + }, + "lecture-booleans-and-conditionals": { + "title": "Booleanos y condicionales", + "intro": [ + "En estas lecciones aprenderás sobre booleanos y condicionales en Python." + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "Construye un calculador de reservas de entradas de cine", + "intro": [ + "En este taller practicarás cómo usar booleanos y sentencias condicionales en Python construyendo un calculador de reservas de entradas de cine." + ] + }, + "lab-travel-weather-planner": { + "title": "Construye un planificador de clima para viajes", + "intro": [ + "En este laboratorio construirás un planificador de clima para viajes usando condicionales." + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "Entendiendo funciones y ámbito", + "intro": [ + "En estas lecciones aprenderás sobre funciones y ámbito en Python." + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "Construye un rastreador de inventario de cocina", + "intro": [ + "En este taller practicarás con funciones y ámbito en Python construyendo un rastreador de inventario de cocina." + ] + }, + "lab-discount-calculator": { + "title": "Construye una función para aplicar descuentos", + "intro": [ + "En este laboratorio practicarás Python básico construyendo un calculador para aplicar un descuento a un precio." + ] + }, + "workshop-caesar-cipher": { + "title": "Construye un cifrado César", + "intro": [ + "En este taller construirás un cifrado César usando conceptos básicos de Python como cadenas, condicionales, funciones y más." + ] + }, + "lab-rpg-character": { + "title": "Construye un personaje de RPG", + "intro": [ + "En este laboratorio practicarás Python básico construyendo un personaje de RPG." + ] + }, + "review-python-basics": { + "title": "Revisión de conceptos básicos de Python", + "intro": [ + "Antes de hacer el quiz sobre conceptos básicos de Python, deberías repasar lo que has aprendido.", + "En esta página de revisión repasarás el trabajo con cadenas, funciones, operadores de comparación y más." + ] + }, + "quiz-python-basics": { + "title": "Quiz de conceptos básicos de Python", + "intro": [ + "Pon a prueba lo que has aprendido sobre conceptos básicos de Python con este quiz." + ] + }, + "lecture-python-installation": { + "title": "Instalación de Python y ejecución de código localmente", + "intro": [ + "En estas lecciones aprenderás cómo instalar Python en tu dispositivo local y ejecutar código localmente." + ] + }, + "review-python-installation": { + "title": "Revisión de instalación de Python", + "intro": [ + "Antes de hacer el quiz sobre trabajar con Python localmente, deberías repasar los conceptos cubiertos en las lecciones." + ] + }, + "quiz-python-installation": { + "title": "Quiz de instalación de Python", + "intro": [ + "Pon a prueba lo que has aprendido sobre la instalación local de Python con este quiz." + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "Trabajo con ciclos y secuencias", + "intro": [ + "Aprende sobre el trabajo con ciclos y secuencias en estas lecciones." + ] + }, + "workshop-pin-extractor": { + "title": "Construye un extractor de pines", + "intro": [ + "En este taller construirás una función para extraer pines secretos ocultos en poemas." + ] + }, + "lab-number-pattern-generator": { + "title": "Construye un generador de patrones numéricos", + "intro": ["En este laboratorio construirás un generador de patrones numéricos."] + }, + "review-loops-and-sequences": { + "title": "Revisión de ciclos y secuencias", + "intro": [ + "Antes de hacer el quiz sobre ciclos y secuencias, deberías repasar lo que has aprendido sobre ellos.", + "Abre esta página para repasar conceptos sobre ciclos, listas, tuplas y algunos de sus métodos comunes." + ] + }, + "quiz-loops-and-sequences": { + "title": "Quiz de ciclos y secuencias", + "intro": [ + "Pon a prueba lo que has aprendido sobre ciclos y secuencias en Python con este quiz." + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "Trabajo con diccionarios y conjuntos", + "intro": [ + "Aprende sobre el trabajo con diccionarios y conjuntos en estas lecciones." + ] + }, + "lecture-working-with-modules": { + "title": "Trabajar con módulos", + "intro": ["Aprende a trabajar con módulos en estas lecciones."] + }, + "workshop-medical-data-validator": { + "title": "Construye un validador de datos médicos", + "intro": [ + "En este taller, practicarás con diccionarios y conjuntos mientras validas una colección de datos médicos." + ] + }, + "review-dictionaries-and-sets": { + "title": "Revisión de diccionarios y conjuntos", + "intro": [ + "Antes de hacer el quiz sobre diccionarios y conjuntos, deberías repasar lo que has aprendido sobre ellos.", + "Abre esta página para repasar conceptos sobre diccionarios, conjuntos y cómo importar módulos." + ] + }, + "quiz-dictionaries-and-sets": { + "title": "Quiz de diccionarios y conjuntos", + "intro": [ + "Pon a prueba lo que has aprendido sobre diccionarios y conjuntos en Python con este quiz." + ] + }, + "lab-user-configuration-manager": { + "title": "Construye un gestor de configuración de usuario", + "intro": [ + "En este laboratorio, practicarás con diccionarios en Python." + ] + }, + "lecture-understanding-error-handling": { + "title": "Comprender el manejo de errores", + "intro": [ + "En estas lecciones aprenderás sobre el manejo de errores en Python. Conocerás los diferentes tipos de errores, buenas prácticas de depuración, qué son las excepciones y cómo manejarlas." + ] + }, + "lab-isbn-validator": { + "title": "Depura un validador de ISBN", + "intro": [ + "En este laboratorio comenzarás con una app con bugs, y deberás depurar y corregir los bugs hasta que funcione correctamente." + ] + }, + "review-error-handling": { + "title": "Revisión del manejo de errores", + "intro": [ + "Antes de hacer el quiz sobre manejo de errores, deberías repasar lo que has aprendido sobre ello." + ] + }, + "quiz-error-handling": { + "title": "Quiz de manejo de errores", + "intro": [ + "Pon a prueba lo que has aprendido sobre manejo de errores en Python con este quiz." + ] + }, + "lecture-classes-and-objects": { + "title": "Clases y objetos", + "intro": ["Aprende sobre clases y objetos en estas lecciones."] + }, + "workshop-musical-instrument-inventory": { + "title": "Construye un inventario de instrumentos musicales", + "intro": [ + "En este taller aprenderás sobre clases, objetos y métodos en Python construyendo un inventario simple de instrumentos musicales." + ] + }, + "lab-planet-class": { + "title": "Construye una clase planeta", + "intro": [ + "En este laboratorio crearás una clase que representa un planeta." + ] + }, + "workshop-email-simulator": { + "title": "Construye un simulador de correo electrónico", + "intro": [ + "En este taller implementarás clases y objetos construyendo un simulador de correo electrónico que simula enviar, recibir y gestionar correos entre diferentes usuarios." + ] + }, + "review-classes-and-objects": { + "title": "Revisión de clases y objetos", + "intro": [ + "Antes de hacer el quiz sobre clases y objetos, deberías repasar lo que has aprendido sobre ellos.", + "Abre esta página para repasar conceptos como cómo funcionan las clases, qué son los objetos, métodos, atributos, métodos especiales y más." + ] + }, + "quiz-classes-and-objects": { + "title": "Quiz de clases y objetos", + "intro": [ + "Pon a prueba lo que has aprendido sobre clases y objetos en Python con este quiz." + ] + }, + "lab-budget-app": { + "title": "Construye una app de presupuesto", + "intro": [ + "En este laboratorio construirás una app de presupuesto y practicarás creando una clase y métodos para esa clase." + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "Comprender la programación orientada a objetos y la encapsulación", + "intro": [ + "Aprende a comprender la programación orientada a objetos y la encapsulación en estas lecciones." + ] + }, + "workshop-salary-tracker": { + "title": "Construye un rastreador de salarios", + "intro": [ + "En este taller practicarás encapsulación, propiedades y otros conceptos de programación orientada a objetos construyendo un sistema para rastrear salarios de empleados." + ] + }, + "lab-game-character-stats": { + "title": "Construye un rastreador de estadísticas de personajes de juego", + "intro": [ + "En este laboratorio construirás un personaje de juego con diferentes estadísticas usando programación orientada a objetos." + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "Comprender la herencia y el polimorfismo", + "intro": [ + "Aprende a comprender la herencia y el polimorfismo en estas lecciones." + ] + }, + "workshop-media-catalogue": { + "title": "Construye un catálogo de medios", + "intro": [ + "En este taller crearás una aplicación de catálogo de medios usando principios de programación orientada a objetos." + ] + }, + "lecture-understanding-abstraction": { + "title": "Comprender la abstracción", + "intro": ["Aprende a comprender la abstracción en estas lecciones."] + }, + "workshop-discount-calculator": { + "title": "Construye una calculadora de descuentos", + "intro": [ + "En este taller construirás una calculadora flexible de precios con descuento mediante clases base abstractas, permitiendo aplicar múltiples algoritmos de descuento intercambiables sin modificar la lógica central." + ] + }, + "lab-player-interface": { + "title": "Construye una interfaz de reproductor", + "intro": [ + "En este laboratorio usarás el módulo abc para construir una interfaz de reproductor." + ] + }, + "review-object-oriented-programming": { + "title": "Revisión de programación orientada a objetos", + "intro": [ + "Antes de hacer el quiz sobre programación orientada a objetos, deberías repasar lo que has aprendido sobre ello." + ] + }, + "quiz-object-oriented-programming": { + "title": "Quiz de programación orientada a objetos", + "intro": [ + "Pon a prueba lo que has aprendido sobre programación orientada a objetos en Python con este quiz." + ] + }, + "lab-polygon-area-calculator": { + "title": "Construye una calculadora de área de polígonos", + "intro": [ + "En este laboratorio usarás programación orientada a objetos para calcular las áreas de diferentes polígonos como cuadrados y rectángulos." + ] + }, + "review-python": { + "title": "Revisión de fundamentos de programación en Python", + "intro": ["Repasa conceptos de Python para prepararte para el próximo examen."] + } + } + }, "algorithms-and-data-structure": { "title": "Certificación en algoritmos y estructura de datos", "intro": [ diff --git a/client/german/intro.json b/client/german/intro.json index 75293ce1429..a8f19bb761a 100644 --- a/client/german/intro.json +++ b/client/german/intro.json @@ -1517,6 +1517,12 @@ "In diesem Workshop üben Sie die Grundlagen der String-Manipulation in Python, indem Sie ein Tool erstellen, das formatierte Mitarbeiterausweise generiert und Mitarbeitercodes analysiert." ] }, + "workshop-employee-profile-validator": { + "title": "Erstellen Sie einen Validator für Mitarbeiterprofile", + "intro": [ + "In diesem Workshop verwenden Sie Python-String-Methoden, um Daten aus einem Mitarbeiterprofil zu validieren und zu formatieren." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Zahlen und mathematische Operationen", "intro": [ @@ -6478,6 +6484,12 @@ "In diesem Workshop üben Sie die Grundlagen der String-Manipulation in Python, indem Sie ein Tool erstellen, das formatierte Mitarbeiterausweise generiert und Mitarbeitercodes analysiert." ] }, + "workshop-employee-profile-validator": { + "title": "Erstellen Sie einen Validator für Mitarbeiterprofile", + "intro": [ + "In diesem Workshop verwenden Sie Python-String-Methoden, um Daten aus einem Mitarbeiterprofil zu validieren und zu formatieren." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Zahlen und mathematische Operationen", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "Erstellen Sie einen RPG-Charakter", "intro": [ - "In diesem Workshop üben Sie grundlegendes Python, indem Sie einen RPG-Charakter erstellen." + "In diesem Labor üben Sie grundlegendes Python, indem Sie einen RPG-Charakter erstellen." ] }, "review-python-basics": { @@ -7006,7 +7018,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "Verstehen der Befehlszeile und Arbeiten mit Bash", "intro": [ - "Lernen Sie in diesen Lektionen die Befehlszeile und das Arbeiten mit Bash kennen." + "Lernen Sie in diesen Lektionen die Befehlszeile und die Arbeit mit Bash kennen." ] }, "workshop-bash-boilerplate": { @@ -10407,6 +10419,359 @@ "english-only": "Die Kurse in diesem Abschnitt sind nur auf Englisch verfügbar. Momentan können wir nur die Titel und Einleitungen übersetzen, nicht jedoch die Lektionen selbst.", "exam-english-only": "Bitte beachten Sie, dass die Zertifizierungsprüfung derzeit nur auf Englisch verfügbar ist. Die übrigen Kurse sind in einigen Sprachen verfügbar." }, + "python-programming-fundamentals": { + "title": "Grundlagen der Python-Programmierung", + "intro": [ + "Dieser Kurs vermittelt die Grundlagen der Python-Programmierung.", + "Schließen Sie die erforderlichen Projekte ab und bestehen Sie die Prüfung, um die Zertifizierung für Grundlagen der Python-Programmierung zu erhalten." + ], + "chapters": { + "python-programming-fundamentals": "Grundlagen der Python-Programmierung" + }, + "modules": { + "python-basics": "Python-Grundlagen", + "python-installation": "Python installieren", + "python-loops-and-sequences": "Schleifen und Folgen", + "python-dictionaries-and-sets": "Wörterbücher und Sets", + "lab-user-configuration-manager": "Erstellen Sie einen Benutzerkonfigurationsmanager", + "python-error-handling": "Fehlerbehandlung", + "python-classes-and-objects": "Klassen und Objekte", + "lab-budget-app": "Erstellen Sie eine Budget-App", + "python-object-oriented-programming": "Objektorientierte Programmierung (OOP)", + "lab-polygon-area-calculator": "Erstellen Sie einen Polygon-Flächenrechner", + "review-python-programming-fundamentals": "Python-Überblick" + }, + "blocks": { + "workshop-first-python-program": { + "title": "Erstellen Sie Ihr erstes Python-Programm", + "intro": [ + "Für diesen Workshop erstellen Sie Ihr erstes Programm in Python." + ] + }, + "lecture-introduction-to-python": { + "title": "Einführung in Python", + "intro": [ + "In diesen Lektionen lernen Sie, was Python ist und wie es in der Branche verwendet wird." + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "Variablen und Datentypen verstehen", + "intro": [ + "In diesen Lektionen lernen Sie Variablen und Datentypen in Python kennen." + ] + }, + "workshop-report-card-printer": { + "title": "Erstellen Sie einen Zeugnisdrucker", + "intro": [ + "In diesem Workshop üben Sie den Umgang mit primitiven Datentypen in Python, indem Sie Daten für ein einfaches Zeugnis erstellen und ausgeben." + ] + }, + "lecture-introduction-to-python-strings": { + "title": "Einführung in Strings", + "intro": ["In diesen Lektionen lernen Sie Strings in Python kennen."] + }, + "workshop-employee-profile-generator": { + "title": "Erstellen Sie einen Generator für Mitarbeiterprofile", + "intro": [ + "In diesem Workshop üben Sie die Grundlagen der String-Manipulation in Python, indem Sie ein Tool erstellen, das formatierte Mitarbeiterausweise generiert und Mitarbeitercodes analysiert." + ] + }, + "workshop-employee-profile-validator": { + "title": "Erstellen Sie einen Validator für Mitarbeiterprofile", + "intro": [ + "In diesem Workshop verwenden Sie Python-String-Methoden, um Daten aus einem Mitarbeiterprofil zu validieren und zu formatieren." + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "Zahlen und mathematische Operationen", + "intro": [ + "In diesen Lektionen lernen Sie Zahlen und mathematische Operationen in Python kennen." + ] + }, + "workshop-bill-splitter": { + "title": "Erstellen Sie einen Rechnungsteiler", + "intro": [ + "In diesem Workshop erstellen Sie einen Rechnungsteiler, um den Umgang mit Zahlen und mathematischen Operationen in Python zu üben." + ] + }, + "lecture-booleans-and-conditionals": { + "title": "Booleans und Bedingungen", + "intro": [ + "In diesen Lektionen lernen Sie Booleans und Bedingungen in Python kennen." + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "Erstellen Sie einen Kinokartenrechner", + "intro": [ + "In diesem Workshop üben Sie die Verwendung von Booleans und bedingten Anweisungen in Python, indem Sie einen Kinokartenrechner erstellen." + ] + }, + "lab-travel-weather-planner": { + "title": "Erstellen Sie einen Reise-Wetterplaner", + "intro": [ + "In diesem Labor erstellen Sie einen Reise-Wetterplaner mit Bedingungen." + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "Funktionen und Gültigkeitsbereich verstehen", + "intro": [ + "In diesen Lektionen lernen Sie Funktionen und Gültigkeitsbereich in Python kennen." + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "Erstellen Sie einen Kücheninventar-Tracker", + "intro": [ + "In diesem Workshop üben Sie den Umgang mit Funktionen und Gültigkeitsbereich in Python, indem Sie einen Kücheninventar-Tracker erstellen." + ] + }, + "lab-discount-calculator": { + "title": "Erstellen Sie eine Rabatt-Funktion", + "intro": [ + "In diesem Labor üben Sie grundlegendes Python, indem Sie einen Rechner erstellen, der einen Rabatt auf einen Preis anwendet." + ] + }, + "workshop-caesar-cipher": { + "title": "Erstellen Sie eine Caesar-Verschlüsselung", + "intro": [ + "In diesem Workshop erstellen Sie eine Caesar-Verschlüsselung mit grundlegenden Python-Konzepten wie Strings, Bedingungen, Funktionen und mehr." + ] + }, + "lab-rpg-character": { + "title": "Erstellen Sie einen RPG-Charakter", + "intro": [ + "In diesem Labor üben Sie grundlegendes Python, indem Sie einen RPG-Charakter erstellen." + ] + }, + "review-python-basics": { + "title": "Überblick über Python-Grundlagen", + "intro": [ + "Bevor Sie im Quiz zu Python-Grundlagen geprüft werden, sollten Sie das Gelernte noch einmal überprüfen.", + "Auf dieser Übersichtsseite wiederholen Sie den Umgang mit Strings, Funktionen, Vergleichsoperatoren und mehr." + ] + }, + "quiz-python-basics": { + "title": "Quiz zu Python-Grundlagen", + "intro": [ + "Testen Sie Ihr Wissen zu Python-Grundlagen mit diesem Quiz." + ] + }, + "lecture-python-installation": { + "title": "Python installieren und Code lokal ausführen", + "intro": [ + "In diesen Lektionen lernen Sie, wie Sie Python auf Ihrem lokalen Gerät installieren und Code lokal ausführen." + ] + }, + "review-python-installation": { + "title": "Überblick zur Python-Installation", + "intro": [ + "Bevor Sie im Quiz zum lokalen Arbeiten mit Python geprüft werden, sollten Sie die in den Lektionen behandelten Konzepte wiederholen." + ] + }, + "quiz-python-installation": { + "title": "Quiz zur Python-Installation", + "intro": [ + "Testen Sie Ihr Wissen zur lokalen Python-Installation mit diesem Quiz." + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "Arbeiten mit Schleifen und Folgen", + "intro": [ + "Lernen Sie in diesen Lektionen den Umgang mit Schleifen und Folgen." + ] + }, + "workshop-pin-extractor": { + "title": "Erstellen Sie einen Pin-Extraktor", + "intro": [ + "In diesem Workshop erstellen Sie eine Funktion, um geheime Pins zu extrahieren, die in Gedichten versteckt sind." + ] + }, + "lab-number-pattern-generator": { + "title": "Erstellen Sie einen Zahlenmuster-Generator", + "intro": ["In diesem Labor erstellen Sie einen Zahlenmuster-Generator."] + }, + "review-loops-and-sequences": { + "title": "Überblick zu Schleifen und Folgen", + "intro": [ + "Bevor Sie im Quiz zu Schleifen und Folgen geprüft werden, sollten Sie das Gelernte noch einmal überprüfen.", + "Öffnen Sie diese Seite, um Konzepte zu Schleifen, Listen, Tuples und einigen ihrer gängigen Methoden zu wiederholen." + ] + }, + "quiz-loops-and-sequences": { + "title": "Quiz zu Schleifen und Folgen", + "intro": [ + "Testen Sie Ihr Wissen zu Schleifen und Folgen in Python mit diesem Quiz." + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "Arbeiten mit Wörterbüchern und Sets", + "intro": [ + "Lernen Sie in diesen Lektionen den Umgang mit Wörterbüchern und Sets." + ] + }, + "lecture-working-with-modules": { + "title": "Arbeiten mit Modulen", + "intro": ["Lernen Sie in diesen Lektionen, wie Sie mit Modulen arbeiten."] + }, + "workshop-medical-data-validator": { + "title": "Erstellen Sie einen Validator für medizinische Daten", + "intro": [ + "In diesem Workshop üben Sie den Umgang mit Dictionaries und Sets, während Sie eine Sammlung medizinischer Daten validieren." + ] + }, + "review-dictionaries-and-sets": { + "title": "Überblick über Dictionaries und Sets", + "intro": [ + "Bevor Sie im Quiz zu Dictionaries und Sets geprüft werden, sollten Sie das Gelernte noch einmal überprüfen.", + "Öffnen Sie diese Seite, um Konzepte zu Dictionaries, Sets und dem Importieren von Modulen zu wiederholen." + ] + }, + "quiz-dictionaries-and-sets": { + "title": "Quiz zu Dictionaries und Sets", + "intro": [ + "Testen Sie Ihr Wissen über Dictionaries und Sets in Python mit diesem Quiz." + ] + }, + "lab-user-configuration-manager": { + "title": "Erstellen Sie einen Benutzerkonfigurationsmanager", + "intro": [ + "In diesem Labor üben Sie den Umgang mit Dictionaries in Python." + ] + }, + "lecture-understanding-error-handling": { + "title": "Fehlerbehandlung verstehen", + "intro": [ + "In diesen Lektionen lernen Sie die Fehlerbehandlung in Python kennen. Sie erfahren etwas über verschiedene Fehlertypen, gute Debugging-Praktiken, was Ausnahmen sind und wie man sie behandelt." + ] + }, + "lab-isbn-validator": { + "title": "Debuggen Sie einen ISBN-Validator", + "intro": [ + "In diesem Labor starten Sie mit einer fehlerhaften Anwendung und müssen die Bugs debuggen und beheben, bis sie richtig funktioniert." + ] + }, + "review-error-handling": { + "title": "Überblick zur Fehlerbehandlung", + "intro": [ + "Bevor Sie im Quiz zur Fehlerbehandlung geprüft werden, sollten Sie das Gelernte noch einmal überprüfen." + ] + }, + "quiz-error-handling": { + "title": "Quiz zur Fehlerbehandlung", + "intro": [ + "Testen Sie Ihr Wissen über Fehlerbehandlung in Python mit diesem Quiz." + ] + }, + "lecture-classes-and-objects": { + "title": "Klassen und Objekte", + "intro": ["Lernen Sie in diesen Lektionen Klassen und Objekte kennen."] + }, + "workshop-musical-instrument-inventory": { + "title": "Erstellen Sie ein Inventar für Musikinstrumente", + "intro": [ + "In diesem Workshop lernen Sie Klassen, Objekte und Methoden in Python kennen, indem Sie ein einfaches Inventar für Musikinstrumente erstellen." + ] + }, + "lab-planet-class": { + "title": "Erstellen Sie eine Planetenklasse", + "intro": [ + "In diesem Labor erstellen Sie eine Klasse, die einen Planeten darstellt." + ] + }, + "workshop-email-simulator": { + "title": "Erstellen Sie einen E-Mail-Simulator", + "intro": [ + "In diesem Workshop implementieren Sie Klassen und Objekte, indem Sie einen E-Mail-Simulator bauen, der das Senden, Empfangen und Verwalten von E-Mails zwischen verschiedenen Nutzenden simuliert." + ] + }, + "review-classes-and-objects": { + "title": "Überblick zu Klassen und Objekten", + "intro": [ + "Bevor Sie im Quiz zu Klassen und Objekten geprüft werden, sollten Sie das Gelernte noch einmal überprüfen.", + "Öffnen Sie diese Seite, um Konzepte wie Funktionsweise von Klassen, Objekte, Methoden, Attribute, spezielle Methoden und mehr zu wiederholen." + ] + }, + "quiz-classes-and-objects": { + "title": "Quiz zu Klassen und Objekten", + "intro": [ + "Testen Sie Ihr Wissen über Klassen und Objekte in Python mit diesem Quiz." + ] + }, + "lab-budget-app": { + "title": "Erstellen Sie eine Budget-App", + "intro": [ + "In diesem Labor erstellen Sie eine Budget-App und üben das Erstellen einer Klasse und von Methoden für diese Klasse." + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "Objektorientierte Programmierung und Kapselung verstehen", + "intro": [ + "Lernen Sie in diesen Lektionen die objektorientierte Programmierung und Kapselung kennen." + ] + }, + "workshop-salary-tracker": { + "title": "Erstellen Sie einen Gehalts-Tracker", + "intro": [ + "In diesem Workshop üben Sie Kapselung, Eigenschaften und andere Konzepte der OOP, indem Sie ein Gehaltsverfolgungssystem für Mitarbeitende erstellen." + ] + }, + "lab-game-character-stats": { + "title": "Erstellen Sie einen Tracker für Spielfigur-Statistiken", + "intro": [ + "In diesem Labor erstellen Sie eine Spielfigur mit verschiedenen Statistiken unter Verwendung objektorientierter Programmierung." + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "Vererbung und Polymorphismus verstehen", + "intro": [ + "Lernen Sie in diesen Lektionen Vererbung und Polymorphismus kennen." + ] + }, + "workshop-media-catalogue": { + "title": "Erstellen Sie einen Medienkatalog", + "intro": [ + "In diesem Workshop erstellen Sie eine Medienkatalog-Anwendung unter Verwendung objektorientierter Programmiergrundsätze." + ] + }, + "lecture-understanding-abstraction": { + "title": "Abstraktion verstehen", + "intro": ["Lernen Sie in diesen Lektionen die Abstraktion kennen."] + }, + "workshop-discount-calculator": { + "title": "Erstellen Sie einen Rabattrechner", + "intro": [ + "In diesem Workshop erstellen Sie einen flexiblen Rabattpreisrechner durch abstrakte Basisklassen, der es ermöglicht, mehrere Rabattalgorithmen austauschbar anzuwenden, ohne die Kernlogik zu verändern." + ] + }, + "lab-player-interface": { + "title": "Erstellen Sie ein Spieler-Interface", + "intro": [ + "In diesem Labor verwenden Sie das abc-Modul, um ein Spieler-Interface zu erstellen." + ] + }, + "review-object-oriented-programming": { + "title": "Überblick zur objektorientierten Programmierung", + "intro": [ + "Bevor Sie im Quiz zur objektorientierten Programmierung geprüft werden, sollten Sie das Gelernte noch einmal überprüfen." + ] + }, + "quiz-object-oriented-programming": { + "title": "Quiz zur objektorientierten Programmierung", + "intro": [ + "Testen Sie Ihr Wissen über objektorientierte Programmierung in Python mit diesem Quiz." + ] + }, + "lab-polygon-area-calculator": { + "title": "Erstellen Sie einen Flächenrechner für Polygone", + "intro": [ + "In diesem Labor verwenden Sie objektorientierte Programmierung, um die Flächen verschiedener Polygone wie Quadrate und Rechtecke zu berechnen." + ] + }, + "review-python": { + "title": "Überblick zu den Grundlagen der Python-Programmierung", + "intro": ["Wiederholen Sie Python-Konzepte, um sich auf die bevorstehende Prüfung vorzubereiten."] + } + } + }, "algorithms-and-data-structure": { "title": "Zertifizierung für Algorithmen und Datenstruktur", "intro": [ diff --git a/client/italian/intro.json b/client/italian/intro.json index 05fedd11cb2..3b63341b551 100644 --- a/client/italian/intro.json +++ b/client/italian/intro.json @@ -1221,7 +1221,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "Comprendere la riga di comando e lavorare con Bash", "intro": [ - "Impara a conoscere la riga di comando e a lavorare con Bash in queste lezioni." + "Impara la riga di comando e come lavorare con Bash in queste lezioni." ] }, "workshop-bash-boilerplate": { @@ -1517,6 +1517,12 @@ "In questo laboratorio metterai in pratica le basi della manipolazione delle stringhe in Python costruendo uno strumento che genera badge dipendenti formattati e analizza codici dipendenti." ] }, + "workshop-employee-profile-validator": { + "title": "Crea un validatore di profili dipendenti", + "intro": [ + "In questo workshop userai i metodi delle stringhe Python per convalidare e formattare i dati di un profilo dipendente." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Numeri e operazioni matematiche", "intro": [ @@ -6478,6 +6484,12 @@ "In questo workshop, praticherai le basi della manipolazione delle stringhe in Python costruendo uno strumento che genera badge formattati per dipendenti e analizza codici dipendenti." ] }, + "workshop-employee-profile-validator": { + "title": "Crea un validatore di profili dipendenti", + "intro": [ + "In questo workshop userai i metodi delle stringhe Python per convalidare e formattare i dati di un profilo dipendente." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Numeri e operazioni matematiche", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "Crea un personaggio RPG", "intro": [ - "In questo laboratorio eserciterai le basi di Python creando un personaggio RPG." + "In questo laboratorio praticherai le basi di Python creando un personaggio RPG." ] }, "review-python-basics": { @@ -10407,6 +10419,359 @@ "english-only": "I corsi in questa sezione sono disponibili solo in inglese. Al momento possiamo tradurre solo titoli e introduzioni, non le lezioni.", "exam-english-only": "Nota che l'esame di certificazione è attualmente disponibile solo in inglese. Il resto dei corsi è disponibile in alcune lingue." }, + "python-programming-fundamentals": { + "title": "Fondamenti di programmazione Python", + "intro": [ + "Questo corso insegna i fondamenti della programmazione Python.", + "Completa i progetti richiesti e supera l'esame per ottenere la certificazione Fondamenti di programmazione Python." + ], + "chapters": { + "python-programming-fundamentals": "Fondamenti di programmazione Python" + }, + "modules": { + "python-basics": "Basi di Python", + "python-installation": "Installa Python", + "python-loops-and-sequences": "Loop e sequenze", + "python-dictionaries-and-sets": "Dizionari e insiemi", + "lab-user-configuration-manager": "Crea un gestore di configurazione utente", + "python-error-handling": "Gestione degli errori", + "python-classes-and-objects": "Classi e oggetti", + "lab-budget-app": "Crea un'app per il budget", + "python-object-oriented-programming": "Programmazione orientata agli oggetti (OOP)", + "lab-polygon-area-calculator": "Crea un calcolatore dell'area di un poligono", + "review-python-programming-fundamentals": "Revisione di Python" + }, + "blocks": { + "workshop-first-python-program": { + "title": "Crea il tuo primo programma Python", + "intro": [ + "Per questo workshop costruirai il tuo primo programma in Python." + ] + }, + "lecture-introduction-to-python": { + "title": "Introduzione a Python", + "intro": [ + "In queste lezioni imparerai cos'è Python e i suoi usi comuni nell'industria." + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "Comprendere variabili e tipi di dati", + "intro": [ + "In queste lezioni imparerai variabili e tipi di dati in Python." + ] + }, + "workshop-report-card-printer": { + "title": "Crea una stampante di pagelle", + "intro": [ + "In questo workshop praticherai l'uso dei tipi di dati primitivi in Python creando e stampando dati per una semplice pagella." + ] + }, + "lecture-introduction-to-python-strings": { + "title": "Introduzione alle stringhe", + "intro": ["In queste lezioni imparerai le stringhe in Python."] + }, + "workshop-employee-profile-generator": { + "title": "Crea un generatore di profili dipendenti", + "intro": [ + "In questo workshop praticherai i fondamenti della manipolazione delle stringhe in Python costruendo uno strumento che genera badge formattati per dipendenti e analizza codici dipendenti." + ] + }, + "workshop-employee-profile-validator": { + "title": "Crea un validatore di profili dipendenti", + "intro": [ + "In questo workshop userai i metodi delle stringhe Python per convalidare e formattare i dati di un profilo dipendente." + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "Numeri e operazioni matematiche", + "intro": [ + "In queste lezioni imparerai numeri e operazioni matematiche in Python." + ] + }, + "workshop-bill-splitter": { + "title": "Crea un divisore del conto", + "intro": [ + "In questo workshop costruirai un divisore del conto per praticare l'uso di numeri e operazioni matematiche in Python." + ] + }, + "lecture-booleans-and-conditionals": { + "title": "Booleani e condizionali", + "intro": [ + "In queste lezioni imparerai booleani e condizionali in Python." + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "Crea un calcolatore per prenotazione biglietti cinema", + "intro": [ + "In questo workshop praticherai l'uso di booleani e istruzioni condizionali in Python costruendo un calcolatore per prenotazione biglietti cinema." + ] + }, + "lab-travel-weather-planner": { + "title": "Crea un pianificatore meteo per viaggi", + "intro": [ + "In questo laboratorio costruirai un pianificatore meteo per viaggi usando condizionali." + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "Comprendere funzioni e ambito", + "intro": [ + "In queste lezioni imparerai funzioni e ambito in Python." + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "Crea un tracciatore di inventario cucina", + "intro": [ + "In questo workshop praticherai l'uso di funzioni e ambito in Python costruendo un tracciatore di inventario cucina." + ] + }, + "lab-discount-calculator": { + "title": "Crea una funzione per applicare sconti", + "intro": [ + "In questo laboratorio praticherai le basi di Python costruendo un calcolatore per applicare uno sconto a un prezzo." + ] + }, + "workshop-caesar-cipher": { + "title": "Crea un cifrario di Cesare", + "intro": [ + "In questo workshop costruirai un cifrario di Cesare usando concetti base di Python come stringhe, condizionali, funzioni e altro." + ] + }, + "lab-rpg-character": { + "title": "Crea un personaggio RPG", + "intro": [ + "In questo laboratorio praticherai le basi di Python creando un personaggio RPG." + ] + }, + "review-python-basics": { + "title": "Revisione delle basi di Python", + "intro": [ + "Prima di affrontare il quiz sulle basi di Python, dovresti rivedere ciò che hai imparato.", + "In questa pagina di revisione rivedrai l'uso di stringhe, funzioni, operatori di confronto e altro." + ] + }, + "quiz-python-basics": { + "title": "Quiz sulle basi di Python", + "intro": [ + "Metti alla prova ciò che hai imparato sulle basi di Python con questo quiz." + ] + }, + "lecture-python-installation": { + "title": "Installare Python ed eseguire codice localmente", + "intro": [ + "In queste lezioni imparerai come installare Python sul tuo dispositivo locale ed eseguire codice localmente." + ] + }, + "review-python-installation": { + "title": "Revisione dell'installazione di Python", + "intro": [ + "Prima di affrontare il quiz sull'uso di Python localmente, dovresti rivedere i concetti trattati nelle lezioni." + ] + }, + "quiz-python-installation": { + "title": "Quiz sull'installazione di Python", + "intro": [ + "Metti alla prova ciò che hai imparato sull'installazione locale di Python con questo quiz." + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "Lavorare con loop e sequenze", + "intro": [ + "Impara a lavorare con loop e sequenze in queste lezioni." + ] + }, + "workshop-pin-extractor": { + "title": "Crea un estrattore di pin", + "intro": [ + "In questo workshop costruirai una funzione per estrarre pin segreti nascosti in poesie." + ] + }, + "lab-number-pattern-generator": { + "title": "Crea un generatore di pattern numerici", + "intro": ["In questo laboratorio costruirai un generatore di pattern numerici."] + }, + "review-loops-and-sequences": { + "title": "Revisione di loop e sequenze", + "intro": [ + "Prima di affrontare il quiz su loop e sequenze, dovresti rivedere ciò che hai imparato su di essi.", + "Apri questa pagina per rivedere i concetti su loop, liste, tuple e alcuni dei loro metodi comuni." + ] + }, + "quiz-loops-and-sequences": { + "title": "Quiz su loop e sequenze", + "intro": [ + "Metti alla prova ciò che hai imparato su loop e sequenze in Python con questo quiz." + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "Lavorare con dizionari e insiemi", + "intro": [ + "Impara a lavorare con dizionari e insiemi in queste lezioni." + ] + }, + "lecture-working-with-modules": { + "title": "Lavorare con i moduli", + "intro": ["Impara a lavorare con i moduli in queste lezioni."] + }, + "workshop-medical-data-validator": { + "title": "Crea un validatore di dati medici", + "intro": [ + "In questo workshop, esercitati a usare dizionari e insiemi mentre convalidi una raccolta di dati medici." + ] + }, + "review-dictionaries-and-sets": { + "title": "Revisione di dizionari e insiemi", + "intro": [ + "Prima di affrontare il quiz su dizionari e insiemi, rivedi ciò che hai imparato su di essi.", + "Apri questa pagina per rivedere i concetti su dizionari, insiemi e come importare moduli." + ] + }, + "quiz-dictionaries-and-sets": { + "title": "Quiz su dizionari e insiemi", + "intro": [ + "Metti alla prova ciò che hai imparato su dizionari e insiemi in Python con questo quiz." + ] + }, + "lab-user-configuration-manager": { + "title": "Crea un gestore di configurazione utente", + "intro": [ + "In questo laboratorio, esercitati a usare dizionari in Python." + ] + }, + "lecture-understanding-error-handling": { + "title": "Comprendere la gestione degli errori", + "intro": [ + "In queste lezioni, imparerai la gestione degli errori in Python. Scoprirai i diversi tipi di errori, alcune buone pratiche di debugging, cosa sono le eccezioni e come gestirle." + ] + }, + "lab-isbn-validator": { + "title": "Esegui il debug di un validatore ISBN", + "intro": [ + "In questo laboratorio, partirai da un'app con bug e dovrai eseguire il debug e correggere i bug finché non funziona correttamente." + ] + }, + "review-error-handling": { + "title": "Revisione della gestione degli errori", + "intro": [ + "Prima di affrontare il quiz sulla gestione degli errori, rivedi ciò che hai imparato a riguardo." + ] + }, + "quiz-error-handling": { + "title": "Quiz sulla gestione degli errori", + "intro": [ + "Metti alla prova ciò che hai imparato sulla gestione degli errori in Python con questo quiz." + ] + }, + "lecture-classes-and-objects": { + "title": "Classi e oggetti", + "intro": ["Impara le classi e gli oggetti in queste lezioni."] + }, + "workshop-musical-instrument-inventory": { + "title": "Crea un inventario di strumenti musicali", + "intro": [ + "In questo workshop, imparerai classi, oggetti e metodi in Python costruendo un semplice inventario di strumenti musicali." + ] + }, + "lab-planet-class": { + "title": "Crea una classe Pianeta", + "intro": [ + "In questo laboratorio creerai una classe che rappresenta un pianeta." + ] + }, + "workshop-email-simulator": { + "title": "Crea un simulatore di email", + "intro": [ + "In questo workshop implementerai classi e oggetti costruendo un simulatore di email che simula l'invio, la ricezione e la gestione delle email tra diversi utenti." + ] + }, + "review-classes-and-objects": { + "title": "Revisione di classi e oggetti", + "intro": [ + "Prima di affrontare il quiz su classi e oggetti, rivedi ciò che hai imparato su di essi.", + "Apri questa pagina per rivedere concetti come il funzionamento delle classi, cosa sono gli oggetti, i metodi, gli attributi, i metodi speciali e altro." + ] + }, + "quiz-classes-and-objects": { + "title": "Quiz su classi e oggetti", + "intro": [ + "Metti alla prova ciò che hai imparato su classi e oggetti in Python con questo quiz." + ] + }, + "lab-budget-app": { + "title": "Crea un'app per il budget", + "intro": [ + "In questo laboratorio costruirai un'app per il budget ed eserciterai la creazione di una classe e dei metodi per quella classe." + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "Comprendere la programmazione orientata agli oggetti e l'incapsulamento", + "intro": [ + "Impara a comprendere la programmazione orientata agli oggetti e l'incapsulamento in queste lezioni." + ] + }, + "workshop-salary-tracker": { + "title": "Crea un tracciatore di stipendi", + "intro": [ + "In questo workshop eserciterai incapsulamento, proprietà e altri concetti OOP costruendo un sistema di monitoraggio degli stipendi per i dipendenti." + ] + }, + "lab-game-character-stats": { + "title": "Crea un tracciatore di statistiche per personaggi di gioco", + "intro": [ + "In questo laboratorio costruirai un personaggio di gioco con diverse statistiche usando la programmazione orientata agli oggetti." + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "Comprendere ereditarietà e polimorfismo", + "intro": [ + "Impara a comprendere ereditarietà e polimorfismo in queste lezioni." + ] + }, + "workshop-media-catalogue": { + "title": "Crea un catalogo multimediale", + "intro": [ + "In questo workshop creerai un'applicazione per catalogo multimediale usando i principi della programmazione orientata agli oggetti." + ] + }, + "lecture-understanding-abstraction": { + "title": "Comprendere l'astrazione", + "intro": ["Impara a comprendere l'astrazione in queste lezioni."] + }, + "workshop-discount-calculator": { + "title": "Crea un calcolatore di sconti", + "intro": [ + "In questo workshop costruirai un calcolatore di prezzi scontati flessibile tramite classi base astratte, permettendo di applicare più algoritmi di sconto in modo intercambiabile senza modificare la logica centrale." + ] + }, + "lab-player-interface": { + "title": "Crea un'interfaccia giocatore", + "intro": [ + "In questo laboratorio userai il modulo abc per costruire un'interfaccia giocatore." + ] + }, + "review-object-oriented-programming": { + "title": "Revisione della programmazione orientata agli oggetti", + "intro": [ + "Prima di affrontare il quiz sulla programmazione orientata agli oggetti, rivedi ciò che hai imparato a riguardo." + ] + }, + "quiz-object-oriented-programming": { + "title": "Quiz sulla programmazione orientata agli oggetti", + "intro": [ + "Metti alla prova ciò che hai imparato sulla programmazione orientata agli oggetti in Python con questo quiz." + ] + }, + "lab-polygon-area-calculator": { + "title": "Crea un calcolatore di area di poligoni", + "intro": [ + "In questo laboratorio userai la programmazione orientata agli oggetti per calcolare le aree di diversi poligoni come quadrati e rettangoli." + ] + }, + "review-python": { + "title": "Revisione dei fondamenti di programmazione Python", + "intro": ["Rivedi i concetti di Python per prepararti all'esame imminente."] + } + } + }, "algorithms-and-data-structure": { "title": "Certificazione algoritmi e struttura dati", "intro": [ diff --git a/client/japanese/intro.json b/client/japanese/intro.json index 180967737c7..86c1a4e471e 100644 --- a/client/japanese/intro.json +++ b/client/japanese/intro.json @@ -1221,7 +1221,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "コマンドラインの理解とBashの操作", "intro": [ - "これらのレッスンでコマンドラインとBashの操作について学びます。" + "これらのレッスンでコマンドラインとBashの使い方を学びましょう。" ] }, "workshop-bash-boilerplate": { @@ -1517,6 +1517,12 @@ "このワークショップでは、フォーマットされた従業員バッジを生成し、従業員コードを分析するツールを作りながら、Pythonの文字列操作の基本を練習します。" ] }, + "workshop-employee-profile-validator": { + "title": "従業員プロフィールバリデーターを作成する", + "intro": [ + "このワークショップでは、Pythonの文字列メソッドを使って従業員プロフィールのデータを検証およびフォーマットします。" + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "数値と数学的演算", "intro": [ @@ -6478,6 +6484,12 @@ "このワークショップでは、Pythonの文字列操作の基本を練習しながら、フォーマットされた従業員バッジを生成し、従業員コードを分析するツールを作成します。" ] }, + "workshop-employee-profile-validator": { + "title": "従業員プロフィールバリデーターを作成する", + "intro": [ + "このワークショップでは、Pythonの文字列メソッドを使って従業員プロフィールのデータを検証およびフォーマットします。" + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "数値と数学的演算", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "RPGキャラクターを作成する", "intro": [ - "このラボでは、RPGキャラクターを作成して基本的なPythonを練習します。" + "このラボでは、RPGキャラクターを作成してPythonの基本を練習します。" ] }, "review-python-basics": { @@ -7006,7 +7018,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "コマンドラインの理解とBashの操作", "intro": [ - "このレッスンでコマンドラインとBashの使い方を学びます。" + "これらのレッスンでコマンドラインとBashの使い方を学びましょう。" ] }, "workshop-bash-boilerplate": { @@ -10407,6 +10419,359 @@ "english-only": "このセクションのコースは英語のみで提供されています。現在、タイトルと紹介文のみ翻訳可能で、レッスン自体は翻訳されていません。", "exam-english-only": "認定試験は現在英語のみで提供されていることにご注意ください。他のコースは一部の言語で利用可能です。" }, + "python-programming-fundamentals": { + "title": "Pythonプログラミング基礎", + "intro": [ + "このコースではPythonプログラミングの基礎を学びます。", + "必要なプロジェクトを完成させ、試験に合格してPythonプログラミング基礎認定を取得してください。" + ], + "chapters": { + "python-programming-fundamentals": "Pythonプログラミング基礎" + }, + "modules": { + "python-basics": "Python基礎", + "python-installation": "Pythonのインストール", + "python-loops-and-sequences": "ループとシーケンス", + "python-dictionaries-and-sets": "辞書とセット", + "lab-user-configuration-manager": "ユーザー設定マネージャーを作成する", + "python-error-handling": "エラー処理", + "python-classes-and-objects": "クラスとオブジェクト", + "lab-budget-app": "予算アプリを作成する", + "python-object-oriented-programming": "オブジェクト指向プログラミング(OOP)", + "lab-polygon-area-calculator": "多角形の面積計算機を作成する", + "review-python-programming-fundamentals": "Pythonレビュー" + }, + "blocks": { + "workshop-first-python-program": { + "title": "最初のPythonプログラムを作成する", + "intro": [ + "このワークショップでは、Pythonで最初のプログラムを作成します。" + ] + }, + "lecture-introduction-to-python": { + "title": "Python入門", + "intro": [ + "これらのレッスンでPythonとは何か、業界での一般的な使い方を学びます。" + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "変数とデータ型の理解", + "intro": [ + "これらのレッスンでPythonの変数とデータ型について学びます。" + ] + }, + "workshop-report-card-printer": { + "title": "成績表プリンターを作成する", + "intro": [ + "このワークショップでは、Pythonの基本データ型を使って簡単な成績表のデータを作成し、出力する練習をします。" + ] + }, + "lecture-introduction-to-python-strings": { + "title": "文字列入門", + "intro": ["これらのレッスンでPythonの文字列について学びます。"] + }, + "workshop-employee-profile-generator": { + "title": "従業員プロフィールジェネレーターを作成する", + "intro": [ + "このワークショップでは、Pythonの文字列操作の基礎を練習し、フォーマットされた従業員バッジを生成し、従業員コードを分析するツールを作成します。" + ] + }, + "workshop-employee-profile-validator": { + "title": "従業員プロフィールバリデーターを作成する", + "intro": [ + "このワークショップでは、Pythonの文字列メソッドを使って従業員プロフィールのデータを検証およびフォーマットします。" + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "数値と数学的演算", + "intro": [ + "これらのレッスンでPythonの数値と数学的演算について学びます。" + ] + }, + "workshop-bill-splitter": { + "title": "割り勘計算機を作成する", + "intro": [ + "このワークショップでは、Pythonの数値と数学的演算を使って割り勘計算機を作成します。" + ] + }, + "lecture-booleans-and-conditionals": { + "title": "ブール値と条件分岐", + "intro": [ + "これらのレッスンでPythonのブール値と条件分岐について学びます。" + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "映画チケット予約計算機を作成する", + "intro": [ + "このワークショップでは、Pythonのブール値と条件文を使って映画チケット予約計算機を作成します。" + ] + }, + "lab-travel-weather-planner": { + "title": "旅行天気プランナーを作成する", + "intro": [ + "このラボでは、条件分岐を使って旅行天気プランナーを作成します。" + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "関数とスコープの理解", + "intro": [ + "これらのレッスンでPythonの関数とスコープについて学びます。" + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "キッチン在庫トラッカーを作成する", + "intro": [ + "このワークショップでは、Pythonの関数とスコープを使ってキッチン在庫トラッカーを作成します。" + ] + }, + "lab-discount-calculator": { + "title": "割引適用関数を作成する", + "intro": [ + "このラボでは、価格に割引を適用する計算機を作成してPythonの基本を練習します。" + ] + }, + "workshop-caesar-cipher": { + "title": "シーザー暗号を作成する", + "intro": [ + "このワークショップでは、文字列、条件分岐、関数などの基本的なPythonの概念を使ってシーザー暗号を作成します。" + ] + }, + "lab-rpg-character": { + "title": "RPGキャラクターを作成する", + "intro": [ + "このラボでは、RPGキャラクターを作成してPythonの基本を練習します。" + ] + }, + "review-python-basics": { + "title": "Python基礎レビュー", + "intro": [ + "Python基礎のクイズを受ける前に、学んだ内容を復習してください。", + "このレビュー画面で、文字列、関数、比較演算子などの扱い方を復習します。" + ] + }, + "quiz-python-basics": { + "title": "Python基礎クイズ", + "intro": [ + "このクイズでPython基礎の理解度を試してください。" + ] + }, + "lecture-python-installation": { + "title": "Pythonのインストールとローカルでのコード実行", + "intro": [ + "これらのレッスンで、ローカルデバイスにPythonをインストールし、コードを実行する方法を学びます。" + ] + }, + "review-python-installation": { + "title": "Pythonインストールレビュー", + "intro": [ + "Pythonをローカルで使うクイズを受ける前に、レッスンで学んだ内容を復習してください。" + ] + }, + "quiz-python-installation": { + "title": "Pythonインストールクイズ", + "intro": [ + "このクイズでPythonのローカルインストールについての理解度を試してください。" + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "ループとシーケンスの操作", + "intro": [ + "これらのレッスンでループとシーケンスの操作について学びます。" + ] + }, + "workshop-pin-extractor": { + "title": "ピン抽出器を作成する", + "intro": [ + "このワークショップでは、詩に隠された秘密のピンを抽出する関数を作成します。" + ] + }, + "lab-number-pattern-generator": { + "title": "数字パターンジェネレーターを作成する", + "intro": ["このラボでは、数字パターンジェネレーターを作成します。"] + }, + "review-loops-and-sequences": { + "title": "ループとシーケンスレビュー", + "intro": [ + "ループとシーケンスのクイズを受ける前に、学んだ内容を復習してください。", + "このページを開いて、ループ、リスト、タプル、およびそれらの一般的なメソッドに関する概念を復習します。" + ] + }, + "quiz-loops-and-sequences": { + "title": "ループとシーケンスクイズ", + "intro": [ + "このクイズでPythonのループとシーケンスの理解度を試してください。" + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "辞書とセットの操作", + "intro": [ + "これらのレッスンで辞書とセットの操作について学びます。" + ] + }, + "lecture-working-with-modules": { + "title": "モジュールの操作", + "intro": ["これらのレッスンでモジュールの操作について学びましょう。"] + }, + "workshop-medical-data-validator": { + "title": "医療データバリデーターを作成する", + "intro": [ + "このワークショップでは、辞書とセットを使って医療データのコレクションを検証する練習をします。" + ] + }, + "review-dictionaries-and-sets": { + "title": "辞書とセットの復習", + "intro": [ + "辞書とセットのクイズを受ける前に、学んだ内容を復習してください。", + "このページを開いて、辞書、セット、モジュールのインポートに関する概念を復習しましょう。" + ] + }, + "quiz-dictionaries-and-sets": { + "title": "辞書とセットのクイズ", + "intro": [ + "このクイズでPythonの辞書とセットについて学んだことを試してください。" + ] + }, + "lab-user-configuration-manager": { + "title": "ユーザー設定マネージャーを作成する", + "intro": [ + "このラボでは、Pythonの辞書を使った操作を練習します。" + ] + }, + "lecture-understanding-error-handling": { + "title": "エラー処理の理解", + "intro": [ + "これらのレッスンでPythonのエラー処理について学びます。さまざまなエラーの種類、良いデバッグの方法、例外とは何か、それらの処理方法を学びます。" + ] + }, + "lab-isbn-validator": { + "title": "ISBNバリデーターのデバッグ", + "intro": [ + "このラボでは、バグのあるアプリから始めて、バグをデバッグして修正し、正常に動作するようにします。" + ] + }, + "review-error-handling": { + "title": "エラー処理の復習", + "intro": [ + "エラー処理のクイズを受ける前に、学んだ内容を復習してください。" + ] + }, + "quiz-error-handling": { + "title": "エラー処理のクイズ", + "intro": [ + "このクイズでPythonのエラー処理について学んだことを試してください。" + ] + }, + "lecture-classes-and-objects": { + "title": "クラスとオブジェクト", + "intro": ["これらのレッスンでクラスとオブジェクトについて学びましょう。"] + }, + "workshop-musical-instrument-inventory": { + "title": "楽器在庫管理を作成する", + "intro": [ + "このワークショップでは、Pythonのクラス、オブジェクト、メソッドについて学びながら、簡単な楽器在庫管理を作成します。" + ] + }, + "lab-planet-class": { + "title": "惑星クラスを作成する", + "intro": [ + "このラボでは、惑星を表すクラスを作成します。" + ] + }, + "workshop-email-simulator": { + "title": "メールシミュレーターを作成する", + "intro": [ + "このワークショップでは、クラスとオブジェクトを実装し、異なるユーザー間でメールの送受信や管理をシミュレートするメールシミュレーターを作成します。" + ] + }, + "review-classes-and-objects": { + "title": "クラスとオブジェクトの復習", + "intro": [ + "クラスとオブジェクトのクイズを受ける前に、学んだ内容を復習してください。", + "このページを開いて、クラスの仕組み、オブジェクト、メソッド、属性、特殊メソッドなどの概念を復習しましょう。" + ] + }, + "quiz-classes-and-objects": { + "title": "クラスとオブジェクトのクイズ", + "intro": [ + "このクイズでPythonのクラスとオブジェクトについて学んだことを試してください。" + ] + }, + "lab-budget-app": { + "title": "予算アプリを作成する", + "intro": [ + "このラボでは、予算アプリを作成し、そのクラスとメソッドの作成を練習します。" + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "オブジェクト指向プログラミングとカプセル化の理解", + "intro": [ + "これらのレッスンでオブジェクト指向プログラミングとカプセル化の理解を深めましょう。" + ] + }, + "workshop-salary-tracker": { + "title": "給与トラッカーを作成する", + "intro": [ + "このワークショップでは、カプセル化、プロパティ、その他のOOP概念を使って従業員の給与追跡システムを作成します。" + ] + }, + "lab-game-character-stats": { + "title": "ゲームキャラクターのステータストラッカーを作成する", + "intro": [ + "このラボでは、オブジェクト指向プログラミングを使って異なるステータスを持つゲームキャラクターを作成します。" + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "継承とポリモーフィズムの理解", + "intro": [ + "これらのレッスンで継承とポリモーフィズムの理解を深めましょう。" + ] + }, + "workshop-media-catalogue": { + "title": "メディアカタログを作成する", + "intro": [ + "このワークショップでは、オブジェクト指向プログラミングの原則を使ってメディアカタログアプリケーションを作成します。" + ] + }, + "lecture-understanding-abstraction": { + "title": "抽象化の理解", + "intro": ["これらのレッスンで抽象化の理解を深めましょう。"] + }, + "workshop-discount-calculator": { + "title": "割引計算機を作成する", + "intro": [ + "このワークショップでは、抽象基底クラスを使って柔軟な割引価格計算機を作成し、コアロジックを変更せずに複数の割引アルゴリズムを切り替えて適用できるようにします。" + ] + }, + "lab-player-interface": { + "title": "プレイヤーインターフェースを作成する", + "intro": [ + "このラボでは、abcモジュールを使ってプレイヤーインターフェースを作成します。" + ] + }, + "review-object-oriented-programming": { + "title": "オブジェクト指向プログラミングの復習", + "intro": [ + "オブジェクト指向プログラミングのクイズを受ける前に、学んだ内容を復習してください。" + ] + }, + "quiz-object-oriented-programming": { + "title": "オブジェクト指向プログラミングのクイズ", + "intro": [ + "このクイズでPythonのオブジェクト指向プログラミングについて学んだことを試してください。" + ] + }, + "lab-polygon-area-calculator": { + "title": "多角形面積計算機を作成する", + "intro": [ + "このラボでは、オブジェクト指向プログラミングを使って正方形や長方形などの多角形の面積を計算します。" + ] + }, + "review-python": { + "title": "Pythonプログラミング基礎の復習", + "intro": ["今後の試験に備えてPythonの概念を復習しましょう。"] + } + } + }, "algorithms-and-data-structure": { "title": "アルゴリズムとデータ構造認定", "intro": [ diff --git a/client/korean/intro.json b/client/korean/intro.json index 3e3cfb9a530..1b027dfcc46 100644 --- a/client/korean/intro.json +++ b/client/korean/intro.json @@ -1221,7 +1221,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "명령줄 이해와 Bash 작업", "intro": [ - "이 수업들에서 명령줄과 Bash 작업에 대해 배우세요." + "이 수업에서 명령줄과 Bash 사용법을 배우세요." ] }, "workshop-bash-boilerplate": { @@ -1517,6 +1517,12 @@ "이 워크숍에서 형식화된 직원 배지를 생성하고 직원 코드를 분석하는 도구를 만들어 Python 문자열 조작 기초를 연습하세요." ] }, + "workshop-employee-profile-validator": { + "title": "직원 프로필 검증기 만들기", + "intro": [ + "이 워크숍에서는 Python 문자열 메서드를 사용해 직원 프로필 데이터를 검증하고 형식을 맞추는 방법을 배우세요." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "숫자와 수학 연산", "intro": [ @@ -6478,6 +6484,12 @@ "이 워크숍에서는 포맷된 직원 배지를 생성하고 직원 코드를 분석하는 도구를 만들어 Python 문자열 조작 기본을 연습합니다." ] }, + "workshop-employee-profile-validator": { + "title": "직원 프로필 검증기 만들기", + "intro": [ + "이 워크숍에서는 Python 문자열 메서드를 사용해 직원 프로필 데이터를 검증하고 형식을 맞추는 방법을 배우세요." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "숫자와 수학 연산", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "RPG 캐릭터 만들기", "intro": [ - "이 실습에서는 RPG 캐릭터를 만들어 기본 Python을 연습하세요." + "이 실습에서 RPG 캐릭터를 만들어 기본 Python을 연습하세요." ] }, "review-python-basics": { @@ -7006,7 +7018,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "명령줄 이해와 배시 사용하기", "intro": [ - "이 수업들에서 명령줄과 배시 사용법을 배우세요." + "이 수업에서 명령줄과 Bash 사용법을 배우세요." ] }, "workshop-bash-boilerplate": { @@ -10407,6 +10419,359 @@ "english-only": "이 섹션의 과정들은 영어로만 제공됩니다. 현재 제목과 소개만 번역할 수 있으며 수업 자체는 번역하지 못합니다.", "exam-english-only": "인증 시험은 현재 영어로만 제공됩니다. 나머지 과정들은 일부 언어로 제공됩니다." }, + "python-programming-fundamentals": { + "title": "Python 프로그래밍 기초", + "intro": [ + "이 과정에서는 Python 프로그래밍의 기초를 배웁니다.", + "필수 프로젝트를 완료하고 시험에 합격하면 Python 프로그래밍 기초 인증서를 받으세요." + ], + "chapters": { + "python-programming-fundamentals": "Python 프로그래밍 기초" + }, + "modules": { + "python-basics": "Python 기초", + "python-installation": "Python 설치", + "python-loops-and-sequences": "반복문과 수열", + "python-dictionaries-and-sets": "사전과 집합", + "lab-user-configuration-manager": "사용자 구성 관리자 만들기", + "python-error-handling": "오류 처리", + "python-classes-and-objects": "클래스와 객체", + "lab-budget-app": "예산 앱 만들기", + "python-object-oriented-programming": "객체지향 프로그래밍 (OOP)", + "lab-polygon-area-calculator": "다각형 넓이 계산기 만들기", + "review-python-programming-fundamentals": "Python 복습" + }, + "blocks": { + "workshop-first-python-program": { + "title": "첫 Python 프로그램 만들기", + "intro": [ + "이 워크숍에서 첫 Python 프로그램을 만드세요." + ] + }, + "lecture-introduction-to-python": { + "title": "Python 소개", + "intro": [ + "이 수업에서 Python이 무엇인지와 업계에서의 일반적인 용도를 배우세요." + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "변수와 데이터 유형 이해하기", + "intro": [ + "이 수업에서 Python의 변수와 데이터 유형에 대해 배우세요." + ] + }, + "workshop-report-card-printer": { + "title": "성적표 출력기 만들기", + "intro": [ + "이 워크숍에서 간단한 성적표 데이터를 만들고 출력하며 Python의 원시 데이터 유형을 연습하세요." + ] + }, + "lecture-introduction-to-python-strings": { + "title": "문자열 소개", + "intro": ["이 수업에서 Python의 문자열에 대해 배우세요."] + }, + "workshop-employee-profile-generator": { + "title": "직원 프로필 생성기 만들기", + "intro": [ + "이 워크숍에서 Python 문자열 조작 기초를 연습하며 형식화된 직원 배지를 생성하고 직원 코드를 분석하는 도구를 만드세요." + ] + }, + "workshop-employee-profile-validator": { + "title": "직원 프로필 검증기 만들기", + "intro": [ + "이 워크숍에서는 Python 문자열 메서드를 사용해 직원 프로필 데이터를 검증하고 형식을 맞추는 방법을 배우세요." + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "숫자와 수학 연산", + "intro": [ + "이 수업에서 Python의 숫자와 수학 연산에 대해 배우세요." + ] + }, + "workshop-bill-splitter": { + "title": "계산서 분할기 만들기", + "intro": [ + "이 워크숍에서 Python의 숫자와 수학 연산을 연습하기 위해 계산서 분할기를 만드세요." + ] + }, + "lecture-booleans-and-conditionals": { + "title": "불리언과 조건문", + "intro": [ + "이 수업에서 Python의 불리언과 조건문에 대해 배우세요." + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "영화 티켓 예약 계산기 만들기", + "intro": [ + "이 워크숍에서 불리언과 조건문을 사용해 영화 티켓 예약 계산기를 만드세요." + ] + }, + "lab-travel-weather-planner": { + "title": "여행 날씨 계획기 만들기", + "intro": [ + "이 실습에서 조건문을 사용해 여행 날씨 계획기를 만드세요." + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "함수와 범위 이해하기", + "intro": [ + "이 수업에서 Python의 함수와 범위에 대해 배우세요." + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "주방 재고 추적기 만들기", + "intro": [ + "이 워크숍에서 함수와 범위를 사용해 주방 재고 추적기를 만드세요." + ] + }, + "lab-discount-calculator": { + "title": "할인 적용 함수 만들기", + "intro": [ + "이 실습에서 가격에 할인을 적용하는 계산기를 만들어 기본 Python을 연습하세요." + ] + }, + "workshop-caesar-cipher": { + "title": "시저 암호 만들기", + "intro": [ + "이 워크숍에서 문자열, 조건문, 함수 등 기본 Python 개념을 사용해 시저 암호를 만드세요." + ] + }, + "lab-rpg-character": { + "title": "RPG 캐릭터 만들기", + "intro": [ + "이 실습에서 RPG 캐릭터를 만들어 기본 Python을 연습하세요." + ] + }, + "review-python-basics": { + "title": "Python 기초 복습", + "intro": [ + "Python 기초 퀴즈 전에 배운 내용을 복습하세요.", + "이 복습 페이지에서 문자열, 함수, 비교 연산자 등을 복습하세요." + ] + }, + "quiz-python-basics": { + "title": "Python 기초 퀴즈", + "intro": [ + "이 퀴즈로 Python 기초에 대해 배운 내용을 테스트하세요." + ] + }, + "lecture-python-installation": { + "title": "Python 설치 및 로컬에서 코드 실행하기", + "intro": [ + "이 수업에서 로컬 장치에 Python을 설치하고 코드를 실행하는 방법을 배우세요." + ] + }, + "review-python-installation": { + "title": "Python 설치 복습", + "intro": [ + "로컬에서 Python 작업에 대한 퀴즈 전에 수업 내용을 복습하세요." + ] + }, + "quiz-python-installation": { + "title": "Python 설치 퀴즈", + "intro": [ + "이 퀴즈로 로컬에 Python 설치에 대해 배운 내용을 테스트하세요." + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "반복문과 수열 작업하기", + "intro": [ + "이 수업에서 반복문과 수열 작업에 대해 배우세요." + ] + }, + "workshop-pin-extractor": { + "title": "핀 추출기 만들기", + "intro": [ + "이 워크숍에서 시에 숨겨진 비밀 핀을 추출하는 함수를 만드세요." + ] + }, + "lab-number-pattern-generator": { + "title": "숫자 패턴 생성기 만들기", + "intro": ["이 실습에서 숫자 패턴 생성기를 만드세요."] + }, + "review-loops-and-sequences": { + "title": "반복문과 수열 복습", + "intro": [ + "반복문과 수열 퀴즈 전에 배운 내용을 복습하세요.", + "이 페이지를 열어 반복문, 리스트, 튜플과 그 일반 메서드 개념을 복습하세요." + ] + }, + "quiz-loops-and-sequences": { + "title": "반복문과 수열 퀴즈", + "intro": [ + "이 퀴즈로 Python의 반복문과 수열에 대해 배운 내용을 테스트하세요." + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "사전과 집합 작업하기", + "intro": [ + "이 수업에서 사전과 집합 작업에 대해 배우세요." + ] + }, + "lecture-working-with-modules": { + "title": "모듈 작업하기", + "intro": ["이 수업에서 모듈 작업에 대해 배우세요."] + }, + "workshop-medical-data-validator": { + "title": "의료 데이터 검증기 만들기", + "intro": [ + "이 워크숍에서는 의료 데이터 모음을 검증하면서 딕셔너리와 세트를 다루는 연습을 하세요." + ] + }, + "review-dictionaries-and-sets": { + "title": "딕셔너리와 세트 복습", + "intro": [ + "딕셔너리와 세트에 대해 퀴즈를 보기 전에 배운 내용을 복습하세요.", + "이 페이지를 열어 딕셔너리, 세트, 모듈 가져오기 개념을 복습하세요." + ] + }, + "quiz-dictionaries-and-sets": { + "title": "딕셔너리와 세트 퀴즈", + "intro": [ + "이 퀴즈로 Python의 딕셔너리와 세트에 대해 배운 내용을 테스트하세요." + ] + }, + "lab-user-configuration-manager": { + "title": "사용자 구성 관리자 만들기", + "intro": [ + "이 실습에서 Python의 딕셔너리를 다루는 연습을 하세요." + ] + }, + "lecture-understanding-error-handling": { + "title": "오류 처리 이해하기", + "intro": [ + "이 수업에서 Python의 오류 처리에 대해 배우세요. 다양한 오류 유형, 좋은 디버깅 방법, 예외가 무엇인지, 그리고 예외를 처리하는 방법을 배웁니다." + ] + }, + "lab-isbn-validator": { + "title": "ISBN 검증기 디버그하기", + "intro": [ + "이 실습에서는 버그가 있는 애플리케이션으로 시작해 버그를 디버그하고 수정하여 제대로 작동하게 만드세요." + ] + }, + "review-error-handling": { + "title": "오류 처리 복습", + "intro": [ + "오류 처리에 대해 퀴즈를 보기 전에 배운 내용을 복습하세요." + ] + }, + "quiz-error-handling": { + "title": "오류 처리 퀴즈", + "intro": [ + "이 퀴즈로 Python의 오류 처리에 대해 배운 내용을 테스트하세요." + ] + }, + "lecture-classes-and-objects": { + "title": "클래스와 객체", + "intro": ["이 수업에서 클래스와 객체에 대해 배우세요."] + }, + "workshop-musical-instrument-inventory": { + "title": "악기 재고 만들기", + "intro": [ + "이 워크숍에서는 간단한 악기 재고를 만들어 Python의 클래스, 객체, 메서드에 대해 배우세요." + ] + }, + "lab-planet-class": { + "title": "행성 클래스 만들기", + "intro": [ + "이 실습에서 행성을 나타내는 클래스를 만드세요." + ] + }, + "workshop-email-simulator": { + "title": "이메일 시뮬레이터 만들기", + "intro": [ + "이 워크숍에서는 서로 다른 사용자 간 이메일을 보내고 받고 관리하는 이메일 시뮬레이터를 만들어 클래스와 객체를 구현하세요." + ] + }, + "review-classes-and-objects": { + "title": "클래스와 객체 복습", + "intro": [ + "클래스와 객체에 대해 퀴즈를 보기 전에 배운 내용을 복습하세요.", + "이 페이지를 열어 클래스 작동 방식, 객체, 메서드, 속성, 특수 메서드 등 개념을 복습하세요." + ] + }, + "quiz-classes-and-objects": { + "title": "클래스와 객체 퀴즈", + "intro": [ + "이 퀴즈로 Python의 클래스와 객체에 대해 배운 내용을 테스트하세요." + ] + }, + "lab-budget-app": { + "title": "예산 앱 만들기", + "intro": [ + "이 실습에서 예산 앱을 만들고 해당 클래스와 메서드를 만드는 연습을 하세요." + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "객체 지향 프로그래밍과 캡슐화 이해하기", + "intro": [ + "이 수업에서 객체 지향 프로그래밍과 캡슐화에 대해 배우세요." + ] + }, + "workshop-salary-tracker": { + "title": "급여 추적기 만들기", + "intro": [ + "이 워크숍에서는 캡슐화, 프로퍼티, 기타 OOP 개념을 연습하며 직원 급여 추적 시스템을 만드세요." + ] + }, + "lab-game-character-stats": { + "title": "게임 캐릭터 능력치 추적기 만들기", + "intro": [ + "이 실습에서 객체 지향 프로그래밍을 사용해 다양한 능력치를 가진 게임 캐릭터를 만드세요." + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "상속과 다형성 이해하기", + "intro": [ + "이 수업에서 상속과 다형성에 대해 배우세요." + ] + }, + "workshop-media-catalogue": { + "title": "미디어 카탈로그 만들기", + "intro": [ + "이 워크숍에서는 객체 지향 프로그래밍 원칙을 사용해 미디어 카탈로그 애플리케이션을 만드세요." + ] + }, + "lecture-understanding-abstraction": { + "title": "추상화 이해하기", + "intro": ["이 수업에서 추상화에 대해 배우세요."] + }, + "workshop-discount-calculator": { + "title": "할인 계산기 만들기", + "intro": [ + "이 워크숍에서는 추상 기본 클래스를 통해 유연한 할인 가격 계산기를 만들어 핵심 로직을 수정하지 않고 여러 할인 알고리즘을 교체하며 적용할 수 있게 하세요." + ] + }, + "lab-player-interface": { + "title": "플레이어 인터페이스 만들기", + "intro": [ + "이 실습에서 abc 모듈을 사용해 플레이어 인터페이스를 만드세요." + ] + }, + "review-object-oriented-programming": { + "title": "객체 지향 프로그래밍 복습", + "intro": [ + "객체 지향 프로그래밍에 대해 퀴즈를 보기 전에 배운 내용을 복습하세요." + ] + }, + "quiz-object-oriented-programming": { + "title": "객체 지향 프로그래밍 퀴즈", + "intro": [ + "이 퀴즈로 Python의 객체 지향 프로그래밍에 대해 배운 내용을 테스트하세요." + ] + }, + "lab-polygon-area-calculator": { + "title": "다각형 면적 계산기 만들기", + "intro": [ + "이 실습에서 객체 지향 프로그래밍을 사용해 정사각형, 직사각형 같은 다양한 다각형의 면적을 계산하세요." + ] + }, + "review-python": { + "title": "Python 프로그래밍 기초 복습", + "intro": ["다가오는 시험을 준비하기 위해 Python 개념을 복습하세요."] + } + } + }, "algorithms-and-data-structure": { "title": "알고리즘과 자료 구조 인증서", "intro": [ diff --git a/client/portuguese/intro.json b/client/portuguese/intro.json index fc0334b7ed3..4a9a4daf697 100644 --- a/client/portuguese/intro.json +++ b/client/portuguese/intro.json @@ -1221,7 +1221,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "Entendendo a linha de comando e trabalhando com Bash", "intro": [ - "Aprenda sobre a linha de comando e como trabalhar com Bash nessas lições." + "Aprenda sobre a linha de comando e como trabalhar com Bash nestas lições." ] }, "workshop-bash-boilerplate": { @@ -1517,6 +1517,12 @@ "Neste laboratório, você praticará os fundamentos da manipulação de strings em Python criando uma ferramenta que gera crachás formatados e analisa códigos de funcionários." ] }, + "workshop-employee-profile-validator": { + "title": "Construa um validador de perfil de funcionário", + "intro": [ + "Nesta oficina, você usará métodos de string do Python para validar e formatar dados de um perfil de funcionário." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Números e operações matemáticas", "intro": [ @@ -6478,6 +6484,12 @@ "Neste workshop, você vai praticar os fundamentos da manipulação de strings em Python criando uma ferramenta que gera crachás formatados de funcionários e analisa códigos de funcionários." ] }, + "workshop-employee-profile-validator": { + "title": "Construa um validador de perfil de funcionário", + "intro": [ + "Nesta oficina, você usará métodos de string do Python para validar e formatar dados de um perfil de funcionário." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Números e operações matemáticas", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "Criar um personagem de RPG", "intro": [ - "Neste laboratório, você vai praticar o básico de Python criando um personagem de RPG." + "Neste laboratório, você praticará o básico de Python construindo um personagem de RPG." ] }, "review-python-basics": { @@ -7006,7 +7018,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "Entendendo a linha de comando e trabalhando com Bash", "intro": [ - "Aprenda sobre a linha de comando e como trabalhar com Bash nessas lições." + "Aprenda sobre a linha de comando e como trabalhar com Bash nestas lições." ] }, "workshop-bash-boilerplate": { @@ -10407,6 +10419,359 @@ "english-only": "Os cursos desta seção estão disponíveis apenas em inglês. No momento, só podemos traduzir os títulos e introduções, não as lições.", "exam-english-only": "Observe que o exame de certificação está disponível atualmente apenas em inglês. O restante dos cursos está disponível em alguns idiomas." }, + "python-programming-fundamentals": { + "title": "Fundamentos da programação em Python", + "intro": [ + "Este curso ensina os fundamentos da programação em Python.", + "Complete os projetos obrigatórios e passe no exame para obter a certificação Fundamentos da programação em Python." + ], + "chapters": { + "python-programming-fundamentals": "Fundamentos da programação em Python" + }, + "modules": { + "python-basics": "Noções básicas de Python", + "python-installation": "Instalar Python", + "python-loops-and-sequences": "Loops e sequências", + "python-dictionaries-and-sets": "Dicionários e conjuntos", + "lab-user-configuration-manager": "Construa um gerenciador de configuração de usuário", + "python-error-handling": "Tratamento de erros", + "python-classes-and-objects": "Classes e objetos", + "lab-budget-app": "Construa um app de orçamento", + "python-object-oriented-programming": "Programação orientada a objetos (POO)", + "lab-polygon-area-calculator": "Construa uma calculadora de área de polígono", + "review-python-programming-fundamentals": "Revisão de Python" + }, + "blocks": { + "workshop-first-python-program": { + "title": "Construa seu primeiro programa em Python", + "intro": [ + "Para esta oficina, você construirá seu primeiro programa em Python." + ] + }, + "lecture-introduction-to-python": { + "title": "Introdução ao Python", + "intro": [ + "Nestas lições, você aprenderá o que é Python e seus usos comuns na indústria." + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "Entendendo variáveis e tipos de dados", + "intro": [ + "Nestas lições, você aprenderá sobre variáveis e tipos de dados em Python." + ] + }, + "workshop-report-card-printer": { + "title": "Construa uma impressora de boletim escolar", + "intro": [ + "Nesta oficina, você praticará trabalhar com tipos de dados primitivos em Python criando e imprimindo dados para um boletim simples." + ] + }, + "lecture-introduction-to-python-strings": { + "title": "Introdução às strings", + "intro": ["Nestas lições, você aprenderá sobre strings em Python."] + }, + "workshop-employee-profile-generator": { + "title": "Construa um gerador de perfil de funcionário", + "intro": [ + "Nesta oficina, você praticará os fundamentos da manipulação de strings em Python construindo uma ferramenta que gera crachás formatados de funcionários e analisa códigos de funcionários." + ] + }, + "workshop-employee-profile-validator": { + "title": "Construa um validador de perfil de funcionário", + "intro": [ + "Nesta oficina, você usará métodos de string do Python para validar e formatar dados de um perfil de funcionário." + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "Números e operações matemáticas", + "intro": [ + "Nestas lições, você aprenderá sobre números e operações matemáticas em Python." + ] + }, + "workshop-bill-splitter": { + "title": "Construa um divisor de conta", + "intro": [ + "Nesta oficina, você construirá um divisor de conta para praticar trabalhar com números e operações matemáticas em Python." + ] + }, + "lecture-booleans-and-conditionals": { + "title": "Booleanos e condicionais", + "intro": [ + "Nestas lições, você aprenderá sobre booleanos e condicionais em Python." + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "Construa uma calculadora de reserva de ingressos de cinema", + "intro": [ + "Nesta oficina, você praticará como usar booleanos e declarações condicionais em Python construindo uma calculadora de reserva de ingressos de cinema." + ] + }, + "lab-travel-weather-planner": { + "title": "Construa um planejador de clima para viagens", + "intro": [ + "Neste laboratório, você construirá um planejador de clima para viagens usando condicionais." + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "Entendendo funções e escopo", + "intro": [ + "Nestas lições, você aprenderá sobre funções e escopo em Python." + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "Construa um rastreador de inventário de cozinha", + "intro": [ + "Nesta oficina, você praticará trabalhar com funções e escopo em Python construindo um rastreador de inventário de cozinha." + ] + }, + "lab-discount-calculator": { + "title": "Construa uma função para aplicar desconto", + "intro": [ + "Neste laboratório, você praticará o básico de Python construindo uma calculadora para aplicar desconto a um preço." + ] + }, + "workshop-caesar-cipher": { + "title": "Construa uma cifra de César", + "intro": [ + "Nesta oficina, você construirá uma cifra de César usando conceitos básicos de Python como strings, condicionais, funções e mais." + ] + }, + "lab-rpg-character": { + "title": "Construa um personagem de RPG", + "intro": [ + "Neste laboratório, você praticará o básico de Python construindo um personagem de RPG." + ] + }, + "review-python-basics": { + "title": "Revisão de noções básicas de Python", + "intro": [ + "Antes de fazer o quiz sobre noções básicas de Python, você deve revisar o que aprendeu.", + "Nesta página de revisão, você revisará o trabalho com strings, funções, operadores de comparação e mais." + ] + }, + "quiz-python-basics": { + "title": "Quiz de noções básicas de Python", + "intro": [ + "Teste o que aprendeu sobre noções básicas de Python com este quiz." + ] + }, + "lecture-python-installation": { + "title": "Instalando Python e executando código localmente", + "intro": [ + "Nestas lições, você aprenderá como instalar Python no seu dispositivo local e executar código localmente." + ] + }, + "review-python-installation": { + "title": "Revisão da instalação do Python", + "intro": [ + "Antes de fazer o quiz sobre trabalhar com Python localmente, você deve revisar os conceitos abordados nas lições." + ] + }, + "quiz-python-installation": { + "title": "Quiz de instalação do Python", + "intro": [ + "Teste o que aprendeu sobre instalar Python localmente com este quiz." + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "Trabalhando com loops e sequências", + "intro": [ + "Aprenda sobre trabalhar com loops e sequências nestas lições." + ] + }, + "workshop-pin-extractor": { + "title": "Construa um extrator de PIN", + "intro": [ + "Nesta oficina, você construirá uma função para extrair PINs secretos escondidos em poemas." + ] + }, + "lab-number-pattern-generator": { + "title": "Construa um gerador de padrão numérico", + "intro": ["Neste laboratório, você construirá um gerador de padrão numérico."] + }, + "review-loops-and-sequences": { + "title": "Revisão de loops e sequências", + "intro": [ + "Antes de fazer o quiz sobre loops e sequências, você deve revisar o que aprendeu sobre eles.", + "Abra esta página para revisar conceitos sobre loops, listas, tuplas e alguns de seus métodos comuns." + ] + }, + "quiz-loops-and-sequences": { + "title": "Quiz de loops e sequências", + "intro": [ + "Teste o que aprendeu sobre loops e sequências em Python com este quiz." + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "Trabalhando com dicionários e conjuntos", + "intro": [ + "Aprenda sobre trabalhar com dicionários e conjuntos nestas lições." + ] + }, + "lecture-working-with-modules": { + "title": "Trabalhando com módulos", + "intro": ["Aprenda a trabalhar com módulos nessas lições."] + }, + "workshop-medical-data-validator": { + "title": "Construa um validador de dados médicos", + "intro": [ + "Nesta oficina, você praticará o uso de dicionários e conjuntos enquanto valida uma coleção de dados médicos." + ] + }, + "review-dictionaries-and-sets": { + "title": "Revisão de dicionários e conjuntos", + "intro": [ + "Antes de fazer o quiz sobre dicionários e conjuntos, revise o que aprendeu sobre eles.", + "Abra esta página para revisar conceitos sobre dicionários, conjuntos e como importar módulos." + ] + }, + "quiz-dictionaries-and-sets": { + "title": "Quiz de dicionários e conjuntos", + "intro": [ + "Teste o que aprendeu sobre dicionários e conjuntos em Python com este quiz." + ] + }, + "lab-user-configuration-manager": { + "title": "Construa um gerenciador de configuração de usuário", + "intro": [ + "Neste laboratório, você praticará o uso de dicionários em Python." + ] + }, + "lecture-understanding-error-handling": { + "title": "Entendendo o tratamento de erros", + "intro": [ + "Nessas lições, você aprenderá sobre tratamento de erros em Python. Vai conhecer os diferentes tipos de erros, boas práticas de depuração, o que são exceções e como tratá-las." + ] + }, + "lab-isbn-validator": { + "title": "Depure um validador de ISBN", + "intro": [ + "Neste laboratório, você começará com uma aplicação com bugs e precisará depurar e corrigir os bugs até que funcione adequadamente." + ] + }, + "review-error-handling": { + "title": "Revisão de tratamento de erros", + "intro": [ + "Antes de fazer o quiz sobre tratamento de erros, revise o que aprendeu sobre o assunto." + ] + }, + "quiz-error-handling": { + "title": "Quiz de tratamento de erros", + "intro": [ + "Teste o que aprendeu sobre tratamento de erros em Python com este quiz." + ] + }, + "lecture-classes-and-objects": { + "title": "Classes e objetos", + "intro": ["Aprenda sobre classes e objetos nessas lições."] + }, + "workshop-musical-instrument-inventory": { + "title": "Construa um inventário de instrumentos musicais", + "intro": [ + "Nesta oficina, você aprenderá sobre classes, objetos e métodos em Python construindo um inventário simples de instrumentos musicais." + ] + }, + "lab-planet-class": { + "title": "Construa uma classe planeta", + "intro": [ + "Neste laboratório, você criará uma classe que representa um planeta." + ] + }, + "workshop-email-simulator": { + "title": "Construa um simulador de e-mail", + "intro": [ + "Nesta oficina, você implementará classes e objetos construindo um simulador de e-mail que simula o envio, recebimento e gerenciamento de e-mails entre diferentes usuários." + ] + }, + "review-classes-and-objects": { + "title": "Revisão de classes e objetos", + "intro": [ + "Antes de fazer o quiz sobre classes e objetos, revise o que aprendeu sobre eles.", + "Abra esta página para revisar conceitos como funcionamento das classes, o que são objetos, métodos, atributos, métodos especiais e mais." + ] + }, + "quiz-classes-and-objects": { + "title": "Quiz de classes e objetos", + "intro": [ + "Teste o que aprendeu sobre classes e objetos em Python com este quiz." + ] + }, + "lab-budget-app": { + "title": "Construa um app de orçamento", + "intro": [ + "Neste laboratório, você construirá um app de orçamento e praticará a criação de uma classe e métodos para essa classe." + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "Entendendo programação orientada a objetos e encapsulamento", + "intro": [ + "Aprenda sobre programação orientada a objetos e encapsulamento nessas lições." + ] + }, + "workshop-salary-tracker": { + "title": "Construa um rastreador de salário", + "intro": [ + "Nesta oficina, você praticará encapsulamento, propriedades e outros conceitos de POO construindo um sistema de rastreamento salarial para funcionários." + ] + }, + "lab-game-character-stats": { + "title": "Construa um rastreador de estatísticas de personagem de jogo", + "intro": [ + "Neste laboratório, você construirá um personagem de jogo com diferentes estatísticas usando programação orientada a objetos." + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "Entendendo herança e polimorfismo", + "intro": [ + "Aprenda sobre herança e polimorfismo nessas lições." + ] + }, + "workshop-media-catalogue": { + "title": "Construa um catálogo de mídia", + "intro": [ + "Nesta oficina, você criará uma aplicação de catálogo de mídia usando princípios de programação orientada a objetos." + ] + }, + "lecture-understanding-abstraction": { + "title": "Entendendo abstração", + "intro": ["Aprenda sobre abstração nessas lições."] + }, + "workshop-discount-calculator": { + "title": "Construa uma calculadora de descontos", + "intro": [ + "Nesta oficina, você construirá uma calculadora flexível de preços com desconto usando classes base abstratas, permitindo aplicar múltiplos algoritmos de desconto de forma intercambiável sem modificar a lógica principal." + ] + }, + "lab-player-interface": { + "title": "Construa uma interface de jogador", + "intro": [ + "Neste laboratório, você usará o módulo abc para construir uma interface de jogador." + ] + }, + "review-object-oriented-programming": { + "title": "Revisão de programação orientada a objetos", + "intro": [ + "Antes de fazer o quiz sobre programação orientada a objetos, revise o que aprendeu sobre o assunto." + ] + }, + "quiz-object-oriented-programming": { + "title": "Quiz de programação orientada a objetos", + "intro": [ + "Teste o que aprendeu sobre programação orientada a objetos em Python com este quiz." + ] + }, + "lab-polygon-area-calculator": { + "title": "Construa uma calculadora de área de polígono", + "intro": [ + "Neste laboratório, você usará programação orientada a objetos para calcular as áreas de diferentes polígonos como quadrados e retângulos." + ] + }, + "review-python": { + "title": "Revisão dos fundamentos de programação em Python", + "intro": ["Revise conceitos de Python para se preparar para o próximo exame."] + } + } + }, "algorithms-and-data-structure": { "title": "Certificação em algoritmos e estrutura de dados", "intro": [ diff --git a/client/swahili/intro.json b/client/swahili/intro.json index 1c4c091b16f..c4edb0ed8cf 100644 --- a/client/swahili/intro.json +++ b/client/swahili/intro.json @@ -1221,7 +1221,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "Kuelewa Amri za Mstari na Kufanya kazi na Bash", "intro": [ - "Jifunze kuhusu Amri za Mstari na Kufanya kazi na Bash katika mafundisho haya." + "Jifunze kuhusu mstari wa amri na kufanya kazi na Bash katika mafundisho haya." ] }, "workshop-bash-boilerplate": { @@ -1517,6 +1517,12 @@ "Katika warsha hii, utatumia misingi ya uendeshaji wa mfuatano wa herufi katika Python kwa kujenga chombo kinachotengeneza beji za mfanyakazi zilizo na muundo na kuchambua misimbo ya wafanyakazi." ] }, + "workshop-employee-profile-validator": { + "title": "Jenga Kithibitishaji cha Wasifu wa Mfanyakazi", + "intro": [ + "Katika warsha hii, utatumia njia za mfuatano wa herufi za Python kuthibitisha na kuunda data kutoka kwa wasifu wa mfanyakazi." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Nambari na shughuli za kihesabu", "intro": [ @@ -6478,6 +6484,12 @@ "Katika warsha hii, utajifunza misingi ya usindikaji wa mfuatano wa herufi katika Python kwa kujenga chombo kinachozalisha beji za mfanyakazi zilizoandaliwa na kuchambua misimbo ya wafanyakazi." ] }, + "workshop-employee-profile-validator": { + "title": "Jenga Kithibitishaji cha Wasifu wa Mfanyakazi", + "intro": [ + "Katika warsha hii, utatumia njia za mfuatano wa herufi za Python kuthibitisha na kuunda data kutoka kwa wasifu wa mfanyakazi." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Nambari na shughuli za kihesabu", "intro": [ @@ -6535,7 +6547,7 @@ "lab-rpg-character": { "title": "Jenga mhusika wa RPG", "intro": [ - "Katika warsha hii utatumia Python ya msingi kwa kujenga mhusika wa RPG." + "Katika maabara hii utatumia Python ya msingi kwa kujenga mhusika wa RPG." ] }, "review-python-basics": { @@ -10407,6 +10419,359 @@ "english-only": "Kozi katika sehemu hii zinapatikana kwa Kiingereza tu. Kwa sasa tunaweza kutafsiri vichwa na utangulizi tu, si mafundisho yenyewe.", "exam-english-only": "Tafadhali kumbuka kuwa mtihani wa vyeti kwa sasa unapatikana kwa Kiingereza tu. Kozi zingine zinapatikana kwa baadhi ya lugha." }, + "python-programming-fundamentals": { + "title": "Misingi ya programu ya Python", + "intro": [ + "Kozi hii inafundisha misingi ya programu ya Python.", + "Kamilisha miradi inayohitajika na pita mtihani ili kupata Cheti cha Misingi ya Programu ya Python." + ], + "chapters": { + "python-programming-fundamentals": "Misingi ya programu ya Python" + }, + "modules": { + "python-basics": "Misingi ya Python", + "python-installation": "Sakinisha Python", + "python-loops-and-sequences": "Mizunguko na mfululizo", + "python-dictionaries-and-sets": "Kamusi na seti", + "lab-user-configuration-manager": "Jenga Meneja wa Usanidi wa Mtumizi", + "python-error-handling": "Kushughulikia makosa", + "python-classes-and-objects": "Darasa la vitu na vitu", + "lab-budget-app": "Jenga Programu ya Bajeti", + "python-object-oriented-programming": "Uandishi wa programu unaotegemea vitu (OOP)", + "lab-polygon-area-calculator": "Jenga Kihesabu cha Eneo la Mstatili", + "review-python-programming-fundamentals": "Kagua Python" + }, + "blocks": { + "workshop-first-python-program": { + "title": "Jenga Programu Yako ya Kwanza ya Python", + "intro": [ + "Kwa warsha hii, utajenga programu yako ya kwanza kwa Python." + ] + }, + "lecture-introduction-to-python": { + "title": "Utangulizi wa Python", + "intro": [ + "Katika mafundisho haya, utajifunza Python ni nini na matumizi yake ya kawaida katika sekta." + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "Kuelewa vigezo na aina za data", + "intro": [ + "Katika mafundisho haya, utajifunza kuhusu vigezo na aina za data katika Python." + ] + }, + "workshop-report-card-printer": { + "title": "Jenga Kifaa cha Kuchapisha Kadi ya Ripoti", + "intro": [ + "Katika warsha hii, utatumia kufanya kazi na aina za data za msingi katika Python kwa kuunda na kuchapisha data kwa kadi rahisi ya ripoti." + ] + }, + "lecture-introduction-to-python-strings": { + "title": "Utangulizi wa mfuatano wa herufi", + "intro": ["Katika mafundisho haya, utajifunza kuhusu mfuatano wa herufi katika Python."] + }, + "workshop-employee-profile-generator": { + "title": "Jenga Kizalishaji cha Wasifu wa Mfanyakazi", + "intro": [ + "Katika warsha hii, utatumia misingi ya usindikaji wa mfuatano wa herufi katika Python kwa kujenga chombo kinachozalisha bango za mfanyakazi zilizoandaliwa na kuchambua misimbo ya mfanyakazi." + ] + }, + "workshop-employee-profile-validator": { + "title": "Jenga Kithibitishaji cha Wasifu wa Mfanyakazi", + "intro": [ + "Katika warsha hii, utatumia njia za mfuatano wa herufi za Python kuthibitisha na kuunda data kutoka kwa wasifu wa mfanyakazi." + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "Nambari na shughuli za kihesabu", + "intro": [ + "Katika mafundisho haya, utajifunza kuhusu nambari na shughuli za kihesabu katika Python." + ] + }, + "workshop-bill-splitter": { + "title": "Jenga Kifaa cha Kugawanya Bili", + "intro": [ + "Katika warsha hii utajenga kifaa cha kugawanya bili ili kufanya mazoezi ya kufanya kazi na nambari na shughuli za kihesabu katika Python." + ] + }, + "lecture-booleans-and-conditionals": { + "title": "Thamani ya kweli au siyo kweli na masharti", + "intro": [ + "Katika mafundisho haya, utajifunza kuhusu thamani ya kweli au siyo kweli na masharti katika Python." + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "Jenga Kihesabu cha Kuweka Tiketi ya Sinema", + "intro": [ + "Katika warsha hii, utatumia mazoezi ya jinsi ya kutumia thamani ya kweli au siyo kweli na taarifa za masharti katika Python kwa kujenga kihesabu cha kuweka tiketi ya sinema." + ] + }, + "lab-travel-weather-planner": { + "title": "Jenga Mpangaji wa Hali ya Hewa ya Safari", + "intro": [ + "Katika maabara hii, utajenga mpangaji wa hali ya hewa ya safari kwa kutumia masharti." + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "Kuelewa kitendakazi na wigo", + "intro": [ + "Katika mafundisho haya, utajifunza kuhusu kitendakazi na wigo katika Python." + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "Jenga Kifuatilia Orodha ya Jikoni", + "intro": [ + "Katika warsha hii, utatumia mazoezi ya kufanya kazi na kitendakazi na wigo katika Python kwa kujenga kifuatilia orodha ya jikoni." + ] + }, + "lab-discount-calculator": { + "title": "Jenga Kitendakazi cha Kutumia Punguzo", + "intro": [ + "Katika maabara hii, utatumia Python ya msingi kwa kujenga kihesabu cha kutumia punguzo kwa bei." + ] + }, + "workshop-caesar-cipher": { + "title": "Jenga Cipher ya Caesar", + "intro": [ + "Katika warsha hii, utajenga cipher ya Caesar kwa kutumia dhana za msingi za Python kama mfuatano wa herufi, masharti, kitendakazi, na zaidi." + ] + }, + "lab-rpg-character": { + "title": "Jenga Mhusika wa RPG", + "intro": [ + "Katika maabara hii utatumia Python ya msingi kwa kujenga mhusika wa RPG." + ] + }, + "review-python-basics": { + "title": "Kagua Misingi ya Python", + "intro": [ + "Kabla ya kujaribiwa kuhusu misingi ya Python, unapaswa kukagua kile ulichojifunza kuhusu hiyo.", + "Katika ukurasa huu wa ukaguzi, utakagua kufanya kazi na mfuatano wa herufi, kitendakazi, waendeshaji wa kulinganisha na zaidi." + ] + }, + "quiz-python-basics": { + "title": "Jaribio fupi la misingi ya Python", + "intro": [ + "Jaribu kile ulichojifunza kuhusu misingi ya Python kwa jaribio hili." + ] + }, + "lecture-python-installation": { + "title": "Kusakinisha Python na kuendesha msimbo kwa ndani", + "intro": [ + "Katika mafundisho haya, utajifunza jinsi ya kusakinisha Python kwenye kifaa chako cha ndani na kuendesha msimbo kwa ndani." + ] + }, + "review-python-installation": { + "title": "Kagua Usakinishaji wa Python", + "intro": [ + "Kabla ya kujaribiwa kuhusu kufanya kazi na Python kwa ndani, unapaswa kukagua dhana zilizofundishwa katika mafundisho." + ] + }, + "quiz-python-installation": { + "title": "Jaribio fupi la usakinishaji wa Python", + "intro": [ + "Jaribu kile ulichojifunza kuhusu kusakinisha Python kwa ndani kwa jaribio hili." + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "Kufanya kazi na mizunguko na mfululizo", + "intro": [ + "Jifunze kuhusu kufanya kazi na mizunguko na mfululizo katika mafundisho haya." + ] + }, + "workshop-pin-extractor": { + "title": "Jenga Kichimbaji cha Pin", + "intro": [ + "Katika warsha hii utajenga kitendakazi cha kuchimba pin za siri zilizofichwa katika mashairi." + ] + }, + "lab-number-pattern-generator": { + "title": "Jenga Kizalishaji cha Mchoro wa Nambari", + "intro": ["Katika maabara hii utajenga kizalishaji cha mchoro wa nambari."] + }, + "review-loops-and-sequences": { + "title": "Kagua mizunguko na mfululizo", + "intro": [ + "Kabla ya kujaribiwa kuhusu mizunguko na mfululizo, unapaswa kukagua kile ulichojifunza kuhusu hayo.", + "Fungua ukurasa huu kukagua dhana zinazohusu mizunguko, orodha, tuple na baadhi ya njia zao za kawaida." + ] + }, + "quiz-loops-and-sequences": { + "title": "Jaribio fupi la mizunguko na mfululizo", + "intro": [ + "Jaribu kile ulichojifunza kuhusu mizunguko na mfululizo katika Python kwa jaribio hili." + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "Kufanya kazi na kamusi na seti", + "intro": [ + "Jifunze kuhusu kufanya kazi na kamusi na seti katika mafundisho haya." + ] + }, + "lecture-working-with-modules": { + "title": "Kufanya kazi na moduli", + "intro": ["Jifunze kuhusu kufanya kazi na moduli katika mafundisho haya."] + }, + "workshop-medical-data-validator": { + "title": "Jenga kimsingi kinachothibitisha data za matibabu", + "intro": [ + "Katika warsha hii, utatumia kufanya kazi na kamusi na seti huku ukithibitisha mkusanyiko wa data za matibabu." + ] + }, + "review-dictionaries-and-sets": { + "title": "Kagua kamusi na seti", + "intro": [ + "Kabla hujajibu jaribio kuhusu kamusi na seti, unapaswa kukagua kile ulichojifunza kuhusu hizo.", + "Fungua ukurasa huu kukagua dhana zinazohusu kamusi, seti, na jinsi ya import moduli." + ] + }, + "quiz-dictionaries-and-sets": { + "title": "Jaribio la kamusi na seti", + "intro": [ + "Jaribu kile ulichojifunza kuhusu kamusi na seti katika Python kwa jaribio hili." + ] + }, + "lab-user-configuration-manager": { + "title": "Jenga msimamizi wa usanidi wa mtumizi", + "intro": [ + "Katika maabara hii, utatumia kufanya kazi na kamusi katika Python." + ] + }, + "lecture-understanding-error-handling": { + "title": "Kuelewa jinsi ya kushughulikia makosa", + "intro": [ + "Katika mafundisho haya, utajifunza kuhusu jinsi ya kushughulikia makosa katika Python. Utajifunza aina tofauti za makosa, baadhi ya mbinu nzuri za kurekebisha makosa, ni nini exceptions, na jinsi ya kuzishughulikia." + ] + }, + "lab-isbn-validator": { + "title": "Tafuta hitilafu katika kinathibitisha ISBN", + "intro": [ + "Katika maabara hii, utaanza na programu yenye hitilafu, na utahitaji kutafuta makosa na kuyarekebisha hadi ifanye kazi vizuri." + ] + }, + "review-error-handling": { + "title": "Kagua jinsi ya kushughulikia makosa", + "intro": [ + "Kabla hujajibu jaribio kuhusu jinsi ya kushughulikia makosa, unapaswa kukagua kile ulichojifunza kuhusu hilo." + ] + }, + "quiz-error-handling": { + "title": "Jaribio la kushughulikia makosa", + "intro": [ + "Jaribu kile ulichojifunza kuhusu kushughulikia makosa katika Python kwa jaribio hili." + ] + }, + "lecture-classes-and-objects": { + "title": "Darasa la vitu na vitu", + "intro": ["Jifunze kuhusu madarasa ya vitu na vitu katika mafundisho haya."] + }, + "workshop-musical-instrument-inventory": { + "title": "Jenga orodha ya vyombo vya muziki", + "intro": [ + "Katika warsha hii, utajifunza kuhusu madarasa ya vitu, vitu, na njia katika Python kwa kujenga orodha rahisi ya vyombo vya muziki." + ] + }, + "lab-planet-class": { + "title": "Jenga darasa la sayari", + "intro": [ + "Katika maabara hii utaunda darasa la vitu linalowakilisha sayari." + ] + }, + "workshop-email-simulator": { + "title": "Jenga kielekezi cha barua pepe", + "intro": [ + "Katika warsha hii utatekeleza madarasa ya vitu kwa kujenga kielekezi cha barua pepe kinachofanikisha kutuma, kupokea, na kusimamia barua pepe kati ya watumizi tofauti." + ] + }, + "review-classes-and-objects": { + "title": "Kagua madarasa ya vitu na vitu", + "intro": [ + "Kabla hujajibu jaribio kuhusu madarasa ya vitu na vitu, unapaswa kukagua kile ulichojifunza kuhusu hayo.", + "Fungua ukurasa huu kukagua dhana kama jinsi madarasa ya vitu yanavyofanya kazi, ni nini vitu, njia, sifa za vipengele, njia maalum na zaidi." + ] + }, + "quiz-classes-and-objects": { + "title": "Jaribio la madarasa ya vitu na vitu", + "intro": [ + "Jaribu kile ulichojifunza kuhusu madarasa ya vitu na vitu katika Python kwa jaribio hili." + ] + }, + "lab-budget-app": { + "title": "Jenga programu ya bajeti", + "intro": [ + "Katika maabara hii utajenga programu ya bajeti na utatumia kuunda darasa la vitu na njia za darasa hilo." + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "Kuelewa uprogramaji unaozingatia vitu na kufunga data", + "intro": [ + "Jifunze kuhusu kuelewa uprogramaji unaozingatia vitu na kufunga data katika mafundisho haya." + ] + }, + "workshop-salary-tracker": { + "title": "Jenga kifuatilia mshahara", + "intro": [ + "Katika warsha hii, utatumia kufunga data, mali, na dhana nyingine za uprogramaji unaozingatia vitu kwa kujenga mfumo wa kufuatilia mishahara ya wafanyakazi." + ] + }, + "lab-game-character-stats": { + "title": "Jenga kifuatilia takwimu za mhusika wa mchezo", + "intro": [ + "Katika maabara hii, utajenga mhusika wa mchezo mwenye takwimu tofauti kwa kutumia uprogramaji unaozingatia vitu." + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "Kuelewa urithi na polymorphism", + "intro": [ + "Jifunze kuhusu kuelewa urithi na polymorphism katika mafundisho haya." + ] + }, + "workshop-media-catalogue": { + "title": "Jenga orodha ya vyombo vya habari", + "intro": [ + "Katika warsha hii, utaunda programu ya orodha ya vyombo vya habari kwa kutumia kanuni za uprogramaji unaozingatia vitu." + ] + }, + "lecture-understanding-abstraction": { + "title": "Kuelewa ufupishaji", + "intro": ["Jifunze kuhusu kuelewa ufupishaji katika mafundisho haya."] + }, + "workshop-discount-calculator": { + "title": "Jenga kielekezi cha punguzo", + "intro": [ + "Katika warsha hii utajenga kielekezi cha bei cha punguzo kinachobadilika kwa kutumia madarasa ya msingi ya ufupishaji, kuruhusu algoriti nyingi za punguzo kutumika badilika bila kubadilisha mantiki kuu." + ] + }, + "lab-player-interface": { + "title": "Jenga kiolesura cha mchezaji", + "intro": [ + "Katika maabara hii, utatumia moduli ya abc kujenga kiolesura cha mchezaji." + ] + }, + "review-object-oriented-programming": { + "title": "Kagua uprogramaji unaozingatia vitu", + "intro": [ + "Kabla hujajibu jaribio kuhusu uprogramaji unaozingatia vitu, unapaswa kukagua kile ulichojifunza kuhusu hilo." + ] + }, + "quiz-object-oriented-programming": { + "title": "Jaribio la uprogramaji unaozingatia vitu", + "intro": [ + "Jaribu kile ulichojifunza kuhusu uprogramaji unaozingatia vitu katika Python kwa jaribio hili." + ] + }, + "lab-polygon-area-calculator": { + "title": "Jenga kielekezi cha eneo la mstatili", + "intro": [ + "Katika maabara hii, utatumia uprogramaji unaozingatia vitu kukokotoa maeneo ya mstatili tofauti kama vile mraba na mstatili." + ] + }, + "review-python": { + "title": "Kagua misingi ya uprogramaji wa Python", + "intro": ["Kagua dhana za Python kujiandaa kwa mtihani unaokuja."] + } + } + }, "algorithms-and-data-structure": { "title": "Cheti cha Algoriti na Muundo wa Data", "intro": [ diff --git a/client/ukrainian/intro.json b/client/ukrainian/intro.json index 4ab9ea953a5..62e9a9b5971 100644 --- a/client/ukrainian/intro.json +++ b/client/ukrainian/intro.json @@ -1221,7 +1221,7 @@ "lecture-understanding-the-command-line-and-working-with-bash": { "title": "Розуміння командного рядка та робота з Bash", "intro": [ - "Вивчайте командний рядок і роботу з Bash у цих уроках." + "Дізнайтеся про командний рядок і роботу з Bash у цих уроках." ] }, "workshop-bash-boilerplate": { @@ -1517,6 +1517,12 @@ "У цій лабораторній роботі ви попрактикуєтеся з основами маніпуляції рядками в Python, створюючи інструмент для генерації форматованих бейджів співробітників і аналізу кодів співробітників." ] }, + "workshop-employee-profile-validator": { + "title": "Створіть валідатор профілю працівника", + "intro": [ + "На цьому практичному занятті ви використаєте методи рядків Python для перевірки та форматування даних профілю працівника." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Числа та математичні операції", "intro": [ @@ -6478,6 +6484,12 @@ "У цьому практичному занятті ви попрактикуєтеся з основами маніпуляції рядками в Python, створюючи інструмент для генерації форматованих бейджів співробітників і аналізу кодів співробітників." ] }, + "workshop-employee-profile-validator": { + "title": "Створіть валідатор профілю працівника", + "intro": [ + "На цьому практичному занятті ви використаєте методи рядків Python для перевірки та форматування даних профілю працівника." + ] + }, "lecture-numbers-and-mathematical-operations": { "title": "Числа та математичні операції", "intro": [ @@ -10407,6 +10419,359 @@ "english-only": "Курси в цьому розділі доступні лише англійською. Наразі ми можемо перекладати лише назви та вступи, а не самі уроки.", "exam-english-only": "Зверніть увагу, що екзамен на сертифікацію наразі доступний лише англійською. Решта курсів доступні деякими мовами." }, + "python-programming-fundamentals": { + "title": "Основи програмування на Python", + "intro": [ + "Цей курс навчає основам програмування на Python.", + "Виконайте необхідні проєкти та складіть екзамен, щоб отримати сертифікацію з основ програмування на Python." + ], + "chapters": { + "python-programming-fundamentals": "Основи програмування на Python" + }, + "modules": { + "python-basics": "Основи Python", + "python-installation": "Встановлення Python", + "python-loops-and-sequences": "Цикли та послідовності", + "python-dictionaries-and-sets": "Словники та множини", + "lab-user-configuration-manager": "Створіть менеджер конфігурації користувача", + "python-error-handling": "Обробка помилок", + "python-classes-and-objects": "Класи та об’єкти", + "lab-budget-app": "Створіть додаток для бюджету", + "python-object-oriented-programming": "Об’єктно-орієнтоване програмування (ООП)", + "lab-polygon-area-calculator": "Створіть калькулятор площі багатокутника", + "review-python-programming-fundamentals": "Повторення Python" + }, + "blocks": { + "workshop-first-python-program": { + "title": "Створіть свою першу програму на Python", + "intro": [ + "На цьому практичному занятті ви створите свою першу програму на Python." + ] + }, + "lecture-introduction-to-python": { + "title": "Вступ до Python", + "intro": [ + "У цих уроках ви дізнаєтеся, що таке Python і як його зазвичай використовують у галузі." + ] + }, + "lecture-understanding-variables-and-data-types": { + "title": "Розуміння змінних і типів даних", + "intro": [ + "У цих уроках ви дізнаєтеся про змінні та типи даних у Python." + ] + }, + "workshop-report-card-printer": { + "title": "Створіть принтер табеля успішності", + "intro": [ + "На цьому практичному занятті ви попрактикуєтеся з примітивними типами даних у Python, створюючи та виводячи дані для простого табеля успішності." + ] + }, + "lecture-introduction-to-python-strings": { + "title": "Вступ до рядків", + "intro": ["У цих уроках ви дізнаєтеся про рядки в Python."] + }, + "workshop-employee-profile-generator": { + "title": "Створіть генератор профілю працівника", + "intro": [ + "На цьому практичному занятті ви попрактикуєтеся з основами маніпуляції рядками в Python, створюючи інструмент для генерації форматованих бейджів працівників і аналізу кодів працівників." + ] + }, + "workshop-employee-profile-validator": { + "title": "Створіть валідатор профілю працівника", + "intro": [ + "На цьому практичному занятті ви використаєте методи рядків Python для перевірки та форматування даних профілю працівника." + ] + }, + "lecture-numbers-and-mathematical-operations": { + "title": "Числа та математичні операції", + "intro": [ + "У цих уроках ви дізнаєтеся про числа та математичні операції в Python." + ] + }, + "workshop-bill-splitter": { + "title": "Створіть калькулятор розподілу рахунку", + "intro": [ + "На цьому практичному занятті ви створите калькулятор розподілу рахунку, щоб попрактикуватися з числами та математичними операціями в Python." + ] + }, + "lecture-booleans-and-conditionals": { + "title": "Булеві значення та умовні оператори", + "intro": [ + "У цих уроках ви дізнаєтеся про булеві значення та умовні оператори в Python." + ] + }, + "workshop-movie-ticket-booking-calculator": { + "title": "Створіть калькулятор бронювання квитків у кіно", + "intro": [ + "На цьому практичному занятті ви попрактикуєтеся у використанні булевих значень та умовних інструкцій у Python, створюючи калькулятор бронювання квитків у кіно." + ] + }, + "lab-travel-weather-planner": { + "title": "Створіть планувальник погоди для подорожей", + "intro": [ + "У цій лабораторній роботі ви створите планувальник погоди для подорожей, використовуючи умовні оператори." + ] + }, + "lecture-understanding-functions-and-scope": { + "title": "Розуміння функцій і області видимості", + "intro": [ + "У цих уроках ви дізнаєтеся про функції та область видимості в Python." + ] + }, + "workshop-kitchen-inventory-tracker": { + "title": "Створіть трекер кухонних запасів", + "intro": [ + "На цьому практичному занятті ви попрактикуєтеся з функціями та областю видимості в Python, створюючи трекер кухонних запасів." + ] + }, + "lab-discount-calculator": { + "title": "Створіть функцію застосування знижки", + "intro": [ + "У цій лабораторній роботі ви попрактикуєтеся у базовому Python, створюючи калькулятор для застосування знижки до ціни." + ] + }, + "workshop-caesar-cipher": { + "title": "Створіть шифр Цезаря", + "intro": [ + "На цьому практичному занятті ви створите шифр Цезаря, використовуючи базові концепції Python, такі як рядки, умовні оператори, функції та інше." + ] + }, + "lab-rpg-character": { + "title": "Створіть персонажа RPG", + "intro": [ + "У цій лабораторній роботі ви попрактикуєтеся у базовому Python, створюючи персонажа RPG." + ] + }, + "review-python-basics": { + "title": "Повторення основ Python", + "intro": [ + "Перед тестуванням з основ Python варто повторити вивчене.", + "На цій сторінці повторення ви переглянете роботу з рядками, функціями, операторами порівняння та іншим." + ] + }, + "quiz-python-basics": { + "title": "Тест з основ Python", + "intro": [ + "Перевірте свої знання з основ Python за допомогою цього тесту." + ] + }, + "lecture-python-installation": { + "title": "Встановлення Python і запуск коду локально", + "intro": [ + "У цих уроках ви дізнаєтеся, як встановити Python на свій локальний пристрій і запускати код локально." + ] + }, + "review-python-installation": { + "title": "Повторення встановлення Python", + "intro": [ + "Перед тестуванням з роботи з Python локально варто повторити поняття, розглянуті в уроках." + ] + }, + "quiz-python-installation": { + "title": "Тест з встановлення Python", + "intro": [ + "Перевірте свої знання про встановлення Python локально за допомогою цього тесту." + ] + }, + "lecture-working-with-loops-and-sequences": { + "title": "Робота з циклами та послідовностями", + "intro": [ + "Дізнайтеся про роботу з циклами та послідовностями у цих уроках." + ] + }, + "workshop-pin-extractor": { + "title": "Створіть екстрактор PIN-кодів", + "intro": [ + "На цьому практичному занятті ви створите функцію для вилучення секретних PIN-кодів, захованих у віршах." + ] + }, + "lab-number-pattern-generator": { + "title": "Створіть генератор числових шаблонів", + "intro": ["У цій лабораторній роботі ви створите генератор числових шаблонів."] + }, + "review-loops-and-sequences": { + "title": "Повторення циклів і послідовностей", + "intro": [ + "Перед тестуванням з циклів і послідовностей варто повторити вивчене.", + "Відкрийте цю сторінку, щоб повторити поняття про цикли, списки, кортежі та деякі їхні загальні методи." + ] + }, + "quiz-loops-and-sequences": { + "title": "Тест з циклів і послідовностей", + "intro": [ + "Перевірте свої знання про цикли та послідовності в Python за допомогою цього тесту." + ] + }, + "lecture-working-with-dictionaries-and-sets": { + "title": "Робота зі словниками та множинами", + "intro": [ + "Дізнайтеся про роботу зі словниками та множинами у цих уроках." + ] + }, + "lecture-working-with-modules": { + "title": "Робота з модулями", + "intro": ["Дізнайтеся про роботу з модулями в цих уроках."] + }, + "workshop-medical-data-validator": { + "title": "Створіть валідатор медичних даних", + "intro": [ + "На цьому практичному занятті ви попрактикуєтеся з роботою зі словниками та множинами, перевіряючи колекцію медичних даних." + ] + }, + "review-dictionaries-and-sets": { + "title": "Повторення словників і множин", + "intro": [ + "Перед тестом зі словників і множин варто повторити вивчене про них.", + "Відкрийте цю сторінку, щоб повторити поняття словників, множин і імпорту модулів." + ] + }, + "quiz-dictionaries-and-sets": { + "title": "Тест зі словників і множин", + "intro": [ + "Перевірте свої знання про словники і множини в Python за допомогою цього тесту." + ] + }, + "lab-user-configuration-manager": { + "title": "Створіть менеджер конфігурації користувача", + "intro": [ + "У цій лабораторній роботі ви попрактикуєтеся з роботою зі словниками в Python." + ] + }, + "lecture-understanding-error-handling": { + "title": "Розуміння обробки помилок", + "intro": [ + "У цих уроках ви дізнаєтеся про обробку помилок у Python. Ви вивчите різні типи помилок, хороші практики налагодження, що таке виключення та як їх обробляти." + ] + }, + "lab-isbn-validator": { + "title": "Налагодьте валідатор ISBN", + "intro": [ + "У цій лабораторній роботі ви почнете з застосунку з помилками, які потрібно налагодити та виправити, щоб він працював правильно." + ] + }, + "review-error-handling": { + "title": "Повторення обробки помилок", + "intro": [ + "Перед тестом з обробки помилок варто повторити вивчене про неї." + ] + }, + "quiz-error-handling": { + "title": "Тест з обробки помилок", + "intro": [ + "Перевірте свої знання про обробку помилок у Python за допомогою цього тесту." + ] + }, + "lecture-classes-and-objects": { + "title": "Класи та об’єкти", + "intro": ["Дізнайтеся про класи та об’єкти в цих уроках."] + }, + "workshop-musical-instrument-inventory": { + "title": "Створіть інвентар музичних інструментів", + "intro": [ + "На цьому практичному занятті ви вивчите класи, об’єкти та методи в Python, створюючи простий інвентар музичних інструментів." + ] + }, + "lab-planet-class": { + "title": "Створіть клас планети", + "intro": [ + "У цій лабораторній роботі ви створите клас, який представляє планету." + ] + }, + "workshop-email-simulator": { + "title": "Створіть симулятор е-пошти", + "intro": [ + "На цьому практичному занятті ви реалізуєте класи та об’єкти, створюючи симулятор е-пошти, який імітує надсилання, отримання та керування листами між різними користувачами." + ] + }, + "review-classes-and-objects": { + "title": "Повторення класів і об’єктів", + "intro": [ + "Перед тестом з класів і об’єктів варто повторити вивчене про них.", + "Відкрийте цю сторінку, щоб повторити поняття про роботу класів, що таке об’єкти, методи, атрибути, спеціальні методи та інше." + ] + }, + "quiz-classes-and-objects": { + "title": "Тест з класів і об’єктів", + "intro": [ + "Перевірте свої знання про класи та об’єкти в Python за допомогою цього тесту." + ] + }, + "lab-budget-app": { + "title": "Створіть застосунок для бюджету", + "intro": [ + "У цій лабораторній роботі ви створите застосунок для бюджету та попрактикуєтеся у створенні класу та методів для нього." + ] + }, + "lecture-understanding-object-oriented-programming-and-encapsulation": { + "title": "Розуміння об’єктно-орієнтованого програмування та інкапсуляції", + "intro": [ + "Дізнайтеся про об’єктно-орієнтоване програмування та інкапсуляцію в цих уроках." + ] + }, + "workshop-salary-tracker": { + "title": "Створіть трекер зарплат", + "intro": [ + "На цьому практичному занятті ви попрактикуєтеся з інкапсуляцією, властивостями та іншими концепціями ООП, створюючи систему відстеження зарплат працівників." + ] + }, + "lab-game-character-stats": { + "title": "Створіть трекер характеристик ігрового персонажа", + "intro": [ + "У цій лабораторній роботі ви створите ігрового персонажа з різними характеристиками, використовуючи об’єктно-орієнтоване програмування." + ] + }, + "lecture-understanding-inheritance-and-polymorphism": { + "title": "Розуміння успадкування та поліморфізму", + "intro": [ + "Дізнайтеся про успадкування та поліморфізм у цих уроках." + ] + }, + "workshop-media-catalogue": { + "title": "Створіть каталог медіаконтенту", + "intro": [ + "На цьому практичному занятті ви створите застосунок каталогу медіаконтенту, використовуючи принципи об’єктно-орієнтованого програмування." + ] + }, + "lecture-understanding-abstraction": { + "title": "Розуміння абстракції", + "intro": ["Дізнайтеся про абстракцію в цих уроках."] + }, + "workshop-discount-calculator": { + "title": "Створіть калькулятор знижок", + "intro": [ + "На цьому практичному занятті ви створите гнучкий калькулятор цін зі знижками через абстрактні базові класи, що дозволить застосовувати різні алгоритми знижок без змін основної логіки." + ] + }, + "lab-player-interface": { + "title": "Створіть інтерфейс гравця", + "intro": [ + "У цій лабораторній роботі ви використаєте модуль abc для створення інтерфейсу гравця." + ] + }, + "review-object-oriented-programming": { + "title": "Повторення об’єктно-орієнтованого програмування", + "intro": [ + "Перед тестом з об’єктно-орієнтованого програмування варто повторити вивчене про нього." + ] + }, + "quiz-object-oriented-programming": { + "title": "Тест з об’єктно-орієнтованого програмування", + "intro": [ + "Перевірте свої знання про об’єктно-орієнтоване програмування в Python за допомогою цього тесту." + ] + }, + "lab-polygon-area-calculator": { + "title": "Створіть калькулятор площі багатокутника", + "intro": [ + "У цій лабораторній роботі ви використаєте об’єктно-орієнтоване програмування для обчислення площ різних багатокутників, таких як квадрати та прямокутники." + ] + }, + "review-python": { + "title": "Повторення основ програмування на Python", + "intro": ["Повторіть концепції Python, щоб підготуватися до майбутнього екзамену."] + } + } + }, "algorithms-and-data-structure": { "title": "Сертифікація з алгоритмів і структур даних", "intro": [ diff --git a/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b0e.md b/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b0e.md index 0b83dccb607..afc45f71190 100644 --- a/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b0e.md +++ b/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b0e.md @@ -1,6 +1,6 @@ --- id: 587d78b2367417b2b2512b0e -title: إضافة عناصر إلى مصفوفة باستخدام push() و unshift() +title: إضافة عناصر إلى مصفوفة باستخدام push()‎ و unshift()‎ challengeType: 1 forumTopicId: 301151 dashedName: add-items-to-an-array-with-push-and-unshift diff --git a/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b0f.md b/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b0f.md index 58d3cfaeb10..11aa94a97b2 100644 --- a/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b0f.md +++ b/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b0f.md @@ -1,6 +1,6 @@ --- id: 587d78b2367417b2b2512b0f -title: إزالة عناصر من مصفوفة باستخدام pop() و shift() +title: إزالة عناصر من مصفوفة باستخدام pop()‎ و shift()‎ challengeType: 1 forumTopicId: 301165 dashedName: remove-items-from-an-array-with-pop-and-shift diff --git a/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b10.md b/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b10.md index 0fcc495bca7..fc6c20d11ad 100644 --- a/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b10.md +++ b/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b2367417b2b2512b10.md @@ -1,6 +1,6 @@ --- id: 587d78b2367417b2b2512b10 -title: إزالة عناصر باستخدام splice() +title: إزالة عناصر باستخدام splice()‎ challengeType: 1 forumTopicId: 301166 dashedName: remove-items-using-splice diff --git a/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b3367417b2b2512b11.md b/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b3367417b2b2512b11.md index 5e54f7a23eb..e9deb3a8967 100644 --- a/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b3367417b2b2512b11.md +++ b/curriculum/challenges/arabic/blocks/basic-data-structures/587d78b3367417b2b2512b11.md @@ -1,6 +1,6 @@ --- id: 587d78b3367417b2b2512b11 -title: إضافة عناصر باستخدام splice() +title: إضافة عناصر باستخدام splice()‎ challengeType: 1 forumTopicId: 301152 dashedName: add-items-using-splice diff --git a/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7a367417b2b2512b12.md b/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7a367417b2b2512b12.md index a9a53d14ec5..b372f670e97 100644 --- a/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7a367417b2b2512b12.md +++ b/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7a367417b2b2512b12.md @@ -1,6 +1,6 @@ --- id: 587d7b7a367417b2b2512b12 -title: نسخ عناصر المصفوفة باستخدام slice() +title: نسخ عناصر المصفوفة باستخدام slice()‎ challengeType: 1 forumTopicId: 301158 dashedName: copy-array-items-using-slice diff --git a/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7b367417b2b2512b14.md b/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7b367417b2b2512b14.md index d6aa0b2c0ab..dff2afa214b 100644 --- a/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7b367417b2b2512b14.md +++ b/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7b367417b2b2512b14.md @@ -1,6 +1,6 @@ --- id: 587d7b7b367417b2b2512b14 -title: التحقق من وجود عنصر باستخدام indexOf() +title: التحقق من وجود عنصر باستخدام indexOf()‎ challengeType: 1 forumTopicId: 301154 dashedName: check-for-the-presence-of-an-element-with-indexof diff --git a/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7d367417b2b2512b1e.md b/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7d367417b2b2512b1e.md index 11d20a56853..803af3e6d88 100644 --- a/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7d367417b2b2512b1e.md +++ b/curriculum/challenges/arabic/blocks/basic-data-structures/587d7b7d367417b2b2512b1e.md @@ -1,6 +1,6 @@ --- id: 587d7b7d367417b2b2512b1e -title: توليد مصفوفة بكل مفاتيح الكائن باستخدام Object.keys() +title: توليد مصفوفة بكل مفاتيح الكائن باستخدام Object.keys()‎ challengeType: 1 forumTopicId: 301160 dashedName: generate-an-array-of-all-object-keys-with-object-keys diff --git a/curriculum/challenges/arabic/blocks/bootstrap/bad87fee1348bd9aedf08845.md b/curriculum/challenges/arabic/blocks/bootstrap/bad87fee1348bd9aedf08845.md index 793e481245e..d5bd7401b48 100644 --- a/curriculum/challenges/arabic/blocks/bootstrap/bad87fee1348bd9aedf08845.md +++ b/curriculum/challenges/arabic/blocks/bootstrap/bad87fee1348bd9aedf08845.md @@ -11,9 +11,9 @@ dashedName: use-a-span-to-target-inline-elements يمكنك استخدام عناصر span لإنشاء عناصر مضمَّنة. هل تذكر عندما استخدمنا صنف `btn-block` لجعل الزر يملأ الصف بأكمله؟ ```html - + - + ``` هذا يوضح الفرق بين عنصر "مضمَّن" وعنصر "كتلة". diff --git a/curriculum/challenges/arabic/blocks/bootstrap/bad87fee1348cd8acef08812.md b/curriculum/challenges/arabic/blocks/bootstrap/bad87fee1348cd8acef08812.md index e7771d76593..9b834a8297e 100644 --- a/curriculum/challenges/arabic/blocks/bootstrap/bad87fee1348cd8acef08812.md +++ b/curriculum/challenges/arabic/blocks/bootstrap/bad87fee1348cd8acef08812.md @@ -43,7 +43,7 @@ assert.isTrue(document.querySelector('button')?.classList?.contains('btn-default assert.isTrue(document.querySelector('button')?.classList?.contains('btn-block')); ``` -يجب أن تحتوي جميع عناصر `button` على وسم الإغلاق. +يجب أن تحتوي كل عناصر `button` الخاصة بك على وسم الإغلاق. ```js assert.match(code,/<\/button>/g); diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md deleted file mode 100644 index 6702d1867d5..00000000000 --- a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e21c48acb466c97ccbee7 -title: استدعاء الطرق من مكتبة أصناف .NET باستخدام C# -challengeType: 19 -dashedName: call-methods-from-the-dot-net-class-library-using-c-sharp ---- - -# --description-- - -سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: - -1. انتقل إلى https://learn.microsoft.com/training/modules/csharp-call-methods/ وأكمل جميع المهام في وحدة "استدعاء الطرق من مكتبة أصناف .NET باستخدام C#". هذا **مطلوب** للحصول على جائزة "إنشاء وتشغيل تطبيقات وحدة تحكم C# بسيطة" على Microsoft Learn، والتأهل لاختبار الشهادة. -1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. - -# --assignment-- - -أكمل وحدة استدعاء الطرق من مكتبة أصناف .NET باستخدام C# على Microsoft Learn. ثم أجب عن السؤال أدناه. - -# --questions-- - -## --text-- - -ما هو الكائن؟ - -## --answers-- - -عنوان ذاكرة. - ---- - -صنف عديم الحالة. - ---- - -مثيل من صنف. - -## --video-solution-- - -3 diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md deleted file mode 100644 index 522c12f3d9b..00000000000 --- a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e21d08acb466c97ccbee8 -title: مشروع تحدٍّ - تطوير تراكيب foreach و if-elseif-else لمعالجة بيانات المصفوفة في C# -challengeType: 19 -dashedName: challenge-project-develop-foreach-and-if-elseif-else-structures-to-process-array-data-in-c-sharp ---- - -# --description-- - -سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: - -1. انتقل إلى https://learn.microsoft.com/training/modules/challenge-project-arrays-iteration-selection/ وأكمل جميع المهام في وحدة "مشروع تحدٍّ - تطوير تراكيب foreach و if-elseif-else لمعالجة بيانات المصفوفة في C#". هذا ضروري للحصول على جائزة "إنشاء وتشغيل تطبيقات وحدة تحكم C# بسيطة" على Microsoft Learn، وللتأهل لاختبار الشهادة. -1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. - -# --assignment-- - -أكمل مشروع التحدي تطوير تراكيب `foreach` و `if`-`elseif`-`else` لمعالجة بيانات المصفوفة في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. - -# --questions-- - -## --text-- - -يعمل مطوِّر مع مطوِّرين آخرين لتحديث مجموعة من التطبيقات. سيستخدم المطوِّرون تعليقات الكود أثناء عملية التحديث. أي مما يلي يصف استخدامًا مناسبًا لتعليقات الكود؟ - -## --answers-- - -عند إجراء التحديثات، يستخدم المطوِّرون تعليقات سطرية وكتلية لتحديد كل تحديث كود فردي. - ---- - -عند إجراء التحديثات، يترك المطوِّرون جميع تعليقات الكود الموجودة كما هي. تُضاف تعليقات جديدة لتوضيح متى لم تعد التعليقات القديمة صالحة. - ---- - -عند إجراء التحديثات، يلخص المطوِّرون التغييرات باستخدام تعليقات كتلية. - -## --video-solution-- - -3 diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md deleted file mode 100644 index 6e01e2b09f5..00000000000 --- a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e21df8acb466c97ccbee9 -title: إنشاء كود قابل للقراءة باستخدام الاصطلاحات، والمسافات البيضاء، والتعليقات في C# -challengeType: 19 -dashedName: create-readable-code-with-conventions-whitespace-and-comments-in-c-sharp ---- - -# --description-- - -سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: - -1. اذهب إلى https://learn.microsoft.com/training/modules/csharp-readable-code/ وأكمل جميع المهام في وحدة "إنشاء كود قابل للقراءة باستخدام الاصطلاحات، والمسافات البيضاء، والتعليقات في C#". هذا **مطلوب** للحصول على جائزة "إنشاء وتشغيل تطبيقات C# بسيطة في وحدة التحكم" على Microsoft Learn، وللتأهل لاختبار الشهادة. -1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. - -# --assignment-- - -أكمل وحدة إنشاء كود قابل للقراءة باستخدام الاصطلاحات، والمسافات البيضاء، والتعليقات في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. - -# --questions-- - -## --text-- - -أي من الأسباب التالية يعتبر سببًا سيئًا لاستخدام تعليق في الكود؟ - -## --answers-- - -لوصف الهدف العام للكود. - ---- - -لإضافة تعليق للكود مؤقتًا على سطر أثناء تقييم ميزة بطريقة مختلفة. - ---- - -لشرح كيفية عمل كلمة مفتاحية جديدة في C#. - -## --video-solution-- - -3 diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md deleted file mode 100644 index 90f07ee66c8..00000000000 --- a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e21eb8acb466c97ccbeea -title: مشروع موجه - تطوير تراكيب foreach و if-elseif-else لمعالجة بيانات المصفوفة في C# -challengeType: 19 -dashedName: guided-project-develop-foreach-and-if-elseif-else-structures-to-process-array-data-in-c-sharp ---- - -# --description-- - -سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: - -1. انتقل إلى https://learn.microsoft.com/training/modules/guided-project-arrays-iteration-selection/ وأكمل جميع المهام في وحدة "مشروع موجه - تطوير تراكيب foreach و if-elseif-else لمعالجة بيانات المصفوفة في C#". هذا مطلوب للحصول على جائزة "إنشاء وتشغيل تطبيقات وحدة تحكم C# بسيطة" على Microsoft Learn، والتأهل لاختبار الشهادة. -1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. - -# --assignment-- - -أكمل مشروعًا موجهًا لتطوير تراكيب `foreach` و `if`-`elseif`-`else` لمعالجة بيانات المصفوفة في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. - -# --questions-- - -## --text-- - -يكتب مطوِّر تطبيقًا يستخدم حلقة `foreach` للتكرار خلال مصفوفة تحتوي على 20 عنصرًا. بعد إكمال التطبيق، يكتشف المطوِّر أن المصفوفة يجب تحديثها لتشمل 40 عنصرًا. يحتاج التطبيق إلى فحص جميع عناصر المصفوفة الـ 40. أي من الخيارات التالية يصف التحديث المطلوب للكود؟ - -## --answers-- - -أنشئ حلقة `foreach` ثانية تتكرر خلال العناصر الإضافية. - ---- - -لا يلزم إجراء أي تغييرات على حلقة `foreach`. - ---- - -ضع حلقة `foreach` الأصلية داخل كتلة الكود لحلقة `foreach` ثانية تتكرر مرتين. - -## --video-solution-- - -2 diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md deleted file mode 100644 index 1087ac1c94b..00000000000 --- a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -id: 647e22058acb466c97ccbeec -title: تخزين وتكرار متتاليات البيانات باستخدام المصفوفات وعبارة foreach في C# -challengeType: 19 -dashedName: store-and-iterate-through-sequences-of-data-using-arrays-and-the-foreach-statement-in-c-sharp ---- - -# --description-- - -سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: - -1. انتقل إلى https://learn.microsoft.com/training/modules/csharp-arrays/ وأكمل جميع المهام في وحدة "تخزين وتكرار متتاليات البيانات باستخدام المصفوفات وعبارة foreach في C#". هذا مطلوب للحصول على جائزة "إنشاء وتشغيل تطبيقات وحدة تحكم C# بسيطة" على Microsoft Learn، وللتأهل لاختبار الشهادة. -1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. - -# --assignment-- - -أكمل وحدة تخزين وتكرار متتاليات البيانات باستخدام المصفوفات وعبارة `foreach` في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. - -# --questions-- - -## --text-- - -أي من عبارات foreach التالية صحيحة نحويًا؟ - -## --answers-- - -`foreach (int value of values)` - ---- - -`foreach (int value with values)` - ---- - -`foreach (int value in values)` - - -## --video-solution-- - -3 diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md new file mode 100644 index 00000000000..4b35991cc03 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md @@ -0,0 +1,39 @@ +--- +id: 6ac3f7679fd5ceb2af42aa67 +title: تكرار الإجراءات باستخدام الحلقات في C# +challengeType: 19 +dashedName: repeat-actions-with-loops-in-c-sharp +--- + +# --description-- + +سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: + +1. انتقل إلى https://learn.microsoft.com/en-us/training/modules/csharp-repeat-actions-loops/ وأكمل جميع المهام في وحدة "تكرار الإجراءات باستخدام الحلقات في C#". هذا **مطلوب** للحصول على جائزة "إنشاء وتشغيل تطبيقات وحدة تحكم C# بسيطة" على Microsoft Learn، والتأهل لاختبار الشهادة. +1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. + +# --assignment-- + +أكمل وحدة تكرار الإجراءات باستخدام الحلقات في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. + +# --questions-- + +## --text-- + +أي حلقة تناسب أفضل عندما تعرف مسبقًا عدد المرات التي تريد تكرار الإجراء فيها؟ + +## --answers-- + +حلقة `while`. + +--- + +حلقة `for`. + +--- + +جملة `if`. + +## --video-solution-- + +2 diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md new file mode 100644 index 00000000000..81c40bc520e --- /dev/null +++ b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md @@ -0,0 +1,39 @@ +--- +id: 6ac3f76d9fd5ceb2af42aa68 +title: تنظيم البيانات باستخدام المصفوفات والقوائم في C# +challengeType: 19 +dashedName: organize-data-with-arrays-and-lists-in-c-sharp +--- + +# --description-- + +سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: + +1. انتقل إلى https://learn.microsoft.com/en-us/training/modules/csharp-arrays-lists/ وأكمل جميع المهام في وحدة "تنظيم البيانات باستخدام المصفوفات والقوائم في C#". هذا **مطلوب** للحصول على جائزة "إنشاء وتشغيل تطبيقات وحدة تحكم C# بسيطة" على Microsoft Learn، وللتأهل لاختبار الشهادة. +1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. + +# --assignment-- + +أكمل وحدة تنظيم البيانات باستخدام المصفوفات والقوائم في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. + +# --questions-- + +## --text-- + +أي طريقة تضيف عنصرًا جديدًا إلى نهاية `List`؟ + +## --answers-- + +`.Append()` + +--- + +`.Insert()` + +--- + +`.Add()` + +## --video-solution-- + +3 diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md new file mode 100644 index 00000000000..627172ba64b --- /dev/null +++ b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md @@ -0,0 +1,39 @@ +--- +id: 6ac3f7739fd5ceb2af42aa69 +title: كتابة كود قابل لإعادة الاستخدام في C# +challengeType: 19 +dashedName: write-reusable-code-in-c-sharp +--- + +# --description-- + +سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: + +1. اذهب إلى https://learn.microsoft.com/en-us/training/modules/csharp-reusable-code/ وأكمل جميع المهام في وحدة "كتابة كود قابل لإعادة الاستخدام في C#". هذا **مطلوب** للحصول على جائزة "إنشاء وتشغيل تطبيقات وحدة تحكم C# بسيطة" على Microsoft Learn، والتأهل لاختبار الشهادة. +1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. + +# --assignment-- + +أكمل وحدة كتابة كود قابل لإعادة الاستخدام في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. + +# --questions-- + +## --text-- + +ماذا يحدث إذا حاولت تخزين نتيجة استدعاء طريقة void في متغير؟ + +## --answers-- + +الكود لا يُترجم. + +--- + +يُعيّن المتغير إلى null. + +--- + +يُعيّن المتغير إلى القيمة الافتراضية لنوعه. + +## --video-solution-- + +1 diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md new file mode 100644 index 00000000000..3edab9e1538 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md @@ -0,0 +1,39 @@ +--- +id: 6ac3f77a9fd5ceb2af42aa6a +title: قراءة وكتابة الملفات في C# +challengeType: 19 +dashedName: read-and-write-files-in-c-sharp +--- + +# --description-- + +سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: + +1. انتقل إلى https://learn.microsoft.com/en-us/training/modules/csharp-read-write-files/ وأكمل جميع المهام في وحدة "قراءة وكتابة الملفات في C#". هذا **مطلوب** للحصول على جائزة "إنشاء وتشغيل تطبيقات وحدة تحكم C# بسيطة" على Microsoft Learn، والتأهل لاختبار الشهادة. +1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. + +# --assignment-- + +أكمل وحدة قراءة وكتابة الملفات في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. + +# --questions-- + +## --text-- + +ماذا تُرجع الدالة `File.ReadAllLines()`؟ + +## --answers-- + +سلسلة نصية واحدة تحتوي على كامل الملف. + +--- + +مصفوفة من السلاسل النصية، واحدة لكل سطر في الملف. + +--- + +عدد الأسطر في الملف. + +## --video-solution-- + +2 diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/681cb05adab50c87ddb2e513.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/681cb05adab50c87ddb2e513.md index a80ab786c68..87c4d096bd2 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/681cb05adab50c87ddb2e513.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/681cb05adab50c87ddb2e513.md @@ -9,11 +9,10 @@ dashedName: challenge-2 معطاة سلسلة نصية تمثل رقمًا، وقاعدة عدد صحيحة من 2 إلى 36، حدّد ما إذا كان الرقم صالحًا في تلك القاعدة. -- قد تحتوي السلسلة النصية على أعداد صحيحة، وأحرف كبيرة أو أحرف صغيرة. -- يجب أن يكون التحقق غير حساس لحالة الأحرف. -- يمكن أن تكون القاعدة أي رقم من 2 إلى 36. -- الرقم صالح إذا كان كل حرف فيه رقمًا صالحًا في القاعدة المعطاة. -- أمثلة على الأرقام الصالحة للقيَم: +- قد تحتوي السلسلة النصية على أرقام وأحرف كبيرة أو أحرف صغيرة. +- يجب أن يكون الفحص غير حساس لحالة الأحرف. +- الرقم صحيح إذا كان كل حرف فيه رقمًا صالحًا في القاعدة المعطاة. +- أمثلة على الأرقام الصالحة في قواعد مختلفة: - القاعدة 2: 0-1 - القاعدة 8: 0-7 - القاعدة 10: 0-9 @@ -118,6 +117,12 @@ assert.isTrue(isValidNumber("AbC", 16)) assert.isTrue(isValidNumber("z", 36)) ``` +`isValidNumber("", 10)` يجب أن ترجع `false`. + +```js +assert.isFalse(isValidNumber("", 10)) +``` + # --seed-- ## --seed-contents-- diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/681cb1afdab50c87ddb2e515.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/681cb1afdab50c87ddb2e515.md index cf3f28d1908..929e9172fbf 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/681cb1afdab50c87ddb2e515.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/681cb1afdab50c87ddb2e515.md @@ -37,7 +37,7 @@ assert.equal(spaceJam("Hello World?!"), "H E L L O W O R L D ? !"); assert.equal(spaceJam("C@t$ & D0g$"), "C @ T $ & D 0 G $"); ``` -`spaceJam("allyourbase")` يجب أن تُرجع `"A L L Y O U R B A S E"`. +يجب أن تُرجع الدالة `spaceJam("all your base")` القيمة `"A L L Y O U R B A S E"`. ```js assert.equal(spaceJam("all your base"), "A L L Y O U R B A S E"); diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a902958.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a902958.md index aac12168a9c..b01d3ae2e35 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a902958.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a902958.md @@ -7,7 +7,7 @@ dashedName: challenge-26 # --description-- -معطاة سلسلة نصية، حدّد إذا كانت عنوان IPv4 صالحًا. يتكون عنوان IPv4 الصالح من أربعة أعداد صحيحة مفصولة بنقاط (`.`). يجب أن يحقق كل عدد الشروط التالية: +بناءً على سلسلة نصية، حدّد ما إذا كان عنوان IPv4 صالحًا. يتكون عنوان IPv4 الصالح من أربعة أعداد صحيحة مفصولة بنقاط (`.`). يجب أن يحقق كل عدد الشروط التالية: - أن يكون بين 0 و255 شاملة. - ألا يحتوي على أصفار بادئة (مثلاً 0 مسموح، لكن 01 غير مسموح). @@ -27,6 +27,18 @@ assert.isTrue(isValidIPv4("192.168.1.1")); assert.isTrue(isValidIPv4("0.0.0.0")); ``` +يجب أن تُرجع الدالة `isValidIPv4("255.255.255.255")` القيمة `true`. + +```js +assert.isTrue(isValidIPv4("255.255.255.255")); +``` + +يجب أن تُرجع الدالة `isValidIPv4("208.67.222.222")` القيمة `true`. + +```js +assert.isTrue(isValidIPv4("208.67.222.222")); +``` + يجب أن تُرجع الدالة `isValidIPv4("255.01.50.111")` القيمة `false`. ```js @@ -57,6 +69,24 @@ assert.isFalse(isValidIPv4("192.168.101.")); assert.isFalse(isValidIPv4("192168145213")); ``` +يجب أن تُرجع الدالة `isValidIPv4("192.168.1.a")` القيمة `false`. + +```js +assert.isFalse(isValidIPv4("192.168.1.a")); +``` + +يجب أن تُرجع الدالة `isValidIPv4("192.168.o.1")` القيمة `false`. + +```js +assert.isFalse(isValidIPv4("192.168.o.1")); +``` + +يجب أن تُرجع الدالة `isValidIPv4("192.168.1.1a")` القيمة `false`. + +```js +assert.isFalse(isValidIPv4("192.168.1.1a")); +``` + # --seed-- ## --seed-contents-- diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a90295e.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a90295e.md index 7919ad4cb7f..eedccefb4c2 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a90295e.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a90295e.md @@ -7,10 +7,10 @@ dashedName: challenge-29 # --description-- -معطاة سلسلة نصية تحتوي على كلمة واحدة أو أكثر، أرجع اختصارًا للكلمات باستخدام القيود التالية: +بالنظر إلى سلسلة نصية تحتوي على كلمة واحدة أو أكثر، أرجع اختصارًا للكلمات باستخدام القيود التالية: -- يجب أن يتكون الاختصار من الحرف الأول من كل كلمة بحروف كبيرة، ما لم يُذكر خلاف ذلك. -- يجب تجاهل الحرف الأول من هذه الكلمات ما لم تكن الكلمة الأولى في السلسلة النصية المعطاة: `a`، `for`، `an`، `and`، `by`، و`of`. +- يجب أن يتكون الاختصار من الحرف الأول من كل كلمة بحرف كبير، ما لم يُذكر خلاف ذلك. +- يجب أن يتجاهل الاختصار الحرف الأول من هذه الكلمات إلا إذا كانت الكلمة الأولى في السلسلة النصية المعطاة: `a`، `for`، `an`، `and`، `by`، و`of`. - يجب إرجاع حروف الاختصار بالترتيب الذي تظهر به. - يجب ألا يحتوي الاختصار على أي فراغات. @@ -43,7 +43,7 @@ assert.equal(buildAcronym("Federal Bureau of Investigation"), "FBI"); `buildAcronym("For your information")` يجب أن تُرجع `"FYI"`. ```js -assert.equal(buildAcronym("Light Amplification by Stimulated Emission of Radiation"), "LASER"); +assert.equal(buildAcronym("For your information"), "FYI"); ``` `buildAcronym("By the way")` يجب أن تُرجع `"BTW"`. diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68af0687ef34c76c28ffa54b.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68af0687ef34c76c28ffa54b.md index dfa4098f4e3..77ba37eaa15 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68af0687ef34c76c28ffa54b.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68af0687ef34c76c28ffa54b.md @@ -7,7 +7,7 @@ dashedName: challenge-32 # --description-- -عند إعطائك سلسلة نصية من الكلمات، أعد سلسلة جديدة بالكلمات بترتيب عكسي. على سبيل المثال، يجب أن تكون الكلمة الأولى في نهاية السلسلة المعادة، والكلمة الأخيرة في بداية السلسلة المعادة. +أعطِ سلسلة نصية من الكلمات، أرجع سلسلة جديدة بالكلمات بترتيب عكسي. على سبيل المثال، يجب أن تكون الكلمة الأولى في نهاية السلسلة المعادة، والكلمة الأخيرة في بداية السلسلة المعادة. - في السلسلة المعطاة، يمكن أن تفصل الكلمات بمسافة واحدة أو أكثر. - يجب أن تحتوي السلسلة المعادة على مسافة واحدة فقط بين الكلمات. @@ -26,7 +26,7 @@ assert.equal(reverseSentence("world hello"), "hello world"); assert.equal(reverseSentence("push commit git"), "git commit push"); ``` -`reverseSentence("npm install sudo")` يجب أن تعيد `"sudo install npm"`. +يجب أن تُرجع الدالة `reverseSentence("npm install apt sudo")` القيمة `"sudo apt install npm"`. ```js assert.equal(reverseSentence("npm install apt sudo"), "sudo apt install npm"); diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68b06e589bf2273243814777.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68b06e589bf2273243814777.md index 74e85081c3f..6637ab7f718 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68b06e589bf2273243814777.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/68b06e589bf2273243814777.md @@ -7,11 +7,11 @@ dashedName: challenge-39 # --description-- -بما أن حجم خزان الوقود ومستوى الوقود الحالي وسعر الجالون معطاة، أرجع تكلفة ملء الخزان بالكامل. +بما أن حجم خزان الوقود، ومستوى الوقود الحالي، وسعر الجالون معروفة، أعد تكلفة ملء الخزان بالكامل. -- `tankSize` هو السعة الكلية للخزان بالجالونات. -- `fuelLevel` هو كمية الوقود الحالية في الخزان بالجالونات. -- `pricePerGallon` هو تكلفة جالون واحد من الوقود. +- المعلمة الأولى هي السعة الكلية للخزان بالغالونات. +- المعلمة الثانية هي كمية الوقود الحالية في الخزان بالغالونات. +- المعلمة الثالثة هي تكلفة جالون واحد من الوقود. - يجب تقريب القيمة المرجعة إلى منزلتين عشريتين بالشكل: `"$d.dd"`. # --hints-- diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/6939b873185d8e00d453563c.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/6939b873185d8e00d453563c.md index 93aae0a86f7..38188c524af 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/6939b873185d8e00d453563c.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/6939b873185d8e00d453563c.md @@ -7,9 +7,9 @@ dashedName: challenge-157 # --description-- -بالنظر إلى سلسلة نصية لرابط في Markdown، أعد السلسلة المكافئة بلغة HTML. +بالنظر إلى سلسلة نصية لرابط في Markdown، أعد السلسلة المكافئة في HTML. -صورة Markdown لها الصيغة التالية: `"[link_text](link_url)"`. أعد سلسلة وسم HTML `a` مع تعيين `href` إلى `link_url` و`link_text` كمحتوى الوسم. +رابط Markdown له التنسيق التالي: `"[link_text](link_url)"`. أرجع سلسلة وسم HTML `a` مع تعيين الخاصية `href` إلى `link_url` وكون `link_text` هو محتوى الوسم. على سبيل المثال، إذا كانت السلسلة `"[freeCodeCamp](https://freecodecamp.org/)"` فأعد `'freeCodeCamp'`; diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/69d03e549613fbdbe21d11e0.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/69d03e549613fbdbe21d11e0.md index 636bd33a08a..216e0d963e1 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/69d03e549613fbdbe21d11e0.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-javascript/69d03e549613fbdbe21d11e0.md @@ -7,12 +7,12 @@ dashedName: challenge-271 # --description-- -معطاة مصفوفة من الأدوية وسلسلة نصية تمثل الوقت الحالي، أرجع الدواء التالي الذي تحتاج إلى تناوله وكم من الوقت تبقى حتى تحتاج لتناوله. +معطاة مصفوفة من الأدوية وسلسلة نصية تمثل الوقت الحالي، أعد الدواء التالي الذي تحتاج إلى تناوله وكم من الوقت تبقى حتى تحتاج لتناوله. -- كل دواء يكون بالشكل `[name, lastTaken]`، حيث `name` هو اسم الدواء و`lastTaken` هو الوقت الذي تم تناوله فيه آخر مرة. -- كل الأوقات المعطاة ستكون بصيغة `"HH:MM"` (24 ساعة). +- يحتوي كل دواء على عنصرين: اسم الدواء، يليه الوقت الذي تم تناوله فيه آخر مرة. +- جميع الأوقات المعطاة ستكون بصيغة `"HH:MM"` (24 ساعة). -استخدم جدول مواعيد الأدوية التالي: +استخدم جدول الأدوية التالي: | الاسم | الجدول | | - | - | @@ -20,7 +20,7 @@ dashedName: challenge-271 | Debuggamanizole | 07:00، 13:00، 21:00 | | Mergeflictamine | كل 4 ساعات | -أرجع سلسلة نصية بالشكل `"{name} in Hh Mm"`. على سبيل المثال، `"Debuggamanizole in 2h 0m"` أو `"Deployxitrin in 1h 5m"`. +أعد سلسلة نصية بصيغة `"{name} in Hh Mm"`. على سبيل المثال، `"Debuggamanizole in 2h 0m"` أو `"Deployxitrin in 1h 5m"`. # --hints-- diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb05adab50c87ddb2e513.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb05adab50c87ddb2e513.md index 9b1e3ebde26..860929b99be 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb05adab50c87ddb2e513.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb05adab50c87ddb2e513.md @@ -9,16 +9,15 @@ dashedName: challenge-2 معطاة سلسلة نصية تمثل رقمًا، وقاعدة عدد صحيحة من 2 إلى 36، حدّد ما إذا كان الرقم صالحًا في تلك القاعدة. -- قد تحتوي السلسلة النصية على أعداد صحيحة، وأحرف كبيرة أو أحرف صغيرة. -- يجب أن يكون التحقق غير حساس لحالة الأحرف. -- يمكن أن تكون القاعدة أي رقم من 2 إلى 36. -- الرقم صالح إذا كان كل حرف فيه رقمًا صالحًا في القاعدة المعطاة. -- أمثلة على الأرقام الصالحة للقيَم: - - القاعدة 2: 0-1 - - القاعدة 8: 0-7 - - القاعدة 10: 0-9 - - القاعدة 16: 0-9 و A-F - - القاعدة 36: 0-9 و A-Z +- قد تحتوي السلسلة النصية على أرقام وأحرف كبيرة أو أحرف صغيرة. +- يجب أن يكون الفحص غير حساس لحالة الأحرف. +- الرقم صحيح إذا كان كل حرف فيه رقمًا صالحًا في الأساس المعطى. +- أمثلة على الأرقام الصالحة في قواعد مختلفة: + - الأساس 2: 0-1 + - الأساس 8: 0-7 + - الأساس 10: 0-9 + - الأساس 16: 0-9 و A-F + - الأساس 36: 0-9 و A-Z # --hints-- @@ -166,6 +165,15 @@ TestCase().assertIs(is_valid_number("z", 36), True)`) }}) ``` +`is_valid_number("", 10)` يجب أن ترجع `False`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_number("", 10), False)`) +}}) +``` + # --seed-- ## --seed-contents-- @@ -185,6 +193,9 @@ def is_valid_number(n, base): availableChars = allChars[0:base] + if not newN: + return False + for char in newN: if char not in availableChars: return False diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e515.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e515.md index 768b16ba0f0..cdaf0d7e008 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e515.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e515.md @@ -49,7 +49,7 @@ TestCase().assertEqual(space_jam("C@t$ & D0g$"), "C @ T $ & D 0 G $")`) }}) ``` -`space_jam("allyourbase")` يجب أن تُرجع `"A L L Y O U R B A S E"`. +يجب أن تُرجع الدالة `space_jam("all your base")` القيمة `"A L L Y O U R B A S E"`. ```js ({test: () => { runPython(` diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e517.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e517.md index 1a92a11fdf1..c013e7ede24 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e517.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e517.md @@ -13,7 +13,7 @@ dashedName: challenge-6 # --hints-- -`are_anagrams("listen", "silent")` يجب أن تُرجع `true`. +يجب أن تُرجع الدالة `are_anagrams("listen", "silent")` القيمة `True`. ```js ({test: () => { runPython(` @@ -22,7 +22,7 @@ TestCase().assertIs(are_anagrams("listen", "silent"), True)`) }}) ``` -`are_anagrams("School master", "The classroom")` يجب أن تُرجع `true`. +يجب أن تُرجع الدالة `are_anagrams("School master", "The classroom")` القيمة `True`. ```js ({test: () => { runPython(` @@ -31,7 +31,7 @@ TestCase().assertIs(are_anagrams("School master", "The classroom"), True)`) }}) ``` -`are_anagrams("A gentleman", "Elegant man")` يجب أن تُرجع `true`. +يجب أن تُرجع الدالة `are_anagrams("A gentleman", "Elegant man")` القيمة `True`. ```js ({test: () => { runPython(` @@ -40,7 +40,7 @@ TestCase().assertIs(are_anagrams("A gentleman", "Elegant man"), True)`) }}) ``` -`are_anagrams("Hello", "World")` يجب أن تُرجع `false`. +يجب أن تُرجع الدالة `are_anagrams("Hello", "World")` القيمة `False`. ```js ({test: () => { runPython(` @@ -49,7 +49,7 @@ TestCase().assertIs(are_anagrams("Hello", "World"), False)`) }}) ``` -`are_anagrams("apple", "banana")` يجب أن تُرجع `false`. +يجب أن تُرجع الدالة `are_anagrams("apple", "banana")` القيمة `False`. ```js ({test: () => { runPython(` @@ -58,7 +58,7 @@ TestCase().assertIs(are_anagrams("apple", "banana"), False)`) }}) ``` -`are_anagrams("cat", "dog")` يجب أن تُرجع `false`. +يجب أن تُرجع الدالة `are_anagrams("cat", "dog")` القيمة `False`. ```js ({test: () => { runPython(` diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68adce01c0e1144d0a902958.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68adce01c0e1144d0a902958.md index 595b84efff6..72238a92d5a 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68adce01c0e1144d0a902958.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68adce01c0e1144d0a902958.md @@ -33,6 +33,24 @@ TestCase().assertIs(is_valid_ipv4("0.0.0.0"), True)`) }}) ``` +يجب أن تُرجع الدالة `is_valid_ipv4("255.255.255.255")` القيمة `True`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("255.255.255.255"), True)`) +}}) +``` + +يجب أن تُرجع الدالة `is_valid_ipv4("208.67.222.222")` القيمة `True`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("208.67.222.222"), True)`) +}}) +``` + `is_valid_ipv4("255.01.50.111")` يجب أن تُرجع `False`. ```js @@ -78,6 +96,33 @@ TestCase().assertIs(is_valid_ipv4("192168145213"), False)`) }}) ``` +يجب أن تُرجع الدالة `is_valid_ipv4("192.168.1.a")` القيمة `False`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("192.168.1.a"), False)`) +}}) +``` + +يجب أن تُرجع الدالة `is_valid_ipv4("192.168.o.1")` القيمة `False`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("192.168.o.1"), False)`) +}}) +``` + +يجب أن تُرجع الدالة `is_valid_ipv4("192.168.1.1a")` القيمة `False`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("192.168.1.1a"), False)`) +}}) +``` + # --seed-- ## --seed-contents-- diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68b06e589bf2273243814777.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68b06e589bf2273243814777.md index 2101448a416..c395bf17e0c 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68b06e589bf2273243814777.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68b06e589bf2273243814777.md @@ -9,9 +9,9 @@ dashedName: challenge-39 بما أن حجم خزان الوقود، ومستوى الوقود الحالي، وسعر الجالون معروفة، أعد تكلفة ملء الخزان بالكامل. -- `tankSize` هو السعة الكلية للخزان بالجالونات. -- `fuelLevel` هو كمية الوقود الحالية في الخزان بالجالونات. -- `pricePerGallon` هو تكلفة جالون واحد من الوقود. +- المعلمة الأولى هي السعة الكلية للخزان بالغالونات. +- المعلمة الثانية هي كمية الوقود الحالية في الخزان بالغالونات. +- المعلمة الثالثة هي تكلفة جالون واحد من الوقود. - يجب تقريب القيمة المرجعة إلى منزلتين عشريتين بالشكل: `"$d.dd"`. # --hints-- diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68f6587287ad1f4ad39b0c7f.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68f6587287ad1f4ad39b0c7f.md index 639310fc879..2b738218b8b 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68f6587287ad1f4ad39b0c7f.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/68f6587287ad1f4ad39b0c7f.md @@ -58,7 +58,7 @@ TestCase().assertEqual(count("freeCodeCamp"), [5, 7])`) ```js ({test: () => { runPython(` from unittest import TestCase -TestCase().assertEqual(count("Hello World"), [3, 7])`) +TestCase().assertEqual(count("Hello, World!"), [3, 7])`) }}) ``` @@ -67,7 +67,7 @@ TestCase().assertEqual(count("Hello World"), [3, 7])`) ```js ({test: () => { runPython(` from unittest import TestCase -TestCase().assertEqual(count("Hello World"), [3, 7])`) +TestCase().assertEqual(count("The quick brown fox jumps over the lazy dog."), [11, 24])`) }}) ``` diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/6939b873185d8e00d453563c.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/6939b873185d8e00d453563c.md index fb773abfdd9..9da7383d425 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/6939b873185d8e00d453563c.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/6939b873185d8e00d453563c.md @@ -9,7 +9,7 @@ dashedName: challenge-157 بالنظر إلى سلسلة نصية لرابط في Markdown، أعد السلسلة المكافئة في HTML. -صورة Markdown لها الصيغة التالية: `"[link_text](link_url)"`. أعد سلسلة وسم HTML `a` مع تعيين `href` إلى `link_url` و`link_text` كمحتوى الوسم. +رابط Markdown له التنسيق التالي: `"[link_text](link_url)"`. أرجع سلسلة وسم HTML `a` مع تعيين `href` إلى `link_url` وكون `link_text` هو محتوى الوسم. على سبيل المثال، إذا كانت السلسلة `"[freeCodeCamp](https://freecodecamp.org/)"` فأعد `'freeCodeCamp'`; diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/697a49e9860d24853adef680.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/697a49e9860d24853adef680.md index d2443d4fe5b..4e7bf09f81b 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/697a49e9860d24853adef680.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/697a49e9860d24853adef680.md @@ -50,7 +50,7 @@ dashedName: challenge-195 # --hints-- -`score_curling([[".", ".", "R", ".", "."], [".", "R", ".", ".", "."], ["Y", ".", ".", ".", "."], [".", "R", ".", ".", "."], [".", ".", ".", ".", "."]])` يجب أن تُرجع `"R:2"`. +يجب أن تُرجع الدالة `score_curling([[".", ".", "R", ".", "."], [".", "R", ".", ".", "."], ["Y", ".", ".", ".", "."], [".", "R", ".", ".", "."], [".", ".", ".", ".", "."]])` القيمة `"R: 2"`. ```js ({test: () => { runPython(` diff --git a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/69d03e549613fbdbe21d11e0.md b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/69d03e549613fbdbe21d11e0.md index 8d23c16f200..82bceb2f199 100644 --- a/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/69d03e549613fbdbe21d11e0.md +++ b/curriculum/challenges/arabic/blocks/daily-coding-challenges-python/69d03e549613fbdbe21d11e0.md @@ -9,8 +9,8 @@ dashedName: challenge-271 معطاة مصفوفة من الأدوية وسلسلة نصية تمثل الوقت الحالي، أعد الدواء التالي الذي تحتاج إلى تناوله وكم من الوقت تبقى حتى تحتاج لتناوله. -- كل دواء يكون بالشكل `[name, lastTaken]`، حيث `name` هو اسم الدواء و`lastTaken` هو الوقت الذي تم تناوله فيه آخر مرة. -- كل الأوقات المعطاة ستكون بصيغة `"HH:MM"` (24 ساعة). +- يحتوي كل دواء على عنصرين: اسم الدواء، يليه الوقت الذي تم تناوله فيه آخر مرة. +- جميع الأوقات المعطاة ستكون بصيغة `"HH:MM"` (24 ساعة). استخدم جدول الأدوية التالي: diff --git a/curriculum/challenges/arabic/blocks/data-structures/587d8255367417b2b2512c73.md b/curriculum/challenges/arabic/blocks/data-structures/587d8255367417b2b2512c73.md index 0b1251cbf7b..6fef91aa3e9 100644 --- a/curriculum/challenges/arabic/blocks/data-structures/587d8255367417b2b2512c73.md +++ b/curriculum/challenges/arabic/blocks/data-structures/587d8255367417b2b2512c73.md @@ -1,6 +1,6 @@ --- id: 587d8255367417b2b2512c73 -title: استخدام معامل النشر والملاحظات لتكامل ES5 Set() +title: استخدام معامل النشر والملاحظات لتكامل ES5 Set()‎ challengeType: 1 forumTopicId: 301720 dashedName: use-spread-and-notes-for-es5-set-integration diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c37.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c37.md index 5868aaf37e3..bd3e1001666 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c37.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c37.md @@ -1,6 +1,6 @@ --- id: 587d8247367417b2b2512c37 -title: إخفاء المعلومات التي قد تكون خطيرة باستخدام helmet.hidePoweredBy() +title: إخفاء المعلومات التي قد تكون خطيرة باستخدام helmet.hidePoweredBy()‎ challengeType: 2 forumTopicId: 301580 dashedName: hide-potentially-dangerous-information-using-helmet-hidepoweredby diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c38.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c38.md index b13a1b40a3c..9b8bb7fa61d 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c38.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c38.md @@ -1,6 +1,6 @@ --- id: 587d8247367417b2b2512c38 -title: تخفيف خطر النقر الاحتيالي باستخدام helmet.frameguard() +title: تخفيف خطر النقر الاحتيالي باستخدام helmet.frameguard()‎ challengeType: 2 forumTopicId: 301582 dashedName: mitigate-the-risk-of-clickjacking-with-helmet-frameguard diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c39.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c39.md index 733c02325f5..f5a2cdff1a3 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c39.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8247367417b2b2512c39.md @@ -1,6 +1,6 @@ --- id: 587d8247367417b2b2512c39 -title: تقليل خطر هجمات البرمجة النصية عبر المواقع (XSS) باستخدام helmet.xssFilter() +title: تقليل خطر هجمات البرمجة النصية عبر المواقع (XSS) باستخدام helmet.xssFilter()‎ challengeType: 2 forumTopicId: 301583 dashedName: mitigate-the-risk-of-cross-site-scripting-xss-attacks-with-helmet-xssfilter diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3a.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3a.md index 067269f5e70..2d82523f41e 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3a.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3a.md @@ -1,6 +1,6 @@ --- id: 587d8248367417b2b2512c3a -title: تجنب استنتاج نوع MIME للاستجابة باستخدام helmet.noSniff() +title: تجنب استنتاج نوع MIME للاستجابة باستخدام helmet.noSniff()‎ challengeType: 2 forumTopicId: 301574 dashedName: avoid-inferring-the-response-mime-type-with-helmet-nosniff diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3b.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3b.md index cc7ef14e8d2..04842353353 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3b.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3b.md @@ -1,6 +1,6 @@ --- id: 587d8248367417b2b2512c3b -title: منع IE من فتح HTML غير موثوق به باستخدام helmet.ieNoOpen() +title: منع IE من فتح HTML غير موثوق به باستخدام helmet.ieNoOpen()‎ challengeType: 2 forumTopicId: 301584 dashedName: prevent-ie-from-opening-untrusted-html-with-helmet-ienoopen diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3c.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3c.md index 1a74f6239e8..1bcc3f29bb6 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3c.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3c.md @@ -1,6 +1,6 @@ --- id: 587d8248367417b2b2512c3c -title: اطلب من المتصفحات الوصول إلى موقعك عبر HTTPS فقط باستخدام helmet.hsts() +title: اطلب من المتصفحات الوصول إلى موقعك عبر HTTPS فقط باستخدام helmet.hsts()‎ challengeType: 2 forumTopicId: 301573 dashedName: ask-browsers-to-access-your-site-via-https-only-with-helmet-hsts diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3d.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3d.md index 19fae13f8da..0f248477e96 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3d.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8248367417b2b2512c3d.md @@ -1,6 +1,6 @@ --- id: 587d8248367417b2b2512c3d -title: تعطيل جلب سجلات DNS المسبق باستخدام helmet.dnsPrefetchControl() +title: تعطيل جلب سجلات DNS المسبق باستخدام helmet.dnsPrefetchControl()‎ challengeType: 2 forumTopicId: 301577 dashedName: disable-dns-prefetching-with-helmet-dnsprefetchcontrol diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c3e.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c3e.md index e0fffe80065..b228a2e8509 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c3e.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c3e.md @@ -1,6 +1,6 @@ --- id: 587d8249367417b2b2512c3e -title: تعطيل التخزين المؤقت على جانب العميل باستخدام helmet.noCache() +title: تعطيل التخزين المؤقت على جانب العميل باستخدام helmet.noCache()‎ challengeType: 2 forumTopicId: 301576 dashedName: disable-client-side-caching-with-helmet-nocache diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c3f.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c3f.md index 28e26efff3f..38ee858b568 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c3f.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c3f.md @@ -1,6 +1,6 @@ --- id: 587d8249367417b2b2512c3f -title: تعيين سياسة أمان المحتوى باستخدام helmet.contentSecurityPolicy() +title: تعيين سياسة أمان المحتوى باستخدام helmet.contentSecurityPolicy()‎ challengeType: 2 forumTopicId: 301585 dashedName: set-a-content-security-policy-with-helmet-contentsecuritypolicy diff --git a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c40.md b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c40.md index cb047cc1b9a..a58943356ab 100644 --- a/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c40.md +++ b/curriculum/challenges/arabic/blocks/information-security-with-helmetjs/587d8249367417b2b2512c40.md @@ -1,6 +1,6 @@ --- id: 587d8249367417b2b2512c40 -title: "تهيئة Helmet باستخدام البرمجيات الوسيطة ‘parent’ helmet()" +title: "تهيئة Helmet باستخدام البرمجيات الوسيطة ‘parent’ helmet()‎" challengeType: 2 forumTopicId: 301575 dashedName: configure-helmet-using-the-parent-helmet-middleware diff --git a/curriculum/challenges/arabic/blocks/lab-business-card/6690e10ebe2181212abc9652.md b/curriculum/challenges/arabic/blocks/lab-business-card/6690e10ebe2181212abc9652.md index b0a25722b3c..7de090e1744 100644 --- a/curriculum/challenges/arabic/blocks/lab-business-card/6690e10ebe2181212abc9652.md +++ b/curriculum/challenges/arabic/blocks/lab-business-card/6690e10ebe2181212abc9652.md @@ -102,13 +102,15 @@ assert.exists(document.querySelector('p.company + hr')); بعد أول عنصر `hr`، يجب أن يكون هناك عنصر `p` يحتوي على عنوان بريد إلكتروني كنص. ```js -assert.isNotEmpty(document.querySelectorAll('.business-card hr + p')[0].textContent.trim()); +assert.isNotEmpty(document.querySelectorAll('.business-card hr + p')[0]?.textContent.trim()); ``` بعد عنصر `p` الخاص بالبريد الإلكتروني، يجب أن يكون هناك عنصر `p` آخر يحتوي على رقم هاتف كنص. ```js -assert.match(document.querySelectorAll(".business-card p")[4].textContent,/.+/); +const phoneParagraph = document.querySelectorAll(".business-card p")[4]; +assert.exists(phoneParagraph); +assert.match(phoneParagraph.textContent, /.+/); ``` بعد عنصر `p` الخاص برقم الهاتف، يجب أن يكون هناك عنصر `a` مع صنف `portfolio-link`. @@ -120,13 +122,13 @@ assert.exists(document.querySelector('a.portfolio-link')); يجب أن يحتوي عنصر `.portfolio-link` على نص `Portfolio`. ```js -assert.equal(document.querySelector('a.portfolio-link').textContent.trim(), 'Portfolio'); +assert.equal(document.querySelector('a.portfolio-link')?.textContent.trim(), 'Portfolio'); ``` يجب أن يحتوي عنصر `.portfolio-link` على خاصية `href` صالحة. ```js -assert.isAbove(document.querySelector('.portfolio-link').getAttribute('href').length, 0); +assert.isAbove(document.querySelector('.portfolio-link')?.getAttribute('href')?.length, 0); ``` بعد عنصر `a` الذي يحتوي على معرض الأعمال، يجب أن يكون هناك عنصر `hr` آخر كفاصل. @@ -211,19 +213,25 @@ const linkHrefValue = document.querySelector('link')?.dataset?.href; assert.strictEqual(linkHrefValue, 'styles.css'); ``` -يجب تعيين لون خلفية الصفحة في محدد `body` إلى `rosybrown`. +يجب أن يكون خلفية الصفحة لديك بلون `rosybrown`. ```js -assert.strictEqual(new __helpers.CSSHelp(document).getStyle('body')?.getPropVal('background-color'), 'rosybrown'); +const transparent = ['rgba(0, 0, 0, 0)', 'transparent']; +const htmlBackground = getComputedStyle(document.documentElement).backgroundColor; +const bodyBackground = getComputedStyle(document.body).backgroundColor; +const pageBackground = transparent.includes(htmlBackground) ? bodyBackground : htmlBackground; +assert.strictEqual(pageBackground, 'rgb(188, 143, 143)'); ``` -يجب تعيين خط الصفحة إلى `Arial` في عنصر `body` مع نظام بديل `sans-serif`. +يجب أن يكون الخط العام للصفحة لديك `Arial`، مع النظام البديل `sans-serif`. ```js -const el = new __helpers.CSSHelp(document).getStyle('body')?.getPropVal('font-family'); -const condition1= el === 'Arial, sans-serif'; -const condition2= el === '"Arial", sans-serif'; -assert.isTrue(condition1 || condition2); +const elements = [...document.body.querySelectorAll('*')]; +assert.isNotEmpty(elements); +for (const element of elements) { + const fontFamily = getComputedStyle(element).fontFamily.replace(/["']/g, ''); + assert.match(fontFamily, /^Arial,\s*sans-serif$/i); +} ``` يجب أن يحتوي محدد `.business-card` على خاصية `width` بقيمة `300px`. @@ -278,17 +286,23 @@ assert.equal(new __helpers.CSSHelp(document).getStyle('.profile-image')?.getProp يجب أن يكون لعناصر `p` لديك هامش `margin` علوي وسفلي بمقدار `5px`. ```js -const marginTop = new __helpers.CSSHelp(document).getStyle('p')?.getPropVal('margin-top'); -const marginBottom = new __helpers.CSSHelp(document).getStyle('p')?.getPropVal('margin-bottom'); - -assert.equal(marginTop, '5px'); -assert.equal(marginBottom, '5px'); +const paragraphs = [...document.querySelectorAll('p')]; +assert.isNotEmpty(paragraphs); +for (const paragraph of paragraphs) { + const { marginTop, marginBottom } = getComputedStyle(paragraph); + assert.strictEqual(marginTop, '5px'); + assert.strictEqual(marginBottom, '5px'); +} ``` يجب ألا تحتوي روابط الصفحة على خط تحت النص. ```js -assert.equal(new __helpers.CSSHelp(document).getStyle('a')?.getPropVal('text-decoration'), 'none'); +const links = [...document.querySelectorAll('a')]; +assert.isNotEmpty(links); +for (const link of links) { + assert.strictEqual(getComputedStyle(link).textDecorationLine, 'none'); +} ``` # --seed-- diff --git a/curriculum/challenges/arabic/blocks/lab-device-loan-ledger/69f0a37c3bf194a7c9c62492.md b/curriculum/challenges/arabic/blocks/lab-device-loan-ledger/69f0a37c3bf194a7c9c62492.md index 4802e9df7f5..c8de370aefd 100644 --- a/curriculum/challenges/arabic/blocks/lab-device-loan-ledger/69f0a37c3bf194a7c9c62492.md +++ b/curriculum/challenges/arabic/blocks/lab-device-loan-ledger/69f0a37c3bf194a7c9c62492.md @@ -29,12 +29,12 @@ const ledger = { 1. يجب أن تمثل السجل ككائن حيث يُفهرس كل جهاز بواسطة وسم الأصل الخاص به ويحتوي على خصائص `type` و`status` و`borrower` (مع `name` و`email`) و`dueDate`. -1. يجب أن تنفذ دالة `checkoutDevice(ledger, assetTag, borrower)` التي تأخذ كائن السجل وتنسخه دون تعديل الأصلي. على النسخة، يجب أن تضبط `name` و`email` في كائن `borrower`، وتحدث `status` إلى `"CheckedOut"`، وترجع كائنًا بالشكل `{ ledger: updatedLedger, message: confirmationString }`، حيث تتضمن `message` وسم الأصل و`name` في كائن `borrower`. +1. يجب تنفيذ دالة باسم `checkoutDevice(ledger, assetTag, borrower)` تستقبل كائن ledger وتقوم باستنساخه باستخدام `serializeLedger` و`loadLedger` دون تعديل الأصل. في النسخة المستنسخة، يجب تعيين خاصيتي `name` و`email` في كائن `borrower`، وتحديث `status` إلى `"CheckedOut"`. ثم تُرجع كائنًا بالشكل `{ ledger: updatedLedger, message: confirmationString }`، حيث يحتوي `message` على وسم الأصل وكائن `borrower` وخاصية `name`. - إذا لم يكن `assetTag` موجودًا في السجل، يجب أن تُرجع الدالة السجل دون تغيير مع `message` تتضمن وسم الأصل وتوضح أنه لم يُعثر عليه. - إذا كان الجهاز بالفعل في حالة `"CheckedOut"`، يجب أن تُرجع الدالة السجل دون تغيير وتترك المستعير الحالي كما هو، مع `message` تتضمن وسم الأصل وتوضح أن الجهاز مُستعار بالفعل. -1. يجب أن تنفذ دالة `checkinDevice(ledger, assetTag)` التي تأخذ كائن السجل وتنسخه دون تعديل الأصلي. على النسخة، يجب أن تمسح `name` و`email` في كائن `borrower`، تعيد تعيين `dueDate` إلى `""`، تحدث `status` إلى `"CheckedIn"`، وترجع كائنًا بالشكل `{ ledger: updatedLedger, message: confirmationString }`، حيث تتضمن `message` وسم الأصل. +1. يجب تنفيذ دالة `checkinDevice(ledger, assetTag)` التي تستقبل كائن ledger وتنسخه باستخدام `serializeLedger` و`loadLedger`، دون تعديل الكائن الأصلي. على النسخة، يجب مسح خاصيتي `name` و`email` في كائن `borrower`، إعادة تعيين `dueDate` إلى `""`، تحديث `status` إلى `"CheckedIn"`، وإرجاع كائن بالشكل `{ ledger: updatedLedger, message: confirmationString }`، حيث تتضمن الخاصية `message` وسم الأصل. - إذا لم يكن `assetTag` موجودًا في السجل، يجب أن تُرجع الدالة السجل دون تغيير مع `message` تتضمن وسم الأصل وتشرح أنه لم يتم العثور عليه. @@ -87,6 +87,14 @@ checkoutDevice(ledger, "1", { name: "Alice", email: "alice@test.com" }); assert.deepEqual(ledger, original); ``` +يجب أن تستخدم دالة `checkoutDevice` دالتي `serializeLedger` و`loadLedger` لنسخ ledger. + +```js +const source = __helpers.removeJSComments(checkoutDevice.toString()); +assert.match(source, /\bserializeLedger\s*\(/); +assert.match(source, /\bloadLedger\s*\(/); +``` + يجب أن تضبط دالة `checkoutDevice` `name` و`email` للمستعير، وتضبط `status` إلى `"CheckedOut"`. ```js @@ -161,6 +169,14 @@ checkinDevice(ledger, "1"); assert.deepEqual(ledger, original); ``` +يجب أن تستخدم دالة `checkinDevice` دالتي `serializeLedger` و`loadLedger` لنسخ ledger. + +```js +const source = __helpers.removeJSComments(checkinDevice.toString()); +assert.match(source, /\bserializeLedger\s*\(/); +assert.match(source, /\bloadLedger\s*\(/); +``` + يجب أن تمسح دالة `checkinDevice` `name` و`email` للمستعير، تعيد تعيين `dueDate` إلى `""`، وتضبط `status` إلى `"CheckedIn"`. ```js @@ -313,7 +329,7 @@ function loadLedger(json) { } function checkoutDevice(ledger, assetTag, borrower) { - const updatedLedger = JSON.parse(JSON.stringify(ledger)); + const updatedLedger = loadLedger(serializeLedger(ledger)); if (!updatedLedger[assetTag]) { return { @@ -337,7 +353,7 @@ function checkoutDevice(ledger, assetTag, borrower) { } function checkinDevice(ledger, assetTag) { - const updatedLedger = JSON.parse(JSON.stringify(ledger)); + const updatedLedger = loadLedger(serializeLedger(ledger)); if (!updatedLedger[assetTag]) { return { diff --git a/curriculum/challenges/arabic/blocks/lab-implement-a-stack/69a92f0b9cc04bb0d5327bb5.md b/curriculum/challenges/arabic/blocks/lab-implement-a-stack/69a92f0b9cc04bb0d5327bb5.md index 079685dcfe0..6925f35aaa7 100644 --- a/curriculum/challenges/arabic/blocks/lab-implement-a-stack/69a92f0b9cc04bb0d5327bb5.md +++ b/curriculum/challenges/arabic/blocks/lab-implement-a-stack/69a92f0b9cc04bb0d5327bb5.md @@ -9,16 +9,16 @@ dashedName: implement-a-stack في هذا المختبر، ستنفذ هيكل بيانات المكدس باستخدام الدوال. المكدس هو هيكل بيانات من نوع آخر يدخل أولاً يخرج أخيراً (LIFO)، حيث تُضاف العناصر وتُزال من الأعلى. -**الهدف:** حقق قصص المستخدم أدناه واجعل جميع الاختبارات تجتاز لإكمال المختبر. +**الهدف:** إكمال قصص المستخدم أدناه واجتياز جميع الاختبارات لإتمام المختبر. **قصص المستخدم:** -1. يجب أن يكون لديك دالة `initStack` تُرجع كائنًا يحتوي على خاصية `collection` مضبوطة على مصفوفة فارغة. -1. يجب أن يكون لديك دالة `push` تضيف عنصرًا إلى أعلى المكدس. -1. يجب أن يكون لديك دالة `pop` تزيل وتُرجع العنصر الأعلى من المكدس، أو `undefined` إذا لم يكن هناك عنصر. -1. يجب أن يكون لديك دالة `peek` تُرجع العنصر الأعلى من المكدس دون إزالته، أو `undefined` إذا لم يكن هناك عنصر. -1. يجب أن يكون لديك دالة `isEmpty` تُرجع `true` إذا كان المكدس لا يحتوي على عناصر، و`false` خلاف ذلك. -1. يجب أن يكون لديك دالة `clear` تزيل جميع العناصر من المكدس. +1. يجب أن تملك دالة `initStack` تُرجع كائنًا يحتوي على خاصية `collection` مضبوطة على مصفوفة فارغة. العنصر الأخير في `collection` يمثل قمة المكدس. +1. يجب أن تملك دالة `push` تأخذ كائن المكدس وعنصرًا كمعلمات، وتضيف العنصر إلى قمة المكدس بوضعه في نهاية `collection` الخاصة بالمكدس. +1. يجب أن تملك دالة `pop` تأخذ كائن المكدس كمعلمة، وتزيل وتُرجع العنصر الأعلى في المكدس، أو `undefined` إذا لم يكن هناك عنصر. +1. يجب أن تملك دالة `peek` تأخذ كائن المكدس كمعلمة، وتُرجع العنصر الأعلى في المكدس دون إزالته، أو `undefined` إذا لم يكن هناك عنصر. +1. يجب أن تملك دالة `isEmpty` تأخذ كائن المكدس كمعلمة، وتُرجع `true` إذا كان المكدس لا يحتوي على عناصر، و`false` خلاف ذلك. +1. يجب أن تملك دالة `clear` تأخذ كائن المكدس كمعلمة، وتزيل جميع العناصر من `collection` الخاصة بالمكدس. **ملاحظة:** تعتمد معظم الاختبارات على دالتي `initStack` و`push`. نفذهما أولاً، إذ تتطلب اختبارات `pop` و`peek` و`isEmpty` و`clear` إضافة عناصر إلى المكدس. @@ -30,7 +30,7 @@ dashedName: implement-a-stack assert.isFunction(push); ``` -يجب أن تضيف دالة `push` عنصرًا إلى أعلى المكدس. +يجب أن تضيف دالة `push` عنصرًا إلى قمة المكدس. ```js const stack = initStack(); @@ -45,7 +45,7 @@ assert.deepEqual(stack.collection, ['first', 'second']); assert.isFunction(pop); ``` -يجب أن تزيل دالة `pop` العنصر الأعلى من المكدس وتُرجعه. +يجب أن تزيل دالة `pop` العنصر الأعلى في المكدس وتُرجعه. ```js const stack = initStack(); @@ -53,7 +53,9 @@ push(stack, 'first'); push(stack, 'second'); push(stack, 'third'); assert.strictEqual(pop(stack), 'third'); +assert.deepEqual(stack.collection, ['first', 'second']); assert.strictEqual(pop(stack), 'second'); +assert.deepEqual(stack.collection, ['first']); ``` يجب أن تُرجع دالة `pop` القيمة `undefined` إذا كان المكدس فارغًا. @@ -78,7 +80,7 @@ assert.lengthOf(stack.collection, 0); assert.isFunction(peek); ``` -يجب أن تُرجع دالة `peek` العنصر الأعلى من المكدس دون إزالته. +يجب أن تُرجع دالة `peek` العنصر الأعلى في المكدس دون إزالته. ```js const stack = initStack(); @@ -86,6 +88,7 @@ push(stack, 'first'); push(stack, 'second'); assert.strictEqual(peek(stack), 'second'); assert.strictEqual(peek(stack), 'second'); +assert.deepEqual(stack.collection, ['first', 'second']); ``` يجب أن تُرجع دالة `peek` القيمة `undefined` إذا كان المكدس فارغًا. @@ -132,7 +135,7 @@ push(stack, false); assert.isFalse(isEmpty(stack)); ``` -يجب أن يكون لديك دالة `clear`. +يجب أن تملك دالة `clear`. ```js assert.isFunction(clear); diff --git a/curriculum/challenges/arabic/blocks/lab-isbn-validator/686b9720ee1d032bd77a480a.md b/curriculum/challenges/arabic/blocks/lab-isbn-validator/686b9720ee1d032bd77a480a.md index ee9b08f3809..bb5543de68d 100644 --- a/curriculum/challenges/arabic/blocks/lab-isbn-validator/686b9720ee1d032bd77a480a.md +++ b/curriculum/challenges/arabic/blocks/lab-isbn-validator/686b9720ee1d032bd77a480a.md @@ -7,14 +7,14 @@ dashedName: debug-an-isbn-validator # --description-- -رقم الكتاب المعياري الدولي (ISBN) هو معرف فريد يُعيَّن للكتب التجارية. يمكن أن يكون طوله 10 أو 13 رقمًا، والرقم الأخير هو رقم تحقق يُحسب من الأرقام الأخرى. +رقم الكتاب المعياري الدولي (ISBN) هو معرف فريد يُعيَّن للكتب التجارية. يتكون من 10 أو 13 حرفًا. الحرف الأخير هو رقم تحقق يُحسب من الأرقام التي تسبقه، والمعروفة بالأرقام الرئيسية. حاول Camperbot بناء مدقق ISBN خاص به. مع ذلك، ارتكب بعض الأخطاء على طول الطريق. في هذا المختبر، ستصلح الكود الموجود وتجعلها تعمل بشكل صحيح. السلوك المتوقع: -عندما يشغل المستخدم البرنامج، سيظهر له الموجه `Enter ISBN and length: `. يمكن للمستخدم إدخال رمز ISBN الذي يريد التحقق منه بصيغة `ISBN,length`. يجب ألا يحتوي رمز ISBN على شرطات، يليه طوله (`10` أو `13`)، مفصولًا بفاصلة. +عند تشغيل البرنامج، سيظهر الموجه `Enter ISBN and length: `. يمكن للمستخدم إدخال كود ISBN الذي يريد التحقق منه بصيغة `ISBN,length`. أدخل ISBN بدون شرطات، متبوعًا بفاصلة وطوله (`10` أو `13`). أمثلة على المدخلات: `1530051126,10` لرموز ISBN-10. @@ -22,26 +22,29 @@ dashedName: debug-an-isbn-validator كيفية إيجاد رقم التحقق: -- لا تحتاج إلى معرفة منطق الحساب التفصيلي في هذا المختبر. الدالتان `calculate_check_digit_10` و `calculate_check_digit_13` ستتوليان الحساب وترجعان رقم التحقق المتوقع كسلسلة نصية. -- رقم التحقق لرموز ISBN-10 يمكن أن يكون رقمًا من `0` إلى `9` أو الحرف الكبير `X`. -- رقم التحقق لرموز ISBN-13 يمكن أن يكون رقمًا من `0` إلى `9`. +- الأرقام الرئيسية هي أول 9 أرقام من كود ISBN-10، أو أول 12 رقمًا من كود ISBN-13. يجب أن تكون كلها أرقام. +- الحرف الأخير هو رقم التحقق المعطى. يُحسب رقم التحقق المتوقع من الأرقام الرئيسية، ويكون كود ISBN صالحًا فقط إذا تطابقا. +- على سبيل المثال، في كود ISBN-10 `1530051126`، الأرقام الرئيسية هي `153005112` ورقم التحقق المعطى هو `6`. في كود ISBN-13 `9781530051120`، الأرقام الرئيسية هي `978153005112` ورقم التحقق المعطى هو `0`. +- لا تحتاج إلى معرفة منطق الحساب التفصيلي في هذا المختبر. الدالتان `calculate_check_digit_10` و `calculate_check_digit_13` تتكفلان بالحساب وترجعان رقم التحقق المتوقع كسلسلة نصية. +- رقم التحقق في أكواد ISBN-10 يمكن أن يكون رقمًا من `0` إلى `9` أو الحرف الكبير `X`. +- رقم التحقق في أكواد ISBN-13 يمكن أن يكون رقمًا من `0` إلى `9`. **الهدف:** إكمال قصص المستخدم أدناه واجتياز جميع الاختبارات لإتمام المختبر. **قصص المستخدم:** 1. يجب إصلاح `IndentationError` في الكود الحالي. -1. حتى إذا لم يُدخل المستخدم قيمة مفصولة بفاصلة، يجب على البرنامج التعامل مع `IndexError` دون تعطل. -1. عندما لا يُدخل المستخدم قيمة مفصولة بفاصلة، يجب أن يرى رسالة `Enter comma-separated values.` في وحدة التحكم، وينهي البرنامج. +1. حتى إذا لم يدخل المستخدم قيمًا مفصولة بفواصل، يجب على البرنامج التعامل مع `IndexError` دون تعطل. +1. عندما لا يدخل المستخدم قيمًا مفصولة بفواصل، يجب أن يرى الرسالة `Enter comma-separated values.` في وحدة التحكم، وينهي البرنامج. 1. حتى إذا أدخل المستخدم قيمة غير رقمية للطول، يجب على البرنامج التعامل مع `ValueError` دون تعطل. -1. عندما يُدخل المستخدم قيمة غير رقمية للطول، يجب أن يرى رسالة `Length must be a number.` في وحدة التحكم، وينهي البرنامج. +1. عندما يدخل المستخدم قيمة غير رقمية للطول، يجب أن يرى الرسالة `Length must be a number.` في وحدة التحكم، وينهي البرنامج. 1. يجب إصلاح خطأ بمقدار واحد في دالة `validate_isbn`. -1. يجب إصلاح `TypeError` في الكود الحالي الذي يحدث عندما يُدخل المستخدم كود ISBN صالح. -1. يجب إصلاح `IndexError` في الكود الحالي عندما يُدخل المستخدم كود ISBN صالح. -1. حتى إذا أدخل المستخدم كود ISBN غير صحيح يحتوي على حروف غير أرقام، يجب على البرنامج التعامل مع `ValueError` التي تحدث دون تعطل. -1. عندما يُدخل المستخدم كود ISBN غير صحيح يحتوي على حروف غير أرقام، يجب أن يرى رسالة `Invalid character was found.` في وحدة التحكم. -1. عندما يُدخل المستخدم `1530051126,10`، يجب أن يرى رسالة `Valid ISBN Code.` -1. عندما يُدخل المستخدم `9781530051120,13`، يجب أن يرى رسالة `Valid ISBN Code.` +1. يجب إصلاح `TypeError` في الكود الحالي الذي يحدث عند إدخال كود ISBN صالح. +1. يجب إصلاح `IndexError` في الكود الحالي عند إدخال كود ISBN صالح. +1. حتى إذا أدخل المستخدم كود ISBN غير صحيح يحتوي على أحرف غير رقمية في الأرقام الرئيسية، يجب على البرنامج التعامل مع `ValueError` دون تعطل. +1. عندما يدخل المستخدم كود ISBN غير صحيح يحتوي على أحرف غير رقمية في الأرقام الرئيسية، يجب أن يرى الرسالة `Invalid character was found.` في وحدة التحكم. +1. عند إدخال `1530051126,10`، يجب أن يرى المستخدم الرسالة `Valid ISBN Code.` +1. عند إدخال `9781530051120,13`، يجب أن يرى المستخدم الرسالة `Valid ISBN Code.` **مهم**: ستحتاج إلى إضافة تعليق على استدعاء `main()` في النطاق العام لكي تعمل الاختبارات بشكل صحيح. @@ -51,10 +54,10 @@ dashedName: debug-an-isbn-validator |-----------|--------|---------| ------------- | | صالح | صالح | `Valid ISBN Code.` | `1530051126,10` | | رقم غير صالح | صالح | `Invalid ISBN Code.` | `1530051125,10` | -| لا يطابق الطول المحدد أو ترك فارغًا | صالح | `ISBN-10 code should be 10 digits long.` أو `ISBN-13 code should be 13 digits long.`، حسب الطول الذي أدخله المستخدم. | `9781530051120,10` أو `1530051126,13` | -| يحتوي على أحرف غير رقمية (باستثناء رقم التحقق) | صالح | `Invalid character was found.` | `15-0051126,10` | +| لا يتطابق مع الطول المحدد أو ترك فارغًا | صالح | `ISBN-10 code should be 10 digits long.` أو `ISBN-13 code should be 13 digits long.`، حسب الطول الذي أدخلته. | `9781530051120,10` أو `1530051126,13` | +| يحتوي على حروف غير رقمية في الأرقام الرئيسية | صالح | `Invalid character was found.` | `15-0051126,10` | | أي | رقم غير صالح | `Length should be 10 or 13.` | `1530051126,9` | -| أي | يحتوي على أحرف غير رقمية أو ترك فارغًا | `Length must be a number.` | `1530051125,A` | +| أي | يحتوي على حروف غير رقمية أو ترك فارغًا | `Length must be a number.` | `1530051125,A` | | غير مفصول بفاصلة | غير مفصول بفاصلة | `Enter comma-separated values.` | `1530051125` | يمكنك استخدام القيم التالية لاختبار الكود يدويًا إذا أردت. @@ -110,7 +113,7 @@ dashedName: debug-an-isbn-validator }) ``` -عندما يدخل المستخدم قيمة غير مفصولة بفاصلة، يجب أن ترى الرسالة `Enter comma-separated values.` في وحدة التحكم. +عندما يدخل المستخدم قيمًا غير مفصولة بفواصل، يجب أن ترى الرسالة `Enter comma-separated values.` في وحدة التحكم. ```js ({test: () => {runPython(` @@ -163,7 +166,7 @@ assert "Length must be a number." in out }}) ``` -عندما يدخل المستخدم رمز ISBN غير صحيح يحتوي على حروف غير أرقام، يجب أن ترى الرسالة `Invalid character was found.` في وحدة التحكم. +عندما يدخل المستخدم كود ISBN غير صحيح يحتوي على أحرف غير رقمية في الأرقام الرئيسية، يجب أن ترى الرسالة `Invalid character was found.` في وحدة التحكم. ```js ({test: () => {runPython(` @@ -244,7 +247,7 @@ assert "Valid ISBN Code." in out }}) ``` -عندما يدخل المستخدم `1530051125,10`، يجب أن ترى الرسالة `Invalid ISBN Code.`. +عندما يدخل المستخدم `1530051125,10`، يجب أن ترى الرسالة `Invalid ISBN Code.` ```js ({test: () => {runPython(` diff --git a/curriculum/challenges/arabic/blocks/lab-leap-year-calculator/66c06fad3475cd92421b9ac2.md b/curriculum/challenges/arabic/blocks/lab-leap-year-calculator/66c06fad3475cd92421b9ac2.md index 197b1e61193..e86d4f20675 100644 --- a/curriculum/challenges/arabic/blocks/lab-leap-year-calculator/66c06fad3475cd92421b9ac2.md +++ b/curriculum/challenges/arabic/blocks/lab-leap-year-calculator/66c06fad3475cd92421b9ac2.md @@ -9,7 +9,7 @@ dashedName: build-a-leap-year-calculator السنة الكبيسة هي السنة التي تقبل القسمة على `4`، باستثناء السنوات التي تقبل القسمة على `100` ولا تقبل القسمة على `400`. على سبيل المثال، `2000` سنة كبيسة، لكن `1900` ليست كذلك. أيضًا، تحتوي السنة الكبيسة على يوم إضافي في فبراير، وهو اليوم التاسع والعشرون من الشهر. -**الهدف:** نفذ قصص المستخدم أدناه واجعل جميع الاختبارات تنجح لإكمال المختبر. +**الهدف:** إكمال قصص المستخدم أدناه واجتياز جميع الاختبارات لإتمام المختبر. **قصص المستخدم:** @@ -22,9 +22,9 @@ dashedName: build-a-leap-year-calculator - إلا إذا كانت السنة تقبل القسمة أيضًا على `100`، فهي ليست سنة كبيسة. - إلا إذا كانت السنة تقبل القسمة أيضًا على `400`، فهي سنة كبيسة. -5. إذا كانت السنة كبيسة، أرجع `[year] is a leap year.`. وإلا، أرجع `[year] is not a leap year.`. ستستبدل `[year]` بالمعلمة المعرفة في دالة `isLeapYear`. -6. يجب استدعاء دالة `isLeapYear` مع `year` كمعلمة وتعيين النتيجة إلى متغير باسم `result`. -7. يجب إخراج متغير `result` إلى وحدة التحكم باستخدام `console.log()`. +5. إذا كان العام سنة كبيسة، أرجع `[year] is a leap year.`. وإلا، أرجع `[year] is not a leap year.`. ستستبدل `[year]` بالمعلمة المعرفة في دالة `isLeapYear`. +6. يجب إعلان متغير باسم `result` وتعيين القيمة التي تُرجع من استدعاء دالة `isLeapYear` مع `year` كمعلمة. +7. يجب إخراج المتغير `result` إلى وحدة التحكم باستخدام `console.log()`. # --hints-- @@ -74,10 +74,16 @@ assert.strictEqual(isLeapYear(1900), '1900 is not a leap year.'); ``` +مع تعيين `1901` كقيمة للمتغير `year`، يجب أن تكون القيمة في `result` هي `1901 is not a leap year.` + +```js +assert.strictEqual(isLeapYear(1901), '1901 is not a leap year.'); +``` + يجب استدعاء دالة `isLeapYear` وتمرير `year` كمعلمة. ```js -assert.match(__helpers.removeJSComments(code), /isLeapYear\(\s*year\s*\)/); +assert.match(__helpers.removeJSComments(code), /isLeapYear\s*\(\s*year\s*\)/); ``` يجب إعلان متغير `result`. @@ -86,16 +92,19 @@ assert.match(__helpers.removeJSComments(code), /isLeapYear\(\s*year\s*\)/); assert.isDefined(result); ``` -يجب تخزين نتيجة استدعاء دالة `isLeapYear` في متغير باسم `result`. +يجب إعلان متغير باسم `result` وتعيين القيمة التي تُرجع من استدعاء دالة `isLeapYear` مع `year`. ```js -assert.match(__helpers.removeJSComments(code), /result\s*=\s*isLeapYear\(\s*year\s*\)/); +const explorer = await __helpers.Explorer(code); +const { result } = explorer.variables; +assert.exists(result); +assert.isTrue(result.value.matches('isLeapYear(year)')); ``` يجب إخراج `result` إلى وحدة التحكم باستخدام `console.log()`. ```js -assert.match(__helpers.removeJSComments(code), /console\.log\(\s*result\s*\)/); +assert.match(__helpers.removeJSComments(code), /console\s*\.\s*log\s*\(\s*result\s*\)/); ``` # --seed-- diff --git a/curriculum/challenges/arabic/blocks/lab-number-pattern-generator/6842a6cd9836f0114a5b7a8a.md b/curriculum/challenges/arabic/blocks/lab-number-pattern-generator/6842a6cd9836f0114a5b7a8a.md index 469d37e61e5..a14f08751cf 100644 --- a/curriculum/challenges/arabic/blocks/lab-number-pattern-generator/6842a6cd9836f0114a5b7a8a.md +++ b/curriculum/challenges/arabic/blocks/lab-number-pattern-generator/6842a6cd9836f0114a5b7a8a.md @@ -9,15 +9,15 @@ dashedName: build-a-number-pattern-generator في هذا المختبر ستتدرب على أساسيات Python ببناء تطبيق صغير يُنشئ نمط أرقام. -**الهدف:** حقق قصص المستخدم أدناه واجعل جميع الاختبارات تنجح لإكمال المختبر. +**الهدف:** إكمال قصص المستخدم أدناه واجتياز جميع الاختبارات لإتمام المختبر. **قصص المستخدم:** -1. يجب أن تعرف دالة باسم `number_pattern` تأخذ معلمة واحدة `n` (تمثل عددًا صحيحًا موجبًا). +1. عرّف دالة باسم `number_pattern` تأخذ معلمة واحدة `n` (تمثل عددًا صحيحًا موجبًا). 1. يجب أن تستخدم `number_pattern` حلقة `for`. -1. يجب أن تُرجع `number_pattern(n)` سلسلة نصية تحتوي كل الأعداد الصحيحة بدءًا من 1 حتى `n` (شاملة) مفصولة بمسافة. على سبيل المثال، يجب أن تُرجع `number_pattern(4)` السلسلة النصية `1 2 3 4`. -1. إذا كانت المعلمة الممررة إلى الدالة ليست قيمة عدد صحيح، يجب أن تُرجع الدالة `Argument must be an integer value.` -1. إذا كانت المعلمة الممررة إلى الدالة أقل من 1، يجب أن تُرجع الدالة `Argument must be an integer greater than 0.` +1. يجب أن ترجع `number_pattern(n)` سلسلة نصية تحتوي على جميع الأعداد الصحيحة من 1 إلى `n`، شاملة، مفصولة بمسافات. على سبيل المثال، يجب أن ترجع `number_pattern(4)` السلسلة النصية `1 2 3 4`. +1. إذا كانت المعلمة الممررة إلى الدالة ليست قيمة عدد صحيح، يجب أن ترجع الدالة `Argument must be an integer value.` +1. إذا كانت المعلمة الممررة إلى الدالة أقل من 1، يجب أن ترجع الدالة `Argument must be an integer greater than 0.` # --hints-- @@ -61,7 +61,7 @@ dashedName: build-a-number-pattern-generator }) ``` -يجب أن تُرجع `number_pattern` قائمة أرقام مفصولة بمسافة لأي عدد صحيح موجب. +يجب أن ترجع `number_pattern` قائمة أرقام مفصولة بمسافات لأي عدد صحيح موجب. ```js ({ diff --git a/curriculum/challenges/arabic/blocks/lab-rpg-character/67d83df6f82eda3868dd2a84.md b/curriculum/challenges/arabic/blocks/lab-rpg-character/67d83df6f82eda3868dd2a84.md index 7076c7dbbeb..31d08b6d88e 100644 --- a/curriculum/challenges/arabic/blocks/lab-rpg-character/67d83df6f82eda3868dd2a84.md +++ b/curriculum/challenges/arabic/blocks/lab-rpg-character/67d83df6f82eda3868dd2a84.md @@ -9,25 +9,25 @@ dashedName: build-an-rpg-character في هذا المختبر ستتمرن على أساسيات Python ببناء تطبيق صغير ينشئ شخصية لمغامرة لعبة تقمص أدوار. -**الهدف:** نفذ قصص المستخدم أدناه واجعل جميع الاختبارات تنجح لإكمال المختبر. +**الهدف:** إكمال قصص المستخدم أدناه واجتياز جميع الاختبارات لإتمام المختبر. **قصص المستخدم:** -1. يجب أن يكون لديك دالة باسم `create_character`. -1. يجب أن تقبل الدالة، بالترتيب، اسم الشخصية متبوعًا بثلاث إحصائيات: القوة، الذكاء، والكاريزما. +1. يجب أن تملك دالة باسم `create_character`. +1. يجب أن تقبل الدالة، بالترتيب، اسم الشخصية متبوعًا بثلاث معلمات: القوة، الذكاء، والكاريزما. 1. يجب التحقق من صحة اسم الشخصية: - - إذا لم يكن اسم الشخصية سلسلة نصية، يجب أن تُرجع الدالة `The character name should be a string`. - - إذا كان اسم الشخصية سلسلة فارغة، يجب أن تُرجع الدالة `The character should have a name`. - - إذا كان اسم الشخصية أطول من 10 أحرف، يجب أن تُرجع الدالة `The character name is too long`. - - إذا احتوى اسم الشخصية على مسافات، يجب أن تُرجع الدالة `The character name should not contain spaces`. -1. يجب التحقق من صحة الإحصائيات أيضًا: - - إذا كانت إحدى الإحصائيات أو أكثر ليست أعداد صحيحة، يجب أن تُرجع الدالة `All stats should be integers`. - - إذا كانت إحدى الإحصائيات أو أكثر أقل من 1، يجب أن تُرجع الدالة `All stats should be no less than 1`. - - إذا كانت إحدى الإحصائيات أو أكثر أكثر من 4، يجب أن تُرجع الدالة `All stats should be no more than 4`. - - إذا كان مجموع كل الإحصائيات مختلفًا عن 7، يجب أن تُرجع الدالة `The character should start with 7 points`. -1. إذا اجتازت كل القيم التحقق، يجب أن تُرجع الدالة سلسلة نصية من أربعة أسطر: - - السطر الأول يجب أن يحتوي على اسم الشخصية - - الأسطر من 2 إلى 4 يجب أن تبدأ باختصار الإحصائية، `STR`، `INT` أو `CHA` (بهذا الترتيب)، ثم مسافة، ثم عدد من النقاط الممتلئة (`●`) يساوي قيمة الإحصائية، وعدد من النقاط الفارغة (`○`) ليصل المجموع إلى 10. مثال: إذا كانت قيمة القوة 3 يجب أن تكون هناك 3 نقاط ممتلئة تليها 7 نقاط فارغة. النقاط موجودة في المحرر. + - إذا لم يكن اسم الشخصية سلسلة نصية، يجب أن ترجع الدالة `The character name should be a string`. + - إذا كان اسم الشخصية سلسلة نصية فارغة، يجب أن ترجع الدالة `The character should have a name`. + - إذا كان اسم الشخصية أطول من 10 أحرف، يجب أن ترجع الدالة `The character name is too long`. + - إذا كان اسم الشخصية يحتوي على مسافات، يجب أن ترجع الدالة `The character name should not contain spaces`. +1. يجب التحقق من صحة المعلمات أيضًا: + - إذا كانت واحدة أو أكثر من المعلمات ليست أعداد صحيحة، يجب أن ترجع الدالة `All stats should be integers`. + - إذا كانت واحدة أو أكثر من المعلمات أقل من 1، يجب أن ترجع الدالة `All stats should be no less than 1`. + - إذا كانت واحدة أو أكثر من المعلمات أكثر من 4، يجب أن ترجع الدالة `All stats should be no more than 4`. + - إذا لم يكن مجموع كل المعلمات يساوي 7، يجب أن ترجع الدالة `The character should start with 7 points`. +1. إذا اجتازت كل القيم التحقق، يجب أن ترجع الدالة سلسلة نصية مكونة من أربعة أسطر: + - السطر الأول يجب أن يحتوي على اسم الشخصية. + - الأسطر من 2 إلى 4 يجب أن تبدأ باختصار المعلمة، `STR`، `INT`، أو `CHA` (بهذا الترتيب)، ثم مسافة، ثم عدد من النقاط الممتلئة (`●`) يساوي قيمة المعلمة، وعدد من النقاط الفارغة (`○`) ليصل المجموع إلى 10. مثال: إذا كانت قيمة القوة 3، يجب أن تكون هناك 3 نقاط ممتلئة تليها 7 نقاط فارغة. النقاط موجودة في المحرر. إليك السلسلة التي يجب أن تُرجعها الدالة `create_character('ren', 4, 2, 1)`: @@ -38,7 +38,7 @@ dashedName: build-an-rpg-character CHA ●○○○○○○○○○ ``` -ملاحظة: رغم أن `str` و `int` اختصارات شائعة للإحصائيات، تذكر أنها كلمات مفتاحية محجوزة في Python ولا يجب استخدامها كأسماء متغيرات. +**ملاحظة:** رغم أن `str` و `int` اختصارات شائعة للمعلمات، يستخدم بايثون هذه الأسماء لأنواع السلاسل النصية والأعداد الصحيحة، لذا من الأفضل تجنب استخدامها كأسماء متغيرات. # --hints-- @@ -54,7 +54,7 @@ assert _Node(_code).has_function('create_character') }) ``` -عند استدعاء `create_character` بمعلمة أولى ليست سلسلة نصية يجب أن تُرجع `The character name should be a string`. +عندما يُستدعى `create_character` بمعلمة أولى ليست سلسلة نصية، يجب أن ترجع `The character name should be a string`. ```js ({ @@ -68,7 +68,7 @@ for wrong_type in wrong_types: }) ``` -عند استدعاء `create_character` بمعلمة أولى سلسلة نصية يجب ألا تُرجع `The character name should be a string`. +عندما يُستدعى `create_character` بمعلمة أولى سلسلة نصية، يجب ألا ترجع `The character name should be a string`. ```js ({ @@ -102,7 +102,7 @@ assert create_character('ren', 4, 2, 1) != 'The character should have a name' }) ``` -عند استدعاء `create_character` بمعلمة أولى أطول من 10 أحرف يجب أن تُرجع `The character name is too long`. +عندما يُستدعى `create_character` بمعلمة أولى أطول من 10 أحرف، يجب أن ترجع `The character name is too long`. ```js ({ @@ -115,7 +115,7 @@ for length in range(11, 27): }) ``` -يجب ألا تقول دالة `create_character` أن الاسم طويل جدًا إذا لم يكن أطول من 10 أحرف. +يجب ألا تقول دالة `create_character` أن اسم الشخصية طويل جدًا إذا لم يكن أطول من 10 أحرف. ```js ({ @@ -128,7 +128,7 @@ for length in range(0, 11): }) ``` -عند استدعاء `create_character` بمعلمة أولى تحتوي على مسافة يجب أن تُرجع `The character name should not contain spaces`. +عندما يُستدعى `create_character` بمعلمة أولى تحتوي على مسافة، يجب أن ترجع `The character name should not contain spaces`. ```js ({ @@ -140,7 +140,7 @@ assert create_character('cha cha', 4, 1, 2) == 'The character name should not co }) ``` -عند استدعاء `create_character` بمعلمة أولى لا تحتوي على مسافة يجب ألا تُرجع `The character name should not contain spaces`. +عندما يُستدعى `create_character` بمعلمة أولى لا تحتوي على مسافة، يجب ألا ترجع `The character name should not contain spaces`. ```js ({ @@ -152,7 +152,7 @@ assert create_character('chacha', 4, 2, 1) != 'The character name should not con }) ``` -عند استدعاء `create_character` بالمعلمة الثانية أو الثالثة أو الرابعة التي ليست عددًا صحيحًا يجب أن تُرجع `All stats should be integers`. +عندما يُستدعى `create_character` بالمعلمة الثانية أو الثالثة أو الرابعة التي ليست عددًا صحيحًا، يجب أن ترجع `All stats should be integers`. ```js ({ @@ -168,7 +168,7 @@ for wrong_type in wrong_types: }) ``` -عند استدعاء `create_character` بالمعلمة الثانية والثالثة والرابعة التي كلها أعداد صحيحة يجب ألا تُرجع `All stats should be integers`. +عندما يُستدعى `create_character` بالمعلمة الثانية والثالثة والرابعة وكلها أعداد صحيحة، يجب ألا ترجع `All stats should be integers`. ```js ({ @@ -180,7 +180,7 @@ assert create_character('friend', 4, 2, 1) != 'All stats should be integers' }) ``` -عند استدعاء `create_character` بالمعلمة الثانية أو الثالثة أو الرابعة التي أقل من `1` يجب أن تُرجع `All stats should be no less than 1`. +عندما يُستدعى `create_character` بالمعلمة الثانية أو الثالثة أو الرابعة التي أقل من `1`، يجب أن ترجع `All stats should be no less than 1`. ```js ({ @@ -199,7 +199,7 @@ assert create_character('ren', 4, 4, -1) == expected }) ``` -عند استدعاء `create_character` بالمعلمة الثانية والثالثة والرابعة التي كلها لا تقل عن `1` يجب ألا تُرجع `All stats should be no less than 1`. +عندما يُستدعى `create_character` بالمعلمة الثانية والثالثة والرابعة وكلها لا تقل عن `1`، يجب ألا ترجع `All stats should be no less than 1`. ```js ({ @@ -211,7 +211,7 @@ assert create_character('ren', 4, 2, 1) != 'All stats should be no less than 1' }) ``` -عند استدعاء `create_character` بالمعلمة الثانية أو الثالثة أو الرابعة التي تزيد عن `4` يجب أن تُرجع `All stats should be no more than 4`. +عندما يُستدعى `create_character` بالمعلمة الثانية أو الثالثة أو الرابعة التي تزيد عن `4`، يجب أن ترجع `All stats should be no more than 4`. ```js ({ @@ -225,7 +225,7 @@ assert create_character('ren', 1, 1, 5) == 'All stats should be no more than 4' }) ``` -عند استدعاء `create_character` بالمعلمة الثانية والثالثة والرابعة التي كلها لا تزيد عن `4` يجب ألا تُرجع `All stats should be no more than 4`. +عندما يُستدعى `create_character` بالمعلمة الثانية والثالثة والرابعة وكلها لا تزيد عن `4`، يجب ألا ترجع `All stats should be no more than 4`. ```js ({ @@ -237,7 +237,7 @@ assert create_character('ren', 4, 2, 1) != 'All stats should be no more than 4' }) ``` -عند استدعاء `create_character` بالمعلمة الثانية أو الثالثة أو الرابعة التي لا يجمع مجموعها إلى `7` يجب أن تُرجع `The character should start with 7 points`. +عندما لا يكون مجموع المعلمات الثانية والثالثة والرابعة الممررة إلى الدالة `create_character` يساوي `7`، يجب أن ترجع الدالة `create_character` القيمة `The character should start with 7 points`. ```js ({ @@ -251,7 +251,7 @@ assert create_character('ren', 1, 2, 3) == 'The character should start with 7 po }) ``` -عند استدعاء `create_character` بالمعلمة الثانية والثالثة والرابعة التي يجمع مجموعها إلى `7` يجب ألا تُرجع `The character should start with 7 points`. +عندما يُستدعى `create_character` بالمعلمة الثانية والثالثة والرابعة التي مجموعها `7`، يجب ألا ترجع `The character should start with 7 points`. ```js ({ @@ -275,7 +275,7 @@ assert create_character('ren', 4, 2, 1) == f'ren\\nSTR ●●●●○○○○ }) ``` -عند استدعاء `create_character` بقيم صحيحة يجب أن تُخرج إحصائيات الشخصية كما هو مطلوب. +عندما يُستدعى `create_character` بقيم صحيحة، يجب أن تعرض إحصائيات الشخصية كما هو مطلوب. ```js ({ @@ -317,7 +317,7 @@ def create_character(character_name, strength, intelligence, charisma): return 'The character name should not contain spaces' if type(strength) != int or type(intelligence) != int or type(charisma) != int: - return 'All stats should be integers' + return 'All stats should be integers' if strength < 1 or intelligence < 1 or charisma < 1: return 'All stats should be no less than 1' if strength > 4 or intelligence > 4 or charisma > 4: diff --git a/curriculum/challenges/arabic/blocks/lab-travel-weather-planner/694acade1d4afdbce71e5840.md b/curriculum/challenges/arabic/blocks/lab-travel-weather-planner/694acade1d4afdbce71e5840.md index a958cb84f98..e38a3407171 100644 --- a/curriculum/challenges/arabic/blocks/lab-travel-weather-planner/694acade1d4afdbce71e5840.md +++ b/curriculum/challenges/arabic/blocks/lab-travel-weather-planner/694acade1d4afdbce71e5840.md @@ -13,25 +13,26 @@ dashedName: build-a-travel-weather-planner **قصص المستخدم:** -1. يجب عليك إنشاء المتغيرات التالية: - * `distance_mi` (رقم يُمثل المسافة التي يجب قطعها بالأميال) - * `is_raining` (قيمة منطقية تُمثل ما إذا كان المستخدم يواجه طقسًا ممطرًا حاليًا) - * `has_bike` (قيمة منطقية تُمثل ما إذا كان لدى المستخدم دراجة) - * `has_car` (قيمة منطقية تُمثل ما إذا كان لدى المستخدم سيارة) - * `has_ride_share_app` (قيمة منطقية تُمثل ما إذا كان لدى المستخدم تطبيق يسمح له بطلب رحلة) -1. يجب عليك استخدام عبارات شرطية لتحديد ما إذا كان التنقل ممكنًا بناءً على قيم هذه المتغيرات. -1. يجب عليك استخدام عبارات `if` و `elif` و `else` لتقييم فئات المسافة بترتيب تصاعدي. -1. إذا كانت قيمة `distance_mi` قيمة خاطئة: - * يجب عليك طباعة `False`. -1. إذا كانت المسافة **أقل من أو تساوي ميلًا واحدًا**: - * يجب عليك طباعة `True` فقط إذا لم يكن هناك مطر. - * وإلا، يجب طباعة `False`. -1. إذا كانت المسافة **أكبر من ميل واحد وأقل من أو تساوي 6 أميال**: - * يجب عليك طباعة `True` فقط إذا كان لدى الشخص دراجة **و** لم يكن هناك مطر. - * وإلا، يجب طباعة `False`. +1. عرّف المتغيرات التالية: + * `distance_mi` (رقم يمثل المسافة التي ستقطعها بالأميال) + * `is_raining` (قيمة منطقية تمثل ما إذا كان المستخدم يواجه طقسًا ممطرًا حاليًا) + * `has_bike` (قيمة منطقية تمثل ما إذا كان لدى المستخدم دراجة) + * `has_car` (قيمة منطقية تمثل ما إذا كان لدى المستخدم سيارة) + * `has_ride_share_app` (قيمة منطقية تمثل ما إذا كان لدى المستخدم تطبيق يسمح له بطلب رحلة) +1. استخدم عبارات شرطية لتحديد ما إذا كان التنقل ممكنًا بناءً على قيم هذه المتغيرات. +1. استخدم عبارات `if` و `elif` و `else` لتقييم فئات المسافة بترتيب تصاعدي. +1. استخدم على الأقل عاملًا منطقيًا واحدًا (`and` أو `or` أو `not`) في كودك. +1. إذا كانت قيمة `distance_mi` خاطئة: + * اطبع `False`. +1. إذا كانت المسافة **أقل من أو تساوي 1 ميل**: + * اطبع `True` فقط إذا لم يكن هناك مطر. + * وإلا، اطبع `False`. +1. إذا كانت المسافة **أكبر من 1 ميل وأقل من أو تساوي 6 أميال**: + * اطبع `True` فقط إذا كان لدى الشخص دراجة **و** لم يكن هناك مطر. + * وإلا، اطبع `False`. 1. إذا كانت المسافة **أكبر من 6 أميال**: - * يجب عليك طباعة `True` إذا كان لدى الشخص سيارة **أو** تطبيق لطلب الرحلات. - * وإلا، يجب طباعة `False`. + * اطبع `True` إذا كان لدى الشخص سيارة **أو** تطبيق لطلب الرحلات. + * وإلا، اطبع `False`. # --hints-- @@ -44,7 +45,7 @@ dashedName: build-a-travel-weather-planner يجب تعيين رقم إلى متغير `distance_mi` الخاص بك. ```js -({ test: () => runPython(`assert isinstance(distance_mi, (int, float))`) }) +({ test: () => runPython(`assert isinstance(distance_mi, (int, float)) and not isinstance(distance_mi, bool)`) }) ``` يجب أن يكون لديك متغير اسمه `is_raining`. @@ -135,7 +136,8 @@ tree = ast.parse(_code) bool_ops = [ node for node in ast.walk(tree) - if isinstance(node, (ast.BoolOp, ast.UnaryOp)) + if isinstance(node, ast.BoolOp) + or (isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.Not)) ] assert len(bool_ops) >= 1 @@ -533,6 +535,54 @@ run_case( `) }) ``` +عندما تكون المسافة بين `1` ميل (مستبعد) و `6` أميال (مشمولة)، وتتوفر دراجة، ويكون الطقس ممطرًا، يجب أن يطبع البرنامج `False`. + +```js +({ test: () => runPython(` +import ast, io, contextlib + +VARIABLES = { + "distance_mi", + "is_raining", + "has_bike", + "has_car", + "has_ride_share_app" +} + +def run_case(env, expected): + tree = ast.parse(_code) + + tree.body = [ + node for node in tree.body + if not ( + isinstance(node, ast.Assign) + and isinstance(node.targets[0], ast.Name) + and node.targets[0].id in VARIABLES + ) + ] + + clean_code = compile(tree, "", "exec") + + buffer = io.StringIO() + with contextlib.redirect_stdout(buffer): + exec(clean_code, env) + + assert buffer.getvalue().strip() == expected + + +run_case( + { + "distance_mi": 2, + "is_raining": True, + "has_bike": True, + "has_car": False, + "has_ride_share_app": False + }, + "False" +) +`) }) +``` + عندما تكون المسافة أكبر من `6` أميال ويتوفر تطبيق لطلب الرحلات، يجب أن يطبع البرنامج `True`. ```js @@ -578,6 +628,17 @@ run_case( }, "True" ) + +run_case( + { + "distance_mi": 12, + "is_raining": True, + "has_bike": False, + "has_car": False, + "has_ride_share_app": True + }, + "True" +) `) }) ``` @@ -626,6 +687,17 @@ run_case( }, "True" ) + +run_case( + { + "distance_mi": 12, + "is_raining": True, + "has_bike": False, + "has_car": True, + "has_ride_share_app": False + }, + "True" +) `) }) ``` diff --git a/curriculum/challenges/arabic/blocks/lab-user-configuration-manager/684aaf9ec670c68d20efd0d0.md b/curriculum/challenges/arabic/blocks/lab-user-configuration-manager/684aaf9ec670c68d20efd0d0.md index 3bcd6b38c63..03a86b6e2bc 100644 --- a/curriculum/challenges/arabic/blocks/lab-user-configuration-manager/684aaf9ec670c68d20efd0d0.md +++ b/curriculum/challenges/arabic/blocks/lab-user-configuration-manager/684aaf9ec670c68d20efd0d0.md @@ -46,8 +46,8 @@ saveSubmissionToDB: true 1. يجب أن تقوم دالة `view_settings` بما يلي: - - أرجع الرسالة `No settings available.` إذا كان القاموس المعطى للإعدادات فارغًا. - - إذا احتوى القاموس على أي إعدادات، أرجع سلسلة نصية تعرض الإعدادات. يجب أن تبدأ السلسلة بـ `Current User Settings:` تليها أزواج المفتاح-القيمة، كل منها في سطر جديد وبالمفتاح مكتوبًا بحرف كبير. على سبيل المثال، `view_settings({'theme': 'dark', 'notifications': 'enabled', 'volume': 'high'})` يجب أن تُرجع: + - أرجع `No settings available.` إذا كان القاموس المعطى للإعدادات فارغًا. + - إذا احتوى القاموس على أي إعدادات، أرجع سلسلة نصية تعرض الإعدادات. يجب أن تبدأ السلسلة بـ `Current User Settings:` تليها أزواج المفتاح-القيمة، كل زوج في سطر جديد مع كتابة الحرف الأول من المفتاح بحرف كبير، وينتهي النص بحرف سطر جديد بعد آخر إعداد. على سبيل المثال، يجب أن تُرجع `view_settings({'theme': 'dark', 'notifications': 'enabled', 'volume': 'high'})` ما يلي: ```md Current User Settings: @@ -117,7 +117,7 @@ saveSubmissionToDB: true }) ``` -`add_setting({'theme': 'light'}, ('THEME', 'dark'))` يجب أن تُرجع رسالة الخطأ `Setting 'theme' already exists! Cannot add a new setting with this name.`. +`add_setting({'theme': 'light', 'language': 'English'}, ('THEME', 'dark'))` يجب أن تُرجع رسالة الخطأ `Setting 'theme' already exists! Cannot add a new setting with this name.`. ```js ({ @@ -206,7 +206,7 @@ saveSubmissionToDB: true }) ``` -`update_setting({'theme': 'light'}, ('theme', 'dark'))` يجب أن تحدّث مفتاحًا موجودًا وتُرجع رسالة النجاح `Setting 'theme' updated to 'dark' successfully!`. +`update_setting({'theme': 'light', 'language': 'English'}, ('theme', 'dark'))` يجب أن تحدّث مفتاحًا موجودًا وتُرجع رسالة النجاح `Setting 'theme' updated to 'dark' successfully!`. ```js ({ @@ -281,7 +281,7 @@ saveSubmissionToDB: true }) ``` -`delete_setting({'theme': 'light'}, 'theme')` يجب أن تزيل المفتاح الموجود وتُرجع رسالة النجاح `Setting 'theme' deleted successfully!`. +`delete_setting({'theme': 'light', 'language': 'English'}, 'theme')` يجب أن تزيل المفتاح الموجود وتُرجع رسالة النجاح `Setting 'theme' deleted successfully!`. ```js ({ diff --git a/curriculum/challenges/arabic/blocks/learn-about-speculation-and-requests/67eea33bbc314f248d210c93.md b/curriculum/challenges/arabic/blocks/learn-about-speculation-and-requests/67eea33bbc314f248d210c93.md index 7ecb6a5faaf..47550c9da26 100644 --- a/curriculum/challenges/arabic/blocks/learn-about-speculation-and-requests/67eea33bbc314f248d210c93.md +++ b/curriculum/challenges/arabic/blocks/learn-about-speculation-and-requests/67eea33bbc314f248d210c93.md @@ -54,7 +54,7 @@ lang: en-US للعثور على الإجابة الصحيحة، ركز على كيفية تقديم صوفي للتعليقات. -تقول `explaining why you chose a particular loop structure`. هذا يدل على أنها لا تقول إن الحلقة خاطئة — بل يجب شرح القرار وراءها. +تقول `explaining why you chose a particular loop structure`. هذا يدل على أنها لا تقول إن الحلقة خاطئة — بل يجب شرح القرار وراء اختيارها. هذا يساعد الآخرين على فهم التفكير وراء الكود، ولهذا السبب التعليقات مفيدة. diff --git a/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/658147bb3dbda824437fd6f9.md b/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/658147bb3dbda824437fd6f9.md index b71fc45d5b8..ae7e5bf228f 100644 --- a/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/658147bb3dbda824437fd6f9.md +++ b/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/658147bb3dbda824437fd6f9.md @@ -46,7 +46,7 @@ lang: en-US ### --feedback-- -هذه الكلمة مرتبطة بالعمل أو المسار المهني. تصف القيام بشيء بطريقة تظهر مهارات وسلوكًا جيدًا في العمل. وتنتهي بـ `-ly` +هذه الكلمة مرتبطة بالعمل أو المهنة. تصف القيام بشيء بطريقة تظهر مهارات وسلوكًا جيدًا في الوظيفة. تنتهي بـ`-ly`. # --scene-- diff --git a/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35429c637c13540c9be80.md b/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35429c637c13540c9be80.md index d701ec126b6..1a66624902e 100644 --- a/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35429c637c13540c9be80.md +++ b/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35429c637c13540c9be80.md @@ -26,7 +26,7 @@ lang: en-US ### --feedback-- -هذا الفعل يعني منح الإذن أو جعل القيام بشيء ممكنًا. هذا الفعل يُصرف مع ضمير الغائب المفرد. لذا، تذكر إضافة `-s`. +هذا الفعل يعني منح الإذن أو جعل شيء ممكنًا للقيام به. يُصرف في صيغة الغائب المفرد، لذا تذكر إضافة `-s`. --- diff --git a/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35c7b9d642f478d6cabba.md b/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35c7b9d642f478d6cabba.md index fb4c0907f95..cfdc06b13df 100644 --- a/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35c7b9d642f478d6cabba.md +++ b/curriculum/challenges/arabic/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35c7b9d642f478d6cabba.md @@ -24,7 +24,7 @@ lang: en-US ### --feedback-- -يُستخدم هذا الظرف لتأكيد صحة أو أهمية بيان، ويُظهر موافقة أو اعتقادًا قويًا. ينتهي بـ `ly`. +يُستخدم هذا الظرف لتأكيد صحة أو أهمية بيان، مظهرًا اتفاقًا قويًا أو اعتقادًا. ينتهي بـ `ly`. # --scene-- diff --git a/curriculum/challenges/arabic/blocks/lecture-browsing-the-web-effectively/672ac9705b07a64439b73b59.md b/curriculum/challenges/arabic/blocks/lecture-browsing-the-web-effectively/672ac9705b07a64439b73b59.md index 4de1488d6a3..748bcb1a55b 100644 --- a/curriculum/challenges/arabic/blocks/lecture-browsing-the-web-effectively/672ac9705b07a64439b73b59.md +++ b/curriculum/challenges/arabic/blocks/lecture-browsing-the-web-effectively/672ac9705b07a64439b73b59.md @@ -15,26 +15,38 @@ dashedName: how-to-use-a-search-engine-effectively-to-achieve-optimal-results إليك مثال على استعلام بحث أساسي لـ `freecodecamp curriculum`. +A search engine search box containing the query freecodecamp curriculum. + عندما تبحث عن `freecodecamp curriculum`، سيُرجع محرك البحث نتائج تطابق *أي* من هذه الكلمات المفتاحية – عادةً مرتبة حسب الصلة (مدى احتمال تطابقها أو ارتباطها بمعظم استعلامك). لكن ماذا لو أردت نتائج تطابق كلا الكلمتين المفتاحيتين فقط؟ ربما سمعت أنه يمكنك وضع الاستعلام بين علامات اقتباس، مثل `"freecodecamp curriculum"`. +A search engine search box containing the query freecodecamp curriculum wrapped in quotation marks. + مع ذلك، هذا الاستعلام يطابق *العبارة* `freecodecamp curriculum` تحديدًا. هذا يعني أن النتائج التي سترىها ستقتصر على المواقع التي تقول `freecodecamp curriculum` معًا، وليس المواقع التي تقول `freecodecamp` وَ `curriculum`. إذا أردت مطابقة المواقع التي تحتوي على كلا المصطلحين، لكن ليس بالضرورة متجاورين كعبارة، يمكنك وضع بادئة علامة زائد لكل مصطلح هكذا: `+freecodecamp +curriculum` +A search engine search box containing the query +freecodecamp +curriculum, with a plus symbol before each term. + بدلاً من ذلك، ربما تهتم بمبادرات freeCodeCamp خارج المنهج. في هذه الحالة، يمكنك وضع بادئة علامة ناقص على المصطلح `curriculum` هكذا: `+freecodecamp -curriculum`. +A search engine search box containing the query +freecodecamp -curriculum, with a plus symbol before freecodecamp and a minus symbol before curriculum. + هذا سيُرجع نتائج تذكر `freecodecamp`، لكنه يستبعد النتائج التي تذكر أيضًا `curriculum`. أو ربما لديك موقع محدد تريد البحث فيه، مثل منصتنا الإخبارية؟ يمكنك استخدام `site:` متبوعًا بعنوان URL للموقع الذي تريد البحث فيه: `site:freecodecamp.org/news curriculum`. +A search engine search box containing the query site:freecodecamp.org/news curriculum. + هذا الاستعلام يُرجع كل النتائج من `freecodecamp.org/news` التي تحتوي على كلمة `curriculum`. بدمج هذه الأدوات، يمكنك صياغة استعلامات محددة جدًا للحصول على المعلومات التي تحتاجها بالضبط. على سبيل المثال، الاستعلام `site:freecodecamp.org/news +python -curriculum` سيبحث عن مقالات بايثون في موقع الأخبار الخاص بنا، مستبعدًا المقالات التي قد تتحدث عن المنهج. +A search engine search box containing the query site:freecodecamp.org/news +python -curriculum. + قد تختلف عوامل البحث، لذا من المهم دائمًا مراجعة الوثائق الخاصة بمحرك البحث الذي تفضله. لكن يجب أن تكون الآن قادرًا على الحصول على النتائج الدقيقة التي تريدها من عمليات البحث على الويب. diff --git a/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/68420bd261d0d35f61922d4b.md b/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/68420bd261d0d35f61922d4b.md index 3d273ab0f15..a3563a621f7 100644 --- a/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/68420bd261d0d35f61922d4b.md +++ b/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/68420bd261d0d35f61922d4b.md @@ -13,6 +13,8 @@ dashedName: how-do-classes-work-and-how-do-they-differ-from-objects لنلقِ نظرة على ما هي الأصناف، وكيف تستخدمها لإنشاء الكائنات. +## إنشاء صنف + لإنشاء صنف، تستخدم الكلمة المفتاحية `class` متبوعة باسم الصنف ونقطتين. ثم داخل الصنف، يمكنك إضافة مُهيئ، بالإضافة إلى أي خصائص وطرق. الخصائص تشبه المتغيرات داخل الصنف، وتُستخدم لتخزين البيانات. الطرق هي دوال معرفة داخل الصنف، وهي الأفعال التي يمكن للكائنات التي تُنشأ من الصنف تنفيذها. @@ -42,6 +44,8 @@ class ClassName: * `print(self.name.upper())` هو ما ستفعله طريقة `sample_method`، في هذه الحالة، تطبع الاسم بأحرف كبيرة. +## مثال على صنف `Dog` + إذا بدا لك كل هذا كثيرًا، لا تقلق. لنلقِ نظرة على مثال مشابه لصنف `Dog`، وكيف يمكنك إنشاء كائنات منه: ```python @@ -54,6 +58,8 @@ class Dog: print(f"{self.name.upper()} says woof woof!") ``` +## إنشاء كائنات من صنف + مع هذا الصنف `Dog`، يمكنك إنشاء كائن. إليك الصيغة النحوية الأساسية لإنشاء كائنات من صنف: ```python @@ -91,6 +97,8 @@ dog_2.bark() # THATCHER says woof woof! I'm 5 years old! ثم عند استدعاء طريقة `.bark()` على `dog_1` و `dog_2`، يمكنك رؤية كيف تختلف المخرجات، وتستخدم الخصائص الفريدة `name` و `age` التي مررتها عند إنشاء كل كائن. +## الفروقات بين الأصناف والكائنات + باختصار، الفرق بين الصنف والكائن هو أن الصنف هو القالب أو المخطط، والكائن هو ما يُنشأ باستخدام ذلك القالب. أيضًا، يحدد الصنف البيانات والسلوك الذي يجب أن يمتلكه الكائن، والكائن يحمل البيانات الفعلية ويستخدم ذلك السلوك. تكتب الصنف مرة واحدة، ويمكنك إنشاء العديد من الكائنات منه، كل منها ببيانات مختلفة. diff --git a/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/6874b7d3b286c538b39d0c25.md b/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/6874b7d3b286c538b39d0c25.md index 5c8d0a2c21c..0c8efb6144a 100644 --- a/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/6874b7d3b286c538b39d0c25.md +++ b/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/6874b7d3b286c538b39d0c25.md @@ -7,6 +7,8 @@ dashedName: what-are-special-methods-and-what-are-they-used-for # --description-- +## ما هي الطرق الخاصة؟ + الطرق الخاصة في Python، المعروفة أيضًا باسم "الطرق السحرية" أو "طرق dunder"، هي طرق Python خاصة تبدأ وتنتهي بشرطتين سفليتين مزدوجتين (`__`). كلمة "dunder" نفسها مشتقة من الشرطتين السفليتين المزدوجتين (**d** من double، **under** من underscores). ربما استخدمت الطرق الخاصة بالفعل دون أن تعرف ذلك. في كل مرة تكتب شيئًا مثل `3 + 4`، يقوم Python بهدوء بتنفيذ `3.__add__(4)` خلف الكواليس. هذه طريقة خاصة تعمل. لذلك، رغم أنه يمكنك *استدعاء* الطرق الخاصة مباشرة، إلا أنك نادرًا ما تفعل ذلك. شيء مثل `3 + 4` أوضح وأسهل في القراءة من استدعاء `3.__add__(4)` بنفسك. @@ -15,6 +17,8 @@ dashedName: what-are-special-methods-and-what-are-they-used-for فكر في الطرق الخاصة كمخرجين للأنشطة بين المبرمج ومفسر لغة Python نفسه. +## متى يستدعي Python الطرق الخاصة + تذكر، لا تحتاج إلى استدعاء الطرق الخاصة مباشرة. بدلاً من ذلك، يستدعيها Python تلقائيًا عند حدوث إجراءات معينة. تشمل هذه العمليات: - **العمليات الحسابية مثل الجمع والطرح والضرب والقسمة وغيرها**. للجمع، تُستدعى `__add__()`، وللطرح `__sub__()`، وللضرب `__mul__()`، وللقسمة `__truediv__()`. @@ -26,6 +30,8 @@ dashedName: what-are-special-methods-and-what-are-they-used-for - **عمليات التكرار مثل جعل الكائن قابلًا للتكرار والتقدم عبر العناصر**. تُستدعى `__iter__()` لإرجاع مكرر و `__next__()` لجلب العنصر التالي. +## لماذا تحتاج الأصناف المخصصة إلى طرق خاصة + عادةً، أنواع بيانات Python مثل السلاسل النصية والأرقام تعرف بالفعل كيف تضيف الأشياء، وتربط السلاسل، وتقارن للتساوي، وتُستخدم في الحلقات، وغيرها. لكن عندما تنشئ صنفك الخاص، لن يعرف Python كيف يتعامل مع الأشياء تلقائيًا. @@ -57,6 +63,8 @@ print(book1 == book2) # False even though they have the same number of pages - كانت نتيجة `book1 == book2` هي `False` لأن Python فقط يتحقق مما إذا كان الكائنان نفسهما في الذاكرة، وليس بالمحتوى. +## تعريف طرقك الخاصة + إليك كيف يمكنك تعريف طرق خاصة خاصة بك مثل `__len__()` و `__str__()` و `__eq__()` لتسهيل العمل مع الكائنات التي تُنشأ من صنف `Book`: ```python @@ -84,6 +92,8 @@ print(str(book2)) # 'Be Your Own Start' has 420 pages print(book1 == book2) # True ``` +## مثال على عربة التسوق + مثال آخر هو عربة التسوق حيث تقوم بما يلي: - إضافة عناصر إلى العربة diff --git a/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/6908d38f7cccc31602743340.md b/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/6908d38f7cccc31602743340.md index 824e69a8701..3e00bb46a4e 100644 --- a/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/6908d38f7cccc31602743340.md +++ b/curriculum/challenges/arabic/blocks/lecture-classes-and-objects/6908d38f7cccc31602743340.md @@ -30,6 +30,8 @@ print(my_car.model) # Gallardo تتيح لك هذه الدوال الوصول إلى الخصائص، إنشاؤها، التحقق منها، وحذفها باستخدام أسماء متغيرة. دعنا نلقي نظرة على كل واحدة منها أثناء العمل. +## `getattr()` + تجعل `getattr()` من الممكن قراءة خاصية من كائن عندما لا تعرف اسمها حتى وقت التشغيل. إذا لم تكن الخاصية موجودة، ترفع استثناء `AttributeError`، إلا إذا وفرت قيمة افتراضية. لاستخدامها، تمرر الكائن، اسم الخاصية، وقيمة افتراضية اختيارية: @@ -75,6 +77,8 @@ print(getattr(person, attr_name, 'Attribute not found')) هنا بالضبط يتألق التعامل الديناميكي مع الخصائص. فهو يسمح لكودك بالاستجابة للمُدخلات والبيانات التي لم يسبق له رؤيتها. +## عرض الخصائص باستخدام `dir()` + بالإضافة إلى ذلك، قد ترغب في استعراض كل الخصائص التي يمتلكها كائن، وليس فقط التي تعرفها مسبقًا. الدالة المدمجة `dir()` تتيح لك ذلك. تعيد قائمة بكل أسماء الخصائص على الكائن. إليك كيفية استخدامها: ```python @@ -99,6 +103,8 @@ for attr in dir(person): في الحلقة أعلاه، `callable()` هي دالة مدمجة تعيد `True` إذا كان الكائن الممرر إليها يمكن استدعاؤه كدالة أو طريقة، و `False` خلاف ذلك. بفحص `not callable(getattr(person, attr))`، تتخطى الحلقة الطرق وتطبع فقط خصائص البيانات مثل `name` و `age`. +## `setattr()` + تتيح لك دالة `setattr()` إنشاء خاصية جديدة أو تحديث خاصية موجودة بشكل ديناميكي. الصيغة تبدو هكذا: ```python @@ -128,6 +134,8 @@ print(config_obj.server_url) # https://api.example.com print(config_obj.timeout_sec) # 30 ``` +## `hasattr()` + هناك أيضًا `hasattr()`. قبل أن تفعل شيئًا مع خاصية أو تحذفها، من الممارسات الجيدة التحقق من وجودها. هذا ما تفعله `hasattr()`. تتحقق من وجود الخاصية وتعيد `True` أو `False` بناءً على النتيجة. إليك الصيغة النحوية الأساسية: @@ -163,6 +171,8 @@ for attr in required_attributes: حدث خطأ ERROR لأن `inventory_id` مفقودة من صنف `Product` ومن نسخته. +## `delattr()` + أخيرًا، تتيح لك `delattr()` حذف خاصية بشكل ديناميكي: ```python diff --git a/curriculum/challenges/arabic/blocks/lecture-introduction-to-git-and-github/6882904fd7063f7258c0aef3.md b/curriculum/challenges/arabic/blocks/lecture-introduction-to-git-and-github/6882904fd7063f7258c0aef3.md index 11dbb628d7b..62f2ea2cdbe 100644 --- a/curriculum/challenges/arabic/blocks/lecture-introduction-to-git-and-github/6882904fd7063f7258c0aef3.md +++ b/curriculum/challenges/arabic/blocks/lecture-introduction-to-git-and-github/6882904fd7063f7258c0aef3.md @@ -7,10 +7,14 @@ dashedName: how-do-you-handle-security-requirements-like-ssh-and-gpg-keys # --description-- +## ما هي مفاتيح SSH و GPG؟ + قبل أن تدفع المستودع الخاص بك إلى GitHub، يجب أن تكون مُوثَّقًا. تستخدم مفاتيح SSH و GPG زوجًا من المفتاح العام والخاص. هذا يعني أنك تحتفظ بمفتاح خاص على جهازك المحلي، تستخدمه للمصادقة على نفسك. تشارك مفتاحًا عامًا مع الأشخاص أو الخدمات التي تحتاج إلى التحقق من مصادقتك. بعبارة أخرى، المفتاح الخاص مطلوب لأداء إجراء، والمفتاح العام يُستخدم للتحقق من هذا الإجراء. مفاتيح GPG، أو GNU Privacy Guard، تُستخدم عادةً لتوقيع الملفات أو الاستدعاءات. يمكن لأي شخص بعد ذلك استخدام مفتاح GPG العام الخاص بك للتحقق من أن توقيع الملف صادر عن مفتاحك وأن محتويات الملف لم تُعدّل أو تُعبث بها. مفاتيح SSH، أو Secure SHell، تُستخدم عادةً للمصادقة على اتصال بعيد بخادم عبر أداة `ssh`. ومع ذلك، كما ستتعلم في هذا الدرس، يمكنك أيضًا استخدام مفتاح SSH لتوقيع الاستدعاءات. +## توليد مفاتيح SSH و GPG + لتوليد مفتاح GPG، ستحتاج إلى تشغيل: ```sh @@ -27,6 +31,8 @@ ssh-keygen -t ed25519 -C "your_email@example.com" يجب أن تطلب كلا الأمرين عبارة مرور لتأمين المفتاح. هذه العبارة اختيارية، لكنها موصى بها بشدة. +## العثور على مفاتيحك العامة + بالنسبة لمفاتيح SSH، ستحصل على ملفين - واحد لمفتاحك الخاص، وآخر لمفتاحك العام. أسماء ملفات المفتاح العام تنتهي بـ `.pub`، حتى لا تشارك مفتاحك الخاص عن طريق الخطأ. ستكون هذه الملفات في `~/.ssh`. أما مفاتيح GPG فستكون في مجلد مخفي ومشفر. بدلاً من ذلك، لعرض مفاتيحك العامة، ستشغل: @@ -41,6 +47,8 @@ gpg --list-secret-keys --keyid-format=long gpg --armor --export "" ``` +## توقيع الالتزامات باستخدام مفتاح GPG + لكن ماذا يمكنك أن تفعل بهذه المفاتيح الجديدة؟ حسنًا، تحدثنا عن توقيع الالتزامات، وهذا شيء يمكنك استخدام أي من هذه المفاتيح من أجله. لتوقيع الالتزامات باستخدام مفتاح GPG، ستحتاج إلى رفع المفتاح العام، وليس الخاص، إلى حساب GitHub الخاص بك. ثم، خذ المعرف القصير الذي حصلت عليه من عرض المفاتيح سابقًا، وشغل هذا الأمر لتعيينه كمفتاح توقيع git الخاص بك: @@ -55,6 +63,8 @@ git config --global user.signingkey git config --global commit.gpgsign true ``` +## توقيع الالتزامات باستخدام مفتاح SSH + لتوقيع باستخدام مفتاح SSH، وهي ميزة جديدة نسبيًا على GitHub، ستحتاج أولًا إلى رفع المفتاح إلى حساب GitHub الخاص بك. ثم ستحتاج إلى تعيين وضع التوقيع لـ git لاستخدام SSH: ```sh diff --git a/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e3a9cc78faaf4248d335.md b/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e3a9cc78faaf4248d335.md index a568722489b..289476b7422 100644 --- a/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e3a9cc78faaf4248d335.md +++ b/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e3a9cc78faaf4248d335.md @@ -9,6 +9,8 @@ dashedName: what-is-the-role-of-js-libraries-and-frameworks-and-why-are-they-use توفر مكتبات وأُطُر عمل JavaScript كودًا مُسبق البناء يُسهّل عملية التطوير. بينما تهدف كل من المكتبات والأُطُر إلى تحسين الإنتاجية وتوحيد ممارسات البرمجة، إلا أنهما تختلفان في النهج ومستوى التحكم الذي توفره للمطوّرين. +## ما هي المكتبات؟ + تركز المكتبات عادةً على تقديم حلول لمهام محددة، مثل التلاعب بـ DOM، التعامل مع الأحداث، أو إدارة طلبات AJAX. مثال على مكتبة JavaScript هو jQuery. @@ -17,16 +19,22 @@ dashedName: what-is-the-role-of-js-libraries-and-frameworks-and-why-are-they-use على الرغم من أن jQuery لم تعد مستخدمة على نطاق واسع كما كانت سابقًا، إلا أنها ساعدت المطوِّرين بشكل كبير بجعل المهام المعقدة في JavaScript العادي أسهل بكثير في التنفيذ. +## ما هي أُطُر العمل؟ + من ناحية أخرى، توفر أُطُر العمل هيكلًا أكثر تحديدًا لبناء التطبيقات. غالبًا ما تأتي مع مجموعة من القواعد والاصطلاحات التي يجب على المطوِّرين اتباعها. على سبيل المثال، يشجع Angular على بنية قائمة على المكونات مع مجموعة من الاصطلاحات والأدوات التي توفر منهجًا منظمًا لتنظيم وبناء التطبيقات. يمنح Angular المطوِّرين إرشادات واضحة حول كيفية هيكلة المكونات، إدارة الحالة، التعامل مع التوجيه، والتفاعل مع الخدمات، مما يجعله إطار عمل أكثر تحديدًا. أمثلة أخرى على أُطُر العمل تشمل Remix و Next.js. +## المكتبات مقابل أُطُر العمل + على النقيض من ذلك، React، وهي مكتبة واجهة مستخدم، أكثر مرونة ولا تفرض أي نمط معماري معين. تركز React بشكل أساسي على طبقة العرض وتترك الكثير من خيارات تصميم التطبيق للمطوِّرين. على الرغم من استخدام المكتبات والأُطُر في مشاريع بجميع الأحجام، يعتمد الاختيار بينهما غالبًا على متطلبات المشروع. توفر المكتبات مرونة للوظائف المحددة، بينما تقدم الأُطُر منهجًا منظمًا تجاه التطبيقات المعقدة. +## لماذا تُستخدم المكتبات وأُطُر العمل في الصناعة + في الصناعة، تُستخدم المكتبات والأُطُر على نطاق واسع لأسباب عدة. فهي تُسرّع التطوير بشكل كبير من خلال توفير حلول سريعة للمشاكل الشائعة. مشكلة شائعة في JavaScript هي التعامل مع التواريخ والمناطق الزمنية. لكن توجد مكتبات توفر حلولًا مدمجة تساعدك في معالجة التواريخ، المناطق الزمنية، وتحليل وتنسيق التواريخ. diff --git a/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e879c78ee6c61db25b90.md b/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e879c78ee6c61db25b90.md index 304d543a1f1..41f881fd56c 100644 --- a/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e879c78ee6c61db25b90.md +++ b/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e879c78ee6c61db25b90.md @@ -15,6 +15,8 @@ dashedName: what-are-components-in-react-and-how-do-they-work تُوصف هذه الواجهة باستخدام JSX، وهو امتداد صيغة نحوية لـ JavaScript يشبه HTML لكنه يسمح لك بكتابة عناصر واجهة المستخدم بطريقة أكثر تعبيرًا. +## مكوِّن أساسي + لننظر إلى مثال على مكوِّن React: ```jsx @@ -43,12 +45,16 @@ function Greeting() { {/* Block Comments */} ``` +## تسمية المكوِّن + شيء آخر قد لاحظته هو أننا نستخدم حرفًا كبيرًا في بداية اسم المكوِّن. لكن لماذا لا يمكننا استخدام أحرف صغيرة فقط؟ ذلك لأن React يعامل المكوِّنات التي تبدأ بحرف كبير كمكوِّنات مخصصة، بينما تُعتبر العناصر التي تبدأ بأحرف صغيرة عناصر HTML مدمجة. عندما يصادف React وسمًا بحروف صغيرة، مثل `
` أو ``، يفترض أنه عنصر HTML قياسي. أما إذا بدأ اسم المكوِّن بحرف كبير، فسيعامله React كمكوِّن معرف من المستخدم ويعرضه وفقًا لذلك. هذا التمييز يساعد React على التفريق بين وسوم HTML الأصلية والمكوِّنات التي تنشئها. +## استخدام مكوِّن + لاستخدام هذا المكوِّن `Greeting` في تطبيقنا، نكتب شيئًا مثل هذا: ```jsx @@ -63,6 +69,8 @@ function Greeting() { {/* /> is required */} ``` +## عرض عناصر متعددة + حتى الآن، كنا ننظر فقط إلى كيفية عرض عنصر `h1` واحد. لكن يمكنك فعليًا عرض عدة عناصر. لنلقِ نظرة على كود المثال التالي هنا: @@ -84,6 +92,8 @@ function Greeting() { سبب ظهور رسالة الخطأ هو أن العناصر الشقيقة المتعددة يجب أن تُحاط بعنصر أبوي. بينما يمكنك إحاطة عنصري `h1` و `p` داخل `div` بسيط، هناك طريقة أخرى لتلبية هذا الشرط. +## أجزاء React + تُستخدم أجزاء React لتجميع العناصر معًا. هذا هو شكل المثال المعدل: ```jsx diff --git a/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/674ba6876f7ada867135bb95.md b/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/674ba6876f7ada867135bb95.md index 830e4194dd6..556fa192b09 100644 --- a/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/674ba6876f7ada867135bb95.md +++ b/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/674ba6876f7ada867135bb95.md @@ -13,6 +13,8 @@ dashedName: how-can-you-import-and-export-components-in-react في هذا الدرس، ستتعلم كيفية تصدير مكوّنات React باستخدام الصادرات الافتراضية والمُسماة، وكيف تستوردها حيثما تحتاجها. +## استخدام التصدير الافتراضي + في هذا المثال، لدينا مكوِّن `Cat` موجود في ملف يسمى `Cat.jsx`. نستخدم الامتداد `.jsx` لأن هذا الملف يعمل بشكل رئيسي مع JSX. يعيد مكوِّن `Cat` هذا ترميز JSX يحتوي على عنوان وصورة لقطة تُدعى Mr. Whiskers: @@ -65,6 +67,8 @@ export default function Cat() { } ``` +## استيراد تصدير افتراضي + يمكنك اختيار استيراد المكوّنات الفرعية في ملفات المكوّنات الأصلية الأخرى، أو استيرادها في ملف المكوّن الجذري. في هذا المثال، سنستورد مكوّن `Cat` داخل ملف المكوّن الجذري. كل مشروع React يحتوي على مكوِّن على المستوى الأعلى، يُسمى عادةً `App`، ومُعرف في ملف باسم `App.jsx`. @@ -101,6 +105,8 @@ export default function App() { تعمل هذه الطريقة جيدًا عندما يكون الملف مسؤولًا عن تصدير مكوّن رئيسي واحد، مما يحافظ على صيغة الاستيراد بسيطة وسهلة القراءة. تذكر، يمكن للملف أن يحتوي على تصدير افتراضي واحد فقط، مما يجعله مثاليًا لملف يحتوي بشكل أساسي على مكوّن واحد. +## استخدام التصدير المسمي + الآن بعد أن عرفت كيفية استخدام التصدير الافتراضي، دعنا نلقي نظرة على التصدير المسمي. يسمح التصدير المسمي لملف بمشاركة عدة مكوِّنات أو دوال. على عكس التصدير الافتراضي، يجب استيرادها باستخدام الاسم الدقيق الذي تم تصديرها به (إلا إذا قمت بإعادة تسميتها باستخدام الكلمة المفتاحية `as`). هذا مفيد عندما يكون الملف مكتبة مكوِّنات. على سبيل المثال، هنا ملف يحتوي على مكوِّنَين، `Cat` و `Dog`: @@ -141,6 +147,8 @@ export default function App() { } ``` +## دمج التصدير الافتراضي والمسمي + أخيرًا، يمكن للملف أن يحتوي على تصدير افتراضي واحد وعدة صادرات مُسماة. ```jsx diff --git a/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-objects-and-their-properties/6732b758194c97257d23fc72.md b/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-objects-and-their-properties/6732b758194c97257d23fc72.md index 357969e5c90..22ba12f76c2 100644 --- a/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-objects-and-their-properties/6732b758194c97257d23fc72.md +++ b/curriculum/challenges/arabic/blocks/lecture-introduction-to-javascript-objects-and-their-properties/6732b758194c97257d23fc72.md @@ -1,6 +1,6 @@ --- id: 6732b758194c97257d23fc72 -title: ما هو دالة البناء Object()، ومتى يجب استخدامها؟ +title: ما هو دالة البناء Object()‎، ومتى يجب استخدامها؟ challengeType: 19 dashedName: what-is-the-object-constructor-and-when-should-you-use-it --- diff --git a/curriculum/challenges/arabic/blocks/lecture-introduction-to-python/67fe81c9c6fd3714343a45ad.md b/curriculum/challenges/arabic/blocks/lecture-introduction-to-python/67fe81c9c6fd3714343a45ad.md index 5ad33ccea1c..b0c216f2a41 100644 --- a/curriculum/challenges/arabic/blocks/lecture-introduction-to-python/67fe81c9c6fd3714343a45ad.md +++ b/curriculum/challenges/arabic/blocks/lecture-introduction-to-python/67fe81c9c6fd3714343a45ad.md @@ -7,27 +7,25 @@ dashedName: what-is-python-and-what-are-some-common-uses-in-the-industry # --description-- -Python هي لغة برمجة عامة الغرض معروفة ببساطتها وسهولة استخدامها. هذه السهولة جعلت Python أكثر لغات البرمجة شعبية في العصر الحديث. +Python هي لغة برمجة عامة الغرض معروفة ببساطتها وسهولة استخدامها. صياغتها النحوية القصيرة والقابلة للقراءة ومرونتها في حل أنواع مختلفة من المشاكل جعلتها واحدة من أكثر لغات البرمجة شعبية في العالم. ولهذا السبب يُنصح بها كثيرًا كلغة أولى. -يُستخدم Python في مجالات كثيرة مثل علم البيانات وتعلم الآلة، تطوير الويب، البرمجة النصية والأتمتة، الأنظمة المدمجة، إنترنت الأشياء، وأكثر من ذلك. +يُستخدم Python على نطاق واسع للعمل مع البيانات. يستخدمه علماء البيانات لتنظيف المعلومات غير المنظمة، وحساب الإحصائيات، واكتشاف الأنماط، وإنشاء المخططات، وأكثر من ذلك بكثير. -Python هي اللغة الرئيسية التي يستخدمها معظم علماء البيانات ومهندسو تعلم الآلة حاليًا. تجعل المكتبات مثل Pandas وNumPy تحليل البيانات أقل إرهاقًا، بينما تسهل مكتبات أخرى مثل TensorFlow وScikit-learn تعلم الآلة والعمل مع نماذج الذكاء الاصطناعي بشكل أكبر. +Python هي أيضًا اللغة الأكثر شيوعًا لبناء وتدريب نماذج تعلم الآلة. هذه هي الأنظمة التي تقف وراء التعرف على الصور، وتوصيات المنتجات، وروبوتات الدردشة. -في تطوير الويب، تتيح أُطُر عمل Python مثل Django وFastAPI وFlask للمطوّرين بناء أنظمة خلفية قابلة للتوسع وآمنة بأقل جهد. تستخدم العديد من منصات التواصل الاجتماعي مثل Instagram وPinterest Python في الخلفية. +في تطوير الويب، يُستخدم Python غالبًا في جانب الخادم لموقع الويب. هذا هو الجزء الذي يعمل خلف الكواليس، ويتولى مهام مثل حسابات المستخدمين، وإرسال النماذج، وحفظ المعلومات. تستخدم العديد من منصات التواصل الاجتماعي، مثل Instagram وPinterest، Python في الخلفية. -يستخدم محترفو الأمن السيبراني والقراصنة الأخلاقيون Python لاكتشاف الثغرات مثل البرمجيات الخبيثة والفيروسات، وبناء فحوصات أمنية مؤتمتة، وتحليل التهديدات. +يستخدم محترفو الأمن السيبراني والقراصنة الأخلاقيون Python لاكتشاف الثغرات والبرمجيات الخبيثة، وبناء فحوصات أمنية آلية، وتحليل التهديدات. -يعمل Python جيدًا على الحواسيب الصغيرة مثل Raspberry Pi واللوحات المتوافقة مع MicroPython، لذا يمكنك بناء جميع أنواع مشاريع إنترنت الأشياء مثل أجهزة المنزل الذكية، محطات مراقبة الطقس، وأكثر. +يعمل Python جيدًا على الحواسيب الصغيرة مثل Raspberry Pi واللوحات المتوافقة مع MicroPython، لذا يمكنك بناء جميع أنواع مشاريع إنترنت الأشياء، مثل أجهزة المنزل الذكي ومحطات مراقبة الطقس. -يُستخدم Python على نطاق واسع في DevOps لكتابة نصوص CI/CD وإدارة البنية التحتية عبر خطوط تطوير البرمجيات. كما يُستخدم عادة لبناء خدمات خلفية وواجهات برمجة تطبيقات داخلية. +في DevOps، يُستخدم Python على نطاق واسع لكتابة سكربتات CI/CD وإدارة البنية التحتية عبر خطوط تطوير البرمجيات. كما يُستخدم عادة لبناء خدمات الخلفية وواجهات برمجة التطبيقات الداخلية. -في اختبار البرمجيات، تُستخدم أدوات Python مثل pytest لإنشاء مجموعات اختبار موثوقة، بينما يعتمد مسؤولو النظام على Python لمراقبة الخوادم، إدارة السجلات، والمهام على مستوى النظام. +في اختبار البرمجيات، يُستخدم Python لإنشاء مجموعات اختبار موثوقة، بينما يعتمد مسؤولو النظام على Python لمراقبة الخوادم، وإدارة السجلات، والمهام على مستوى النظام. -أخيرًا، من أكبر نقاط قوة Python هي الأتمتة. يمكنك كتابة نصوص بسيطة تساعدك في المهام المتكررة مثل استخراج البيانات من جداول البيانات، إرسال البريد الإلكتروني، والعمل مع الملفات على جهازك المحلي. +أخيرًا، من أكبر نقاط قوة Python هو الأتمتة. يمكنك كتابة سكربتات بسيطة للتعامل مع المهام المتكررة مثل استخراج البيانات من جداول البيانات، وإرسال البريد الإلكتروني، والعمل مع الملفات على جهازك المحلي. -تُسهّل مكتبات مثل Selenium وBeautifulSoup التفاعل مع مواقع الويب، بحيث يمكنك جمع البيانات العامة، أتمتة المهام عبر واجهة ويب، وحتى إدارة عمليات التشغيل السحابية لمشاريعك. - -كما ترى، Python لغة قوية جدًا، ومع ذلك سهلة التعلم. من نصوص الأتمتة البسيطة إلى التطبيقات الصناعية واسعة النطاق، يمكنك استخدام Python لأي شيء تقريبًا. +كما ترى، Python لغة قوية جدًا، ومع ذلك سهلة التعلم. من سكربتات الأتمتة البسيطة إلى التطبيقات الصناعية واسعة النطاق، يمكنك استخدام Python لأي شيء تقريبًا. Python خيار رائع لأي شخص يريد تعلم البرمجة، بغض النظر عن التخصص الذي يختاره لاحقًا. @@ -35,35 +33,35 @@ Python خيار رائع لأي شخص يريد تعلم البرمجة، بغض ## --text-- -ما هي المكتبات التي تُستخدم عادة لتحليل البيانات في Python؟ +كيف يستخدم علماء البيانات Python؟ ## --answers-- -Pandas وNumPy +لتنظيف المعلومات غير المنظمة، وحساب الإحصائيات، واكتشاف الأنماط، وإنشاء المخططات. --- -TensorFlow وScikit-learn +لتصميم التخطيط البصري لصفحات الويب. ### --feedback-- -فكر في المكتبات التي تساعد في التعامل مع مجموعات البيانات الكبيرة ومعالجتها بكفاءة. +فكر في ما ينطوي عليه العمل مع البيانات. --- -React وVue +لبناء الأجهزة لأجهزة المنزل الذكي. ### --feedback-- -فكر في المكتبات التي تساعد في التعامل مع مجموعات البيانات الكبيرة ومعالجتها بكفاءة. +فكر في ما ينطوي عليه العمل مع البيانات. --- -Django وFlask +لاستبدال جداول البيانات وقواعد البيانات بالكامل. ### --feedback-- -فكر في المكتبات التي تساعد في التعامل مع مجموعات البيانات الكبيرة ومعالجتها بكفاءة. +فكر في ما ينطوي عليه العمل مع البيانات. ## --video-solution-- @@ -107,35 +105,35 @@ Django وFlask ## --text-- -ما هي أُطُر عمل Python المستخدمة في تطوير الويب؟ +أي جزء من موقع الويب يُستخدم Python فيه غالبًا في تطوير الويب؟ ## --answers-- -React وVue وAngular +ألوان وخطوط الصفحة. ### --feedback-- -فكر في الأُطُر التي تساعد مطوري الويب على بناء أنظمة خلفية قابلة للتوسع. +فكر في الجزء من موقع الويب الذي يعمل خلف الكواليس. --- -TensorFlow وPyTorch وScikit-learn +الرسوم المتحركة التي يراها المستخدمون عند التمرير. ### --feedback-- -فكر في الأُطُر التي تساعد مطوري الويب على بناء أنظمة خلفية قابلة للتوسع. +فكر في الجزء من موقع الويب الذي يعمل خلف الكواليس. --- -NumPy وPandas وMatplotlib +تخطيط الأزرار والصور. ### --feedback-- -فكر في الأُطُر التي تساعد مطوري الويب على بناء أنظمة خلفية قابلة للتوسع. +فكر في الجزء من موقع الويب الذي يعمل خلف الكواليس. --- -Django وFastAPI وFlask +جانب الخادم، يتولى مهام مثل حسابات المستخدمين، وإرسال النماذج، وحفظ المعلومات. ## --video-solution-- diff --git a/curriculum/challenges/arabic/blocks/lecture-introduction-to-strings/672d49c4e899345f5b33c24c.md b/curriculum/challenges/arabic/blocks/lecture-introduction-to-strings/672d49c4e899345f5b33c24c.md index 93c721672c1..705883146d9 100644 --- a/curriculum/challenges/arabic/blocks/lecture-introduction-to-strings/672d49c4e899345f5b33c24c.md +++ b/curriculum/challenges/arabic/blocks/lecture-introduction-to-strings/672d49c4e899345f5b33c24c.md @@ -1,6 +1,6 @@ --- id: 672d49c4e899345f5b33c24c -title: ما هو استخدام console.log()، وكيف يعمل؟ +title: ما هو استخدام console.log()‎، وكيف يعمل؟ challengeType: 19 dashedName: what-is-console-log --- diff --git a/curriculum/challenges/arabic/blocks/lecture-python-installation/67fe8567f141d632afaeb71b.md b/curriculum/challenges/arabic/blocks/lecture-python-installation/67fe8567f141d632afaeb71b.md index 8b462e8e01f..af1b582e6db 100644 --- a/curriculum/challenges/arabic/blocks/lecture-python-installation/67fe8567f141d632afaeb71b.md +++ b/curriculum/challenges/arabic/blocks/lecture-python-installation/67fe8567f141d632afaeb71b.md @@ -7,12 +7,18 @@ dashedName: how-do-you-install-configure-and-use-python-in-your-local-environmen # --description-- +## لماذا تثبت Python محليًا؟ + في جميع ورش العمل والمختبرات، ستستخدم محرر Python الخاص بـ freeCodeCamp. لكن من المهم أن تتعلم كيفية إعداد Python على جهازك المحلي. +## تنزيل Python + أسهل طريقة لتثبيت Python على ويندوز وماك هي تنزيل المثبت من الموقع الرسمي لـ Python. سنشرح أيضًا كيفية تشغيل Python على لينكس لاحقًا في هذا الدرس. اذهب إلى `https://www.python.org/` وحرك المؤشر فوق "التنزيلات". ستظهر نافذة منبثقة تعرض الإصدار الحالي من Python لنظام التشغيل الخاص بك. +## تثبيت Python على macOS + سنبدأ بشرح كيفية تثبيت Python على جهاز يعمل بنظام macOS أولاً: - انقر على الزر الذي يعرض الإصدار الحالي من Python (من النافذة السابقة)، وسيبدأ تنزيل ملف تثبيت `.pkg` تلقائيًا. @@ -22,14 +28,22 @@ dashedName: how-do-you-install-configure-and-use-python-in-your-local-environmen - بعد ذلك، يجب أن تظهر رسالة تهنئة تفيد بأن Python تم تثبيته بنجاح. - انقر على زر "إغلاق"، وبهذا تكون انتهيت! +## التحقق من التثبيت + يمكنك التحقق من التثبيت بفتح الطرفية وتشغيل الأمر `python --version` أو `python3 --version`. يمكنك أيضًا فتح مفسر Python بتشغيل `python` أو `python3` في الطرفية. مفسر Python هو البرنامج الذي يقرأ كود Python، يترجمه إلى تعليمات يفهمها الكمبيوتر وينفذ تلك التعليمات. +## ما هو الطرفية؟ + الطرفية هي واجهة نصية تتيح لك التفاعل مع جهاز الكمبيوتر بكتابة الأوامر. كل نظام تشغيل يأتي مع تطبيق طرفية افتراضي. على macOS، يمكنك استخدام تطبيق Terminal. على ويندوز، يمكنك استخدام Command Prompt أو PowerShell. على لينكس، لكل بيئة سطح مكتب تطبيق طرفية افتراضي خاص بها، مثل GNOME Terminal أو Konsole. +## استخدام `python` مقابل `python3` + لاحظ أنه في بعض أنظمة macOS وLinux القديمة، قد يكون `python` مخصصًا لـ Python 2، بينما `python3` مخصص لـ Python 3 تحديدًا. إذا شغلت `python --version` ورأيت إصدار Python 2 مثل `Python 2.7.18`، فمن المحتمل أن نظام التشغيل يعتمد على بعض البرامج المكتوبة بالإصدار القديم من Python. في هذه الحالة، يجب استخدام `python3` لتشغيل كود Python الخاص بك من الآن فصاعدًا. Python 2 انتهى عمره الافتراضي ولا يجب استخدامه لأي تطوير جديد. +## تثبيت Python على Windows + لتثبيت Python على ويندوز، اتبع الخطوات التالية: - اذهب إلى `https://www.python.org/`، وحرك المؤشر فوق "التنزيلات". سترى نافذة تقول "تنزيل لويندوز" وزر تنزيل مع الإصدار الحالي من Python. @@ -40,6 +54,8 @@ dashedName: how-do-you-install-configure-and-use-python-in-your-local-environmen يمكنك التحقق من التثبيت بفتح واجهة سطر الأوامر مثل PowerShell وتشغيل `python --version`. يمكنك أيضًا فتح مفسر Python بتشغيل `python`. +## تثبيت Python على Linux + بالنسبة لـ Python على لينكس، معظم التوزيعات الرئيسية مثل أوبونتو، ديبيان، وفيدورا تأتي مع Python مثبتة. فقط افتح الطرفية وشغّل `python --version` أو `python3 --version`: diff --git a/curriculum/challenges/arabic/blocks/lecture-python-installation/69fd6b21fcaa14b089c27182.md b/curriculum/challenges/arabic/blocks/lecture-python-installation/69fd6b21fcaa14b089c27182.md index a24ba4049ee..c53ac8ac3da 100644 --- a/curriculum/challenges/arabic/blocks/lecture-python-installation/69fd6b21fcaa14b089c27182.md +++ b/curriculum/challenges/arabic/blocks/lecture-python-installation/69fd6b21fcaa14b089c27182.md @@ -7,6 +7,8 @@ dashedName: how-to-run-python-scripts # --description-- +## تثبيت محرر كود أو بيئة تطوير متكاملة + في الدرس السابق، تعلمت كيفية تثبيت Python على جهازك المحلي. في هذا الدرس، ستتعلم كيفية تشغيل كود Python محليًا. قبل أن تبدأ في بناء سكريبتات Python محليًا، تحتاج إلى تثبيت محرر كود أو بيئة تطوير متكاملة (IDE). تعني IDE بيئة التطوير المتكاملة، وتحتوي على ميزات تشمل محرر كود، أدوات اختبار، محطة طرفية والمزيد. @@ -18,6 +20,8 @@ dashedName: how-to-run-python-scripts - PyCharm - Spyder +## إنشاء ملف Python + بعد تحميل المحرر، افتحه. بعد الفتح، تحتاج إلى فتح مجلد. انقر على خيار قائمة `File` في الزاوية العلوية اليسرى ثم انقر على `Open Folder`. من هناك، يمكنك اختيار مجلد أو إنشاء مجلد لمشروعك. للممارسة الإضافية خارج الدرس، قد ترغب في مجلد باسم `python-projects`. بمجرد إعداد المجلد، يمكنك فتح المستكشف وهو الشريط الجانبي الأيسر في VS Code. انقر على أيقونة `New File` التي تشبه ورقة مع رمز زائد فوقها. ثم أنشئ ملفًا باسم `main.py` واضغط Enter. الامتداد `.py` يشير إلى أن هذا ملف Python. @@ -28,6 +32,8 @@ dashedName: how-to-run-python-scripts print("Hello, world!") ``` +## تشغيل سكريبت Python الخاص بك + لتشغيل هذا الكود، لديك عدة خيارات. الخيار الأول هو النقر على زر التشغيل الذي يشبه زر التشغيل الموجود في الزاوية العلوية اليمنى. هذا سيفتح محطة طرفية ويشغّل سكريبت Python هناك. يجب أن ترى النص `"Hello, world!"`. خيار آخر هو فتح محطة طرفية وتشغيل البرنامج يدويًا باستخدام: @@ -48,6 +54,8 @@ cd python-projects python main.py ``` +## استخدام `python3` بدلاً من `python` + في بعض بيئات العمل، خاصة على أنظمة macOS وLinux حيث يتم تثبيت Python 2 وPython 3 معًا، قد تحتاج إلى استخدام `python3` بدلًا من `python`. هذا شائع عندما لا يوجد أمر `python` أو يشير إلى إصدار أقدم من Python. ```bash diff --git a/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5b78609f97400923f7f.md b/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5b78609f97400923f7f.md index f031e1c52c2..66a5603b65d 100644 --- a/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5b78609f97400923f7f.md +++ b/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5b78609f97400923f7f.md @@ -19,10 +19,14 @@ dashedName: what-are-state-management-libraries-and-when-should-you-use-them لنلقِ نظرة على بعض خيارات إدارة الحالة المختلفة المتاحة لديك، ومتى تستخدمها. +## واجهة برمجة التطبيقات للسياق + واجهة برمجة التطبيقات Context API هي مدير حالة مدمج في React يتيح لك مشاركة الحالة عبر المكوّنات دون استخدام مكتبة خارجية. إنها ترقية معتمدة على خطاف `useState`، لذا فهي مثالية لحالات مثل تبديل السمات أو حالة توثيق المستخدم. مع ذلك، لا تتعامل Context API بشكل جيد مع التحديثات المتكررة، وقد تسبب إعادة عرض غير ضرورية، مما يجعلها أقل ملاءمة لاحتياجات الحالة المعقدة في تطبيقات مثل التجارة الإلكترونية ومنصات التواصل الاجتماعي. +### إنشاء السياق + إليك مكوّن عداد يوضح الاستخدام الأساسي لـ Context API: ```jsx @@ -49,6 +53,8 @@ export { CounterContext, CounterProvider }; لذا، عندما تغلف تطبيقك بالكامل بـ `CounterProvider`، تصبح حالة `count` متاحة في كل مكان داخل التطبيق. +### تغليف التطبيق + إليك كيفية تغليف `CounterProvider` حول تطبيقك: ```jsx @@ -65,6 +71,8 @@ function App() { export default App; ``` +### استخدام السياق + وهنا كيفية استخدام حالة `count`: ```jsx @@ -97,6 +105,8 @@ export default Counter; ثم تُعرض حالة `count` الحالية، وتُستخدم `setCount` لزيادة أو تقليل حالة `count` عند نقر المستخدم على أزرار النقص والزيادة على التوالي. +## Redux + مكتبة إدارة الحالة الشهيرة الأخرى هي Redux، وهي واحدة من أكثر المكتبات استخدامًا مع React. موجودة منذ فترة طويلة، ومثالية للتطبيقات الكبيرة مثل التجارة الإلكترونية ومنصات التواصل الاجتماعي والمنتديات، وغيرها. يدير Redux الحالة من خلال توفير مخزن مركزي وتحكم صارم في تحديثات الحالة. يستخدم نمطًا متوقعًا مع الإجراءات، والمخفضات، والبرمجيات الوسيطة. @@ -111,6 +121,8 @@ export default Counter; عادةً ما تعرف الإجراءات والمخفضات في ملف واحد باستخدام دالة `createSlice()`. من الشائع تسمية الملف بحيث ينتهي بكلمة `Slice`، مثل `productSlice`، `userSlice`، `counterSlice`، وهكذا. +### ملف `counterSlice` + إليك ملف `counterSlice` ليعرض لك الأساسيات: ```jsx @@ -138,12 +150,16 @@ export default counterSlice.reducer; من هنا، تحتاج إلى تغليف التطبيق بالكامل بـ `Provider`، اختيار جزء من الحالة من الشريحة باستخدام `useSelector()`، ثم استخدام `useDispatch()` لتنشيط الحالة. +## Zustand + خيار آخر للنظر فيه هو Zustand. Zustand هي مكتبة خفيفة لإدارة الحالة بواجهة برمجة تطبيقات بسيطة. تعتمد على الـ hooks، لذا هناك قالب جاهز أقل مقارنة بـ Redux، مما يجعل الإعداد أسهل وأسرع. Zustand مثالية للتطبيقات الصغيرة إلى المتوسطة الحجم. تعمل باستخدام خطاف `useStore` للوصول إلى الحالة مباشرة في المكوّنات والصفحات. هذا يتيح لك تعديل والوصول إلى البيانات دون الحاجة إلى إجراءات، أو مخفضات، أو موفر. +### مثال عداد باستخدام Zustand + إليك `useCounterStore` التي تنفذ وظيفة عداد أخرى: ```jsx diff --git a/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5dacd5e0c749e5d534c.md b/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5dacd5e0c749e5d534c.md index bbb0364ccce..af10f4d1602 100644 --- a/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5dacd5e0c749e5d534c.md +++ b/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5dacd5e0c749e5d534c.md @@ -11,12 +11,16 @@ dashedName: how-can-you-debug-your-react-components-using-react-devtools مع ذلك، فهي ليست مثالية للعثور على الأخطاء البرمجية وإصلاحها في تطبيقات React. لذلك، طوّر فريق React أداة تسمى "أدوات مطوِّر React" (المعروفة أيضًا باسم React DevTools) لتتمكن من فحص وتصحيح وتحليل تطبيقات React. +## تثبيت أدوات مطوِّر React + تتوفر React DevTools كإضافة للمتصفح لكل من Chrome وEdge وFirefox. إذا كنت تستخدم Chrome أو Edge، توجه إلى متجر Chrome الإلكتروني، وابحث عن "React Developer Tools"، وأضفها إلى متصفحك. وإذا كنت تستخدم Firefox، توجه إلى صفحة الإضافات الخاصة بـ Firefox، وابحث عن الأداة، وأضفها إلى متصفحك. إذا كنت تستخدم Safari، يمكنك تثبيت React DevTools من npm عبر تشغيل الأمر `npm install -g react-devtools` أو `yarn global add react-devtools`. +## استكشاف علامات تبويب المكوِّنات والمُحلل + بعد تثبيت وتمكين React DevTools، إذا فتحت تطبيق React في متصفحك ثم فتحت أدوات المطوِّر في المتصفح، سترى تبويبين إضافيين: Components وProfiler. يعرض تبويب Components كل مكوِّن لك في شكل عرض شجري. يمكنك من خلاله: @@ -29,6 +33,8 @@ dashedName: how-can-you-debug-your-react-components-using-react-devtools من ناحية أخرى، يساعدك تبويب Profiler على تسجيل وتحليل أداء المكونات لتتمكن من تحديد عمليات إعادة العرض غير الضرورية، وعرض مدة الالتزام، والأمور التي يمكنك تحسينها. +## فحص المكوِّنات والخصائص والحالة + إليك تطبيقًا بسيطًا يوضح لك كيف يمكنك فحص المكونات وأي خصائص وحالات تمتلكها. هذا مشابه للكود الذي استخدمناه في درس سابق عن تمرير الخصائص (prop drilling): ```jsx @@ -73,6 +79,8 @@ const Grandchild = ({ greeting, response }) => { لتسجيل بيانات في مكوِّن إلى وحدة التحكم، افحص عناصر DOM المطابقة واطلع على الكود المصدري للمكوِّن. الأيقونات في الزاوية العلوية اليمنى تتيح لك ذلك. إذا اخترت مكوِّن `Grandchild` ونقرت على زر `Log the component data to the console`، فسيسجل الخصائص والحالة والهوكس والعقد وبيانات أخرى في وحدة التحكم. +## معالجة أخطاء عدم تطابق الخصائص + خطأ شائع قد تواجهه في React يسمى عدم تطابق الخصائص (props mismatch). على سبيل المثال، لنفترض أنك في مكوِّن `Child` مررت خاصية `reply` بدلًا من `response` عن طريق الخطأ: diff --git a/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5f19a0f0b75343f1905.md b/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5f19a0f0b75343f1905.md index 695f6d31cab..3bd6f74aa12 100644 --- a/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5f19a0f0b75343f1905.md +++ b/curriculum/challenges/arabic/blocks/lecture-react-strategies-and-debugging/67d2f5f19a0f0b75343f1905.md @@ -11,6 +11,8 @@ dashedName: what-are-react-server-components-and-how-do-they-work لنلقِ نظرة على ماهية مكونات الخادم، كيف تعمل، وما الذي أدى إلى تقديم مكونات الخادم. +## ما هي مكوِّنات خادم React؟ + مكونات خادم React هي مكونات React تُعرض حصريًا على الخادم، الذي يرسل فقط HTML النهائي إلى العميل. هذا يعني أن تلك المكونات يمكنها الوصول مباشرة إلى موارد الخادم وتقليل كمية جافاسكريبت المرسلة إلى المتصفح بشكل كبير. تقليديًا، تستخدم تطبيقات React نظام "مكونات العميل" الذي يتولى كل شيء في تطبيق React النموذجي، مثل العرض، التفاعل، والآثار الجانبية. لم يكن مصطلح "مكون العميل" يُستخدم كثيرًا حتى ظهور مكونات خادم React مؤخرًا. @@ -23,6 +25,8 @@ dashedName: what-are-react-server-components-and-how-do-they-work انتشرت مكونات الخادم أولًا وأصبحت متاحة بسهولة في Next.js. أُطُر أخرى مثل Remix وGatsby تلحق بالركب، وهناك إضافة تجريبية لـ Vite تسمى `vite-plugin-react-server` تتيح لك بناء مكونات خادم. +## جلب البيانات باستخدام مكوِّنات الخادم + فكيف تعمل مكونات الخادم؟ واحدة من أفضل الطرق لشرح مكونات خادم React هي من خلال جلب البيانات. @@ -55,6 +59,8 @@ export default Users; بما أن مكونات خادم React تعمل فقط على الخادم، يمكنك ببساطة جلب البيانات من API وعرضها مرة واحدة فقط. أيضًا، بما أن جلب البيانات يحدث على الخادم، أقرب إلى المصدر، قد يتحسن أداء تطبيقك، خاصة للأشخاص ذوي الاتصالات الشبكية البطيئة. +## إضافة التفاعل باستخدام مكوِّنات العميل + مشكلة كبيرة هي أن كل الكود الخاص بمكوِّنات الخادم يبقى على الخادم ولا يُرسل إلى المتصفح. هذا يعني أنك لا تستطيع استخدام React hooks معها، ولا يمكنها الوصول إلى واجهات برمجة تطبيقات الويب أو مستمعي الأحداث في المتصفح. فكيف تضيف التفاعل؟ في موجِّه تطبيق Next.js، كل المكونات هي مكونات خادم افتراضيًا. إذا أردت إضافة التفاعل، يجب أن تحدد المكون كمكون عميل باستخدام توجيه `"use client"`. @@ -117,6 +123,8 @@ const Users2 = () => { export default Users2; ``` +### التعامل مع أحداث النقر + إذا أردت إضافة تفاعل مثل أحداث النقر، يجب أيضًا تحديد المكون كمكون عميل: ```jsx diff --git a/curriculum/challenges/arabic/blocks/lecture-routing-react-frameworks-and-dependency-management-tools/67d1ab248317a5a29058a763.md b/curriculum/challenges/arabic/blocks/lecture-routing-react-frameworks-and-dependency-management-tools/67d1ab248317a5a29058a763.md index 567342c62f9..300c28573e6 100644 --- a/curriculum/challenges/arabic/blocks/lecture-routing-react-frameworks-and-dependency-management-tools/67d1ab248317a5a29058a763.md +++ b/curriculum/challenges/arabic/blocks/lecture-routing-react-frameworks-and-dependency-management-tools/67d1ab248317a5a29058a763.md @@ -15,6 +15,8 @@ dashedName: what-is-dependency-management-and-how-does-it-work-with-libraries-li لإدارة تبعيات البرمجيات في مشروع، ستحتاج إلى استخدام مدير حزم. مدير الحزم هو أداة تُستخدم للتثبيت والتحديث والإزالة للتبعيات. العديد من لغات البرمجة الشهيرة مثل JavaScript وPython وRuby وJava تستخدم مديري حزم. +## تثبيت التبعيات باستخدام npm + في درس سابق، تم تقديم مدير الحزم الشهير npm بشكل موجز. لإنشاء مشروع React جديد باستخدام Vite وnpm يمكنك تشغيل الأمر التالي: @@ -25,14 +27,20 @@ npm create vite@latest my-react-app -- --template react كما تتذكر من الدروس السابقة، هذا سينشئ كل كود القالب الجاهز اللازم لإطلاق تطبيق React جديد. قبل أن تطلق التطبيق، ستحتاج إلى تثبيت التبعيات عبر تشغيل `npm install` أو اختصارًا `npm i`. +## ملف `package.json` + يمكنك عرض كل التبعيات في ملف `package.json` الموجود في الدليل الجذري لمشروعك. ملف `package.json` هو ملف تكوين رئيسي في المشاريع يحتوي على بيانات وصفية عن مشروعك، بما في ذلك اسمه، وإصداره، وتبعياته. كما يحدد السكربتات، ومعلومات الترخيص، وإعدادات أخرى تساعد في إدارة المشروع وتبعياته. +## مجلد `node_modules` + عند تثبيت التبعيات، سيُضاف مجلد `node_modules` إلى مشروعك. مجلد `node_modules` هو المكان الذي تُخزن فيه جميع الحزم والمكتبات المطلوبة لمشروعك. يحتوي هذا المجلد على الكود الفعلي للتبعيات المدرجة في ملف `package.json`، بما في ذلك التبعيات المباشرة لمشروعك وأي تبعيات لتلك التبعيات. +## التبعيات + التبعيتان الأساسيتان اللازمتان لمشروع React هما حزمتا `react` و`react-dom`: ```json @@ -44,8 +52,12 @@ npm create vite@latest my-react-app -- --template react سيُدرج ملف `package.json` الإصدارات الحالية التي تستخدمها لتلك الحزم. إذا احتجت إلى تحديث أي حزمة محليًا، يمكنك تشغيل الأمر `npm update`. أو يمكنك تحديث كل الحزم عالميًا بتشغيل الأمر `npm update -g`. +## ملف `package-lock.json` + بالإضافة إلى ملف `package.json`، سيكون لديك أيضًا ملف `package-lock.json`. هذا الملف يُثبت الإصدارات الدقيقة لكل الحزم التي يستخدمها مشروعك. عند تحديث حزمة، تُحدث الإصدارات الجديدة في ملف القفل أيضًا. +## تبعيات التطوير + جانب مهم آخر في ملف `package.json` هو التبعيات الخاصة بالتطوير: ```json @@ -65,6 +77,8 @@ npm create vite@latest my-react-app -- --template react التبعيات الخاصة بالتطوير هي حزم تُستخدم فقط أثناء التطوير وليس في الإنتاج. مثال على ذلك مكتبة اختبار مثل Jest. تثبت Jest كتبعيات تطوير لأنك تستخدمها فقط لاختبار مشروعك محليًا، ولا تحتاجها لتشغيل التطبيق في الإنتاج. +## اختيار مدير الحزم + لجزء كبير من هذا الدرس، ركزنا على npm. لكن هناك مديري حزم آخرين مثل yarn وpnpm. إذًا، أي مدير حزم يجب أن تستخدم لمشروعك؟ الإجابة المختصرة هي: يعتمد الأمر. diff --git a/curriculum/challenges/arabic/blocks/lecture-searching-and-sorting-algorithms/68420c70e4bfe26d52b780dc.md b/curriculum/challenges/arabic/blocks/lecture-searching-and-sorting-algorithms/68420c70e4bfe26d52b780dc.md index 9965081bf75..b9cecb53976 100644 --- a/curriculum/challenges/arabic/blocks/lecture-searching-and-sorting-algorithms/68420c70e4bfe26d52b780dc.md +++ b/curriculum/challenges/arabic/blocks/lecture-searching-and-sorting-algorithms/68420c70e4bfe26d52b780dc.md @@ -9,6 +9,8 @@ dashedName: what-is-binary-search-and-how-does-it-differ-from-linear-search البحث في قائمة من العناصر أمر شائع في علوم الحاسوب. هناك خوارزميتان رئيسيتان يجب أن تعرفهما عند الحديث عن البحث: البحث الخطي والبحث الثنائي. +## ما هو البحث الخطي؟ + يبدأ البحث الخطي من بداية القائمة ويكرر المرور عبر كل عنصر حتى يجد القيمة المستهدفة التي يبحث عنها. إذا وُجدت القيمة المستهدفة، يُعاد الفهرس الذي تقع فيه في القائمة. إذا لم تُوجد القيمة المستهدفة، يُعاد `-1`. نُعيد `-1` لأنه ليس فهرسًا صالحًا في معظم لغات البرمجة. @@ -27,18 +29,24 @@ def linear_search(arr, target): إذا غيرنا القيمة المستهدفة إلى `5`، فستُعيد الدالة `-1` لأن `5` غير موجودة في القائمة. +## تعقيد الوقت والمساحة للبحث الخطي + رغم أن هذه خوارزمية بسيطة نسبيًا، إلا أنها ليست الأكثر كفاءة. إذا كانت لديك قائمة كبيرة من العناصر، قد يستغرق البحث الخطي وقتًا طويلًا للعثور على القيمة المستهدفة. تعقيد الزمن للبحث الخطي هو `O(n)` لأن الوقت الذي يستغرقه البحث في القائمة ينمو خطيًا مع حجم القائمة. تعقيد المساحة للبحث الخطي هو `O(1)` لأنه لا يتطلب مساحة إضافية للبحث في القائمة. +## ما هو البحث الثنائي؟ + البحث الثنائي هو خوارزمية أكثر كفاءة للبحث في قائمة كبيرة من العناصر. الشرط هنا هو أن تكون القائمة مرتبة تصاعديًا. يعمل البحث الثنائي عن طريق تقسيم القائمة إلى نصفين والتحقق مما إذا كانت القيمة المستهدفة في منتصف القائمة. إذا كانت القيمة المستهدفة في منتصف القائمة، يُعاد فهرس القيمة المستهدفة. وإلا، تتحقق الخوارزمية مما إذا كانت القيمة المستهدفة في النصف الأيسر أو الأيمن من القائمة. يستمر في تقسيم الأجزاء المتبقية من القائمة إلى أنصاف حتى يُعثر على القيمة المستهدفة. إذا لم تكن القيمة المستهدفة في القائمة، يعيد `-1`. +## تنفيذ البحث الثنائي + هذا هو شكل الكود الخاص بالبحث الثنائي: ```python @@ -71,10 +79,14 @@ def binary_search(arr, target): نستمر في تكرار هذه العملية حتى نجد الهدف أو نحدد أن الهدف غير موجود في القائمة. +## تعقيد الوقت والمساحة للبحث الثنائي + تعقيد الزمن للبحث الثنائي هو `O(log n)` لأن الوقت الذي يستغرقه البحث في القائمة ينمو لوغاريتميًا مع حجم القائمة. تعقيد المساحة للبحث الثنائي هو `O(1)` لأنه لا يتطلب مساحة إضافية للبحث في القائمة. +## الخلاصة + يمكن استخدام البحث الثنائي والبحث الخطي لمجموعة متنوعة من المشكلات التي ستواجهها في علوم الحاسوب. من المهم فهم الفروقات بين الخوارزميتين ومتى تستخدم كل واحدة منهما. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-styling-lists-and-links/672b951b1bf78038b1a2a0e7.md b/curriculum/challenges/arabic/blocks/lecture-styling-lists-and-links/672b951b1bf78038b1a2a0e7.md index 13c34d6954d..3e3a1126611 100644 --- a/curriculum/challenges/arabic/blocks/lecture-styling-lists-and-links/672b951b1bf78038b1a2a0e7.md +++ b/curriculum/challenges/arabic/blocks/lecture-styling-lists-and-links/672b951b1bf78038b1a2a0e7.md @@ -19,6 +19,8 @@ dashedName: how-do-the-different-list-style-properties-work كل واحدة منها تلعب دورًا مختلفًا في تحديد مظهر القوائم. +## `list-style-type` + تسمح لك الخاصية `list-style-type` بتحديد نوع نقطة التعداد أو الرقم المستخدم في القائمة. بالنسبة للقوائم غير المرتبة، يمكنك الاختيار من بين عدة أنماط لنقاط التعداد، مثل الأقراص، الدوائر، أو المربعات. @@ -43,6 +45,8 @@ dashedName: how-do-the-different-list-style-properties-work تُعد الخاصية `list-style-type` الأكثر استخدامًا من بين الثلاث، لأنها تؤثر مباشرة على مظهر نقطة التعداد أو نمط الترقيم في قوائمك. +## `list-style-position` + تتحكم الخاصية `list-style-position` في موضع نقطة التعداد أو الرقم بالنسبة لمحتوى عنصر القائمة. هناك قيمتان يمكنك استخدامهما: `inside` و `outside`. عند استخدام القيمة `outside`، تظهر نقطة التعداد أو الرقم خارج المحتوى، وهو السلوك الافتراضي. @@ -72,6 +76,8 @@ dashedName: how-do-the-different-list-style-properties-work يمكن أن تكون الخاصية `list-style-position` مفيدة عندما تريد التحكم في محاذاة محتوى القائمة، خاصة في الحالات التي تحتوي فيها عناصر القائمة على عدة أسطر من النص. +## `list-style-image` + تسمح لك الخاصية `list-style-image` باستخدام صورة كنقطة تعداد لعناصر قائمتك. يمكن أن يكون هذا مفيدًا لإضافة نمط بصري فريد لقوائمك. إليك مثالًا على استخدام `list-style-image`: @@ -102,6 +108,8 @@ dashedName: how-do-the-different-list-style-properties-work عند استخدام `list-style-image`، تأكد من أن الصورة التي تختارها صغيرة ومناسبة لتصميم صفحة الويب. إذا كانت الصورة كبيرة جدًا أو معقدة، قد يصعب قراءة القائمة. +## الخاصية المختصرة `list-style` + يمكنك دمج الخصائص الثلاث — `list-style-type`، `list-style-position`، و `list-style-image` — في خاصية مختصرة واحدة هي `list-style`. ترتيب القيم في الخاصية المختصرة لا يهم، لكن يمكن تحديد الثلاث معًا. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-abstraction/68c3bc80f67363a31791fe1c.md b/curriculum/challenges/arabic/blocks/lecture-understanding-abstraction/68c3bc80f67363a31791fe1c.md index 8ccccce486a..64c6f6a739e 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-abstraction/68c3bc80f67363a31791fe1c.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-abstraction/68c3bc80f67363a31791fe1c.md @@ -9,16 +9,22 @@ dashedName: what-is-abstraction-and-how-does-it-help-keep-complex-systems-organi بعد أن استعرضنا التغليف والوراثة وتعدد الأشكال، دعنا نناقش المفهوم الرئيسي التالي في البرمجة كائنية التوجه – التجريد. +## ما هو التجريد؟ + التجريد هو عملية إخفاء تفاصيل التنفيذ المعقدة وإظهار الميزات الأساسية فقط لكائن أو نظام. فكر فيه على أنه تركيز على ما يفعله الشيء بدلاً من كيفية فعله. التجريد ليس مقتصرًا على Python فقط. إنه مفهوم برمجي يمكن تنفيذه في العديد من اللغات التي تدعم البرمجة كائنية التوجه. +## مثال واقعي على التجريد + لتوضيح التجريد، تخيل أنك تقود سيارة. عندما تكون في مقعد السائق، تتفاعل مع الأجزاء الأساسية مثل عجلة القيادة، وذراع التغيير، ودواسات الوقود والفرامل. لا تحتاج إلى معرفة التفاصيل الدقيقة لكيفية عمل المحرك، أو كيفية تغيير التروس في ناقل الحركة، أو الفيزياء وراء نظام الفرامل، إذ إن كل ذلك هو تفاصيل تنفيذ معقدة. هذا هو التجريد يعمل! فهو يوفر لك واجهة مبسطة للتفاعل مع نظام معقد. في حالة السيارة مرة أخرى، الواجهة المبسطة هي عجلة القيادة والفرامل ودواسة الوقود، بينما النظام المعقد هو السيارة نفسها. +## التجريد في Python باستخدام وحدة `abc` + أما كيف ينفذ Python التجريد، فهو يتم عبر وحدة `abc`. تقدم هذه الوحدة الصنف `ABC` (الذي يعني “الصنف الأساسي المجرد”) وزخرفة `@abstractmethod`. @@ -27,6 +33,8 @@ dashedName: what-is-abstraction-and-how-does-it-help-keep-complex-systems-organi من ناحية أخرى، الطريقة المجردة هي طريقة معلنة في صنف أساسي مجرد (ABC) باستخدام زخرفة `@abstractmethod`. قد لا تحتوي على تنفيذ أو تحتوي على تنفيذ افتراضي بسيط. ومع ذلك، يجب على أي صنف فرعي تجاوزها ليُعتبر ملموسًا وقابلًا للإنشاء، حتى لو وُجد تنفيذ افتراضي. +## صيغة الصنف المجرد + إليك الصيغة النحوية الأساسية للصنف المجرد في Python: ```py @@ -49,6 +57,8 @@ class ConcreteClassTwo(AbstractClass): print('Implementation in ConcreteClassTwo') ``` +## استخدام صنف أساسي مجرد + إليك مثالًا أساسيًا: ```py @@ -94,6 +104,8 @@ for animal in animals: - ننشئ الأصناف الملموسة `Dog` و`Cat` و`Monkey`، التي يجب أن تتجاوز الطريقة المجردة `make_sound`. - ننشئ كائنات من الأصناف الملموسة وندعو طريقتهم `make_sound` لنُظهر كيف ينفذ كل منها الطريقة المجردة `make_sound` بطريقته الخاصة. +## لا يمكن إنشاء نسخ من الأصناف المجردة + تذكر أنه لا يمكنك إنشاء نسخة من صنف Animal. هذا ما يحدث إذا حاولت ذلك: ```py @@ -113,6 +125,8 @@ bird = Bird() # without an implementation for abstract method 'make_sound' ``` +## الأصناف المجردة مع خاصيات المثيل + إليك مثالًا آخر، هذه المرة مع خاصية مثيل يمكنك تمريرها إلى كائنات الطرق الملموسة: ```py @@ -159,6 +173,8 @@ for toy in toys: - تنفذ الأصناف الفرعية `RobotToy` و`TeddyBearToy` و`DinosaurToy` الطريقة `speak` بطريقتها الخاصة. - عند إنشاء كائنات من هذه الأصناف الفرعية واستدعاء الطريقة `speak`، تتحدث كل لعبة بطريقتها الفريدة. +## كيف يحافظ التجريد على تنظيم الأنظمة المعقدة + في الختام، يبسط التجريد في Python الأنظمة المعقدة بزيادة إعادة الاستخدام. لقد رأيت كيف يمكنك إعادة استخدام طريقة واحدة من صنف مجرد عبر عدة أصناف فرعية مع إجبار كل صنف فرعي على توفير سلوكه الخاص. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-asynchronous-programming/673407be6af21d6766ed4b96.md b/curriculum/challenges/arabic/blocks/lecture-understanding-asynchronous-programming/673407be6af21d6766ed4b96.md index 568b03bfeef..638a9fe24d0 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-asynchronous-programming/673407be6af21d6766ed4b96.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-asynchronous-programming/673407be6af21d6766ed4b96.md @@ -1,6 +1,6 @@ --- id: 673407be6af21d6766ed4b96 -title: كيف تعمل واجهة برمجة التطبيقات Fetch مع طرق HTTP الشائعة و res.json()؟ +title: كيف تعمل واجهة برمجة التطبيقات Fetch مع طرق HTTP الشائعة و res.json()‎؟ challengeType: 19 dashedName: how-does-the-fetch-api-work-with-common-http-methods-and-res-json --- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-code-clarity/672d49d93b54b85faa4dbad7.md b/curriculum/challenges/arabic/blocks/lecture-understanding-code-clarity/672d49d93b54b85faa4dbad7.md index 093a5d57bab..7cc76e50188 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-code-clarity/672d49d93b54b85faa4dbad7.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-code-clarity/672d49d93b54b85faa4dbad7.md @@ -7,41 +7,74 @@ dashedName: what-is-the-role-of-semicolons # --description-- -في JavaScript والعديد من لغات البرمجة الأخرى، تساعد الفواصل المنقوطة على تحديد البيانات وتحسين قابلية قراءة الكود. +تمامًا كما يمكن للنقطة (`.`) أن تشير إلى نهاية جملة في اللغة الإنجليزية، يمكن استخدام الفاصلة المنقوطة (`;`) لتحديد نهاية بيان في JavaScript. مع ذلك، لا تعني البيانات بالضرورة نفس الشيء كسطر واحد من الكود المصدري. يمكن أن يمتد البيان عبر عدة أسطر، ويمكن أن يحتوي السطر الواحد على أكثر من بيان. -في JavaScript، تُستخدم الفاصلة المنقوطة (`;`) للدلالة على نهاية البيان. +على سبيل المثال: -تمامًا كما يشير النقطة (`.`) إلى نهاية الجملة في اللغة الإنجليزية، تشير الفاصلة المنقوطة إلى نهاية سطر قابل للتنفيذ من الكود. هذا يسمح لمحرك JavaScript بتمييز الأوامر المنفصلة. +```js +let variableOne = 5; +let variableTwo = 10; +``` -على سبيل المثال: +في هذا الكود، تجعل الفواصل المنقوطة نهاية كل بيان واضحة وصريحة. كما أن JavaScript تحتوي على ميزة الإدراج التلقائي للفواصل المنقوطة (ASI)، التي تسمح لهذه الإعلانات بالبقاء صحيحة دون الحاجة إلى فواصل منقوطة صريحة: + +```js +let variableOne = 5 +let variableTwo = 10 +``` + +في هذا المثال، تسمح ASI لـ JavaScript بمعاملة كل إعلان كبيان منفصل رغم عدم وجود فواصل منقوطة. مع ذلك، لا تقوم ASI ببساطة بإدراج فاصلة منقوطة بعد كل فاصل سطر. + +على سبيل المثال، يمكن أن يسبب فاصل السطر بعد بيان `return` سلوكًا غير متوقع: + +```js +function getValue() { + return + { + value: 42 + }; +} +``` + +هنا، تقوم ASI بإدراج فاصلة منقوطة بعد `return`، لذا تُرجع الدالة `undefined` بدلًا من الكائن. كتابة الكائن في نفس السطر يتجنب هذا السلوك: ```js -let variableOne = 5; // Declare a variable and assign a value -let variableTwo = 10; // Declare another variable and assign a value +function getValue() { + return { + value: 42 + }; +} ``` -في هذا الكود، تشير الفواصل المنقوطة في نهاية كل سطر إلى نهاية كل بيان. بدونها، قد يواجه محرك JavaScript صعوبة في تفسير مكان انتهاء بيان وبداية آخر. +هذا يوضح لماذا لا تتطابق فواصل الأسطر دائمًا مع حدود البيانات. -تُستخدم الفواصل المنقوطة بشكل أساسي لتحديد نهاية البيان. هذا يساعد محرك JavaScript على فهم فصل التعليمات الفردية، وهو أمر مهم للتنفيذ الصحيح. +يمكن أن تكون الفواصل المنقوطة مفيدة أيضًا عندما يسمح فاصل السطر بخلاف ذلك بتفسير قطعتين من الكود كتعبير واحد. التعبير عن دالة تُنفذ فور تعريفها (IIFE) هو دالة تُشغّل بمجرد تعريفها. إحدى طرق إنشاء IIFE هي تغليف دالة مجهولة، وهي دالة بلا اسم، داخل أقواس عادية ثم إضافة `()` في النهاية لاستدعائها. يمكن أن تسبب IIFE مشكلة عندما لا ينتهي البيان السابق بفاصلة منقوطة: ```js -let a = 1; // Statement ends here -let b = 2; // Another statement starts here +const message = "Hello" + +(function () { + console.log(message); +})() ``` -بينما يحتوي JavaScript على ميزة الإدراج التلقائي للفواصل المنقوطة (Automatic Semicolon Insertion - ASI) التي تضيف الفواصل تلقائيًا، فإن تضمينها صراحةً يحسن وضوح الكود ويساعد على منع الأخطاء التي قد تنشأ من سلوك ASI غير المتوقع. +هنا، لا تُدرج JavaScript فاصلة منقوطة بعد إعلان السلسلة النصية لأن `(` التالية يمكن أن تواصل تعبير المُهيئ. تقوم JavaScript بتحليل المُهيئ كاستدعاء للسلسلة النصية `"Hello"`، مع التعبير الدالي كمعلمة. هذا يؤدي إلى رمي `TypeError` قبل أن تعمل IIFE. إضافة فاصلة منقوطة تنهي الإعلان قبل IIFE: -تُستخدم الفواصل المنقوطة في العديد من لغات البرمجة، بما في ذلك C وC++ وJava. +```js +const message = "Hello"; -تشير الفواصل المنقوطة إلى نهاية البيانات أو التعليمات، مما يساعد المترجم أو المفسر على تحليل الكود بشكل صحيح. يقوم المترجم بتحويل كود لغة البرمجة عالية المستوى إلى كود قابل للقراءة من قبل الآلة، مما ينشئ ملفًا قابلًا للتنفيذ. +(function () { + console.log(message); +})() +``` -من خلال تحديد البيانات بوضوح، تساهم الفواصل المنقوطة في قابلية قراءة الكود وصيانته. تساعد الفواصل المنقوطة على منع الغموض في تنفيذ الكود وتضمن أن البيانات تُنهى بشكل صحيح. +الفاصلة المنقوطة الصريحة تحافظ على إعلان المتغير وIIFE كبيانات منفصلة. -الفواصل المنقوطة جزء أساسي من JavaScript والعديد من لغات البرمجة الأخرى. +تُستخدم الفواصل المنقوطة في العديد من لغات البرمجة، بما في ذلك C وC++ وJava. تختلف قواعدها الدقيقة بين اللغات، لكنها عادةً تساعد في تحديد مكان انتهاء البيانات. -تشير إلى نهاية البيانات، وتحسن قابلية قراءة الكود، وتساعد على تجنب الأخطاء المتعلقة بالإدراج التلقائي للفواصل المنقوطة. +المُجمّع يترجم الكود المصدري إلى شكل آخر، مثل كود الآلة، أو البايت كود، أو تمثيل وسيط، حسب اللغة والمُجمّع. لا ينتج التجميع بالضرورة ملفًا تنفيذيًا مستقلًا. -من خلال فهم واستخدام الفواصل المنقوطة بشكل صحيح، يمكنك كتابة كود أكثر موثوقية وقابلية للصيانة. +الاستخدام المتسق للفواصل المنقوطة يمكن أن يجعل حدود البيانات أوضح ويجعل الكود أسهل في القراءة والصيانة. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-code-clarity/672d49e65a1c855fe7bb3fdb.md b/curriculum/challenges/arabic/blocks/lecture-understanding-code-clarity/672d49e65a1c855fe7bb3fdb.md index 0b27b10d1d0..ecc8c0b7e8a 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-code-clarity/672d49e65a1c855fe7bb3fdb.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-code-clarity/672d49e65a1c855fe7bb3fdb.md @@ -41,7 +41,7 @@ const I18N_CURRICULUM_DIR = path.resolve( 1. تساعد على منع التغييرات أو الحذف غير الضروري دون استشارة الفريق، مما قد يؤدي إلى أخطاء برمجية أو مشاكل. -نوع آخر من التعليقات هو تعليقات متعددة الأسطر. إليك الصيغة النحوية الأساسية: +نوع آخر من التعليقات هو التعليق متعدد الأسطر. هذه هي الصيغة النحوية الأساسية: ```js /* @@ -85,7 +85,7 @@ const price = 10; في هذا الموقف، لا حاجة لإضافة أي تعليقات هنا لأن الكود واضح بذاته. الهدف هو تحسين قابلية القراءة، وليس إرباك الكود بتفسيرات غير ضرورية. -إذا أردت إضافة تعليقات إلى مشاريعك الشخصية أثناء تعلمك البرمجة، فهذا جيد. لكن بمجرد أن تبدأ العمل على مشاريع حقيقية مع مطوِّرين آخرين، من المهم عدم استخدام التعليقات للكود الواضح بذاته. +إذا أردت إضافة تعليقات إلى مشاريعك الشخصية أثناء تعلمك البرمجة، فهذا مقبول. لكن بمجرد أن تبدأ العمل على مشاريع حقيقية مع مطوّرين آخرين، من المهم ألا تستخدم التعليقات لشرح الكود الواضح بذاته. من المهم أيضًا عدم استخدام التعليقات لتبرير كود معقد أو مربك أو مكتوب بشكل سيئ. في هذه الحالات، من الأفضل إعادة هيكلة الكود أو تغييره حتى يفهمه المطوِّرون الآخرون بشكل أفضل. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-effects-and-referencing-values-in-react/67d1ec87b34cee1d9219f7e9.md b/curriculum/challenges/arabic/blocks/lecture-understanding-effects-and-referencing-values-in-react/67d1ec87b34cee1d9219f7e9.md index 1b785ba7e52..bfcd61445ec 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-effects-and-referencing-values-in-react/67d1ec87b34cee1d9219f7e9.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-effects-and-referencing-values-in-react/67d1ec87b34cee1d9219f7e9.md @@ -11,6 +11,8 @@ dashedName: how-can-you-create-custom-hooks-in-react لكن أحيانًا، تحتاج إلى إضافة ميزة لا يمكن لأي من الهوكس المدمجة مساعدتك بها. لحسن الحظ، يمكنك إنشاء هوكس مخصصة خاصة بك في React. +## فوائد الخطاطيف المخصصة + الهوكس المخصصة ليست معقدة كما قد تبدو. هي مجرد دوال قابلة لإعادة الاستخدام تتيح لك مشاركة المنطق عبر مكوّنات متعددة. هذا يعني أن قابلية إعادة الاستخدام سبب آخر يدفعك لبناء هوك خاص بك. مع هوك مخصصة، يمكنك استخراج المنطق بعيدًا عن أي مكوّنات تستخدمها، مثل جلب البيانات، إدارة الحالة، التبديل، التأثيرات الجانبية مثل التحقق من حالة الاتصال بالإنترنت أو عدمه، وهكذا. @@ -19,6 +21,8 @@ dashedName: how-can-you-create-custom-hooks-in-react الآن، لنلقِ نظرة على كيفية إنشاء هوك مخصصة خاصة بك. +## تسمية الخطاطيف المخصصة + في React، تبدأ جميع الهوكس المدمجة بكلمة `use`، لذا يجب أن تتبع هوكك المخصصة نفس الاصطلاح. يجب أن يعبر اسم هوكك المخصصة بوضوح عن وظيفتها. لذا، إذا كانت هوكك المخصصة… @@ -29,6 +33,8 @@ dashedName: how-can-you-create-custom-hooks-in-react - أو إذا كانت تنفذ تقنية debouncing، فإن `useDebounce` اسم جيد +## إنشاء خطاف تأخير التنفيذ (Debounce) + لنفترض أنك تريد بناء هوك مخصصة لإضافة تقنية debouncing إلى تطبيقك. تقنية debouncing هي تقنية برمجية تحد من عدد مرات تشغيل دالة. تعمل عن طريق الانتظار حتى يتوقف المستخدم عن أداء فعل معين لفترة زمنية محددة قبل تنفيذ الدالة. على سبيل المثال، في مربع البحث، بدلًا من إجراء استعلام API مع كل ضغطة مفتاح، تنتظر تقنية debouncing حتى يتوقف المستخدم عن الكتابة لمدة، لنقل، 500 مللي ثانية. @@ -69,6 +75,8 @@ export { useDebounce }; داخل هوك `useEffect` هنا، تستخدم `setTimeout` لتعيين `debouncedValue`. ثم تُرجع دالة تنظيف تستخدم `clearTimeout` لمسح المهلة السابقة كلما تغيرت `value` أو `delay`، أو عند إزالة المكوّن. +## مثال: استخدام خطاف تأخير التنفيذ + لاستخدام هذه الهوك، أعددنا مصفوفة `footballers` للتصفية عبرها باستخدام شريط بحث بسيط: ```js diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-form-validation/6733d3a33abdd27cd562bdf2.md b/curriculum/challenges/arabic/blocks/lecture-understanding-form-validation/6733d3a33abdd27cd562bdf2.md index f038e429884..95398aebffe 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-form-validation/6733d3a33abdd27cd562bdf2.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-form-validation/6733d3a33abdd27cd562bdf2.md @@ -1,6 +1,6 @@ --- id: 6733d3a33abdd27cd562bdf2 -title: ما هو الغرض من طريقة preventDefault()؟ +title: ما هو الغرض من طريقة preventDefault()‎؟ challengeType: 19 dashedName: what-is-the-purpose-of-e-preventdefault --- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-functions-and-scope/67fe859f55cd33356e322fd3.md b/curriculum/challenges/arabic/blocks/lecture-understanding-functions-and-scope/67fe859f55cd33356e322fd3.md index 7e2e314b5a4..ea7427293d4 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-functions-and-scope/67fe859f55cd33356e322fd3.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-functions-and-scope/67fe859f55cd33356e322fd3.md @@ -7,6 +7,8 @@ dashedName: how-do-functions-work-in-python # --description-- +## ما هي الدوال؟ + الدوال هي قطع قابلة لإعادة الاستخدام من الكود تُنفذ عند استدعائها. يوفر Python دوال مدمجة، منها `print()` التي استخدمتها في الدروس السابقة. دالة مدمجة مفيدة أخرى هي `input()`، التي تتيح لك طلب مُدخَل من المستخدم: @@ -25,6 +27,8 @@ print(int(True)) # 1 print(int(False)) # 0 ``` +## تعريف واستدعاء الدوال + يمكنك أيضًا كتابة دوال مخصصة خاصة بك. للقيام بذلك، استخدم الكلمة المفتاحية `def`، تليها الاسم الذي تريد إعطاءه للدالة، ثم زوج من الأقواس العادية، ونقطتين. بعد ذلك، في سطر جديد، اكتب الكود الذي يجب أن تنفذه الدالة. يُشار إلى الكود الذي تنفذه الدالة أيضًا باسم جسم الدالة. إليك مثال على دالة مخصصة اسمها `hello` تطبع السلسلة النصية `Hello World` في الطرفية: @@ -42,6 +46,8 @@ hello() # Hello World لاحظ المسافة البادئة قبل `print('Hello World')`. كما تتذكر من الدروس السابقة، يعتمد Python على المسافة البادئة لتحديد مجموعات العبارات التي تنتمي معًا. تُسمى هذه المجموعات من العبارات كتل الكود. +## استخدام المعلمات والمعلمات + إليك دالة بسيطة أخرى تطبع مجموع رقمين في الطرفية: ```python @@ -67,6 +73,8 @@ calculate_sum() # TypeError: calculate_sum() missing 2 required positional arguments: 'a' and 'b' ``` +## إرجاع القيم من الدوال + تستخدم الدوال أيضًا الكلمة المفتاحية الخاصة `return` للخروج من الدالة وإرجاع قيمة. إذا لم تستخدم `return` صراحة، ستُرجع بايثون `None` افتراضيًا. `None` قيمة خاصة تمثل غياب القيمة. هي القيمة الوحيدة لنوع البيانات `NoneType`. `None` غير قابلة للتغيير وتُعتبر خاطئة، مما يعني أنها لا يمكن تعديلها وتُقيّم إلى `False` في سياق القيمة المنطقية. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-how-http-dns-tcpip-work/69661d2fc36411aa9e25ea64.md b/curriculum/challenges/arabic/blocks/lecture-understanding-how-http-dns-tcpip-work/69661d2fc36411aa9e25ea64.md index dff4deefeae..3d817e422cc 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-how-http-dns-tcpip-work/69661d2fc36411aa9e25ea64.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-how-http-dns-tcpip-work/69661d2fc36411aa9e25ea64.md @@ -29,7 +29,7 @@ dashedName: what-are-some-common-http-response-codes الآن لنتحدث عن **رموز إعادة التوجيه**. -تعاد هذه الرموز من الخادم عندما يتم نقل المورد المطلوب من العميل إلى موقع مختلف أو عندما يحتاج العميل لاتخاذ خطوات إضافية لإكمال الطلب. +تُرجع هذه الرموز من الخادم عندما يتم نقل المورد المطلوب من العميل إلى موقع مختلف أو عندما يحتاج العميل إلى اتخاذ خطوات إضافية لإكمال الطلب. تبدأ هذه الرموز بالرقم 3. @@ -37,15 +37,15 @@ dashedName: what-are-some-common-http-response-codes يشير الرمز **302 Found** إلى أن المورد المطلوب من العميل قد نُقل مؤقتًا إلى موقع آخر. يجب على الخادم توفير عنوان URL الجديد في الاستجابة ويجب على العميل إعادة توجيه المستخدم إلى هذا العنوان. مع ذلك، قد يكون العنوان الأصلي متاحًا في المستقبل لأن التغيير مؤقت. هذا هو الفرق الرئيسي بين الرمزين 301 و302. -يرجع الخادم الرمز **304 Not Modified** ليخبر العميل أن المورد المطلوب لم يتم تعديله منذ آخر طلب. يرسل الخادم هذا الرمز لتجنب إرسال بيانات سبق إرسالها إذا لم يتغير المحتوى. إنها تقنية لتحسين الأداء. +يرجع الخادم رمز **304 Not Modified** ليخبر العميل أن المورد المطلوب لم يتغير منذ آخر طلب. يرسل الخادم هذا الرمز لتجنب إرسال بيانات سبق إرسالها إذا لم يتغير المحتوى. إنها تقنية لتحسين الأداء. ## رموز أخطاء العميل -الآن سنبدأ في الغوص في **رموز الأخطاء**. +الآن سنبدأ بالغوص في **رموز الخطأ**. -يمكن أن تحدث الأخطاء بسبب العميل أو الخادم. سنتحدث أولًا عن رموز أخطاء العميل. +يمكن أن تكون الأخطاء ناجمة عن العميل أو الخادم. سنتحدث أولاً عن رموز أخطاء العميل. -تعاد رموز أخطاء العميل عندما لا يمكن إكمال الطلب بسبب مشكلة ناتجة عن العميل. +تشير استجابة 4xx إلى أن العميل يبدو أنه ارتكب خطأ. تبدأ هذه الرموز بالرقم 4. @@ -53,19 +53,19 @@ dashedName: what-are-some-common-http-response-codes يرتبط الرمز **401 Unauthorized** بالتوثيق. يشير إلى أن العميل يجب أن يقدم بيانات اعتماد معينة للوصول إلى المورد المطلوب. قد تشمل هذه البيانات اسم مستخدم وكلمة مرور. -يرجع الخادم الرمز **403 Forbidden** عندما لا يكون العميل مخولًا للوصول إلى المورد المطلوب. الفرق بين 401 و403 هو أنه في 403، لا يمتلك العميل الأذونات اللازمة للمورد المحدد الذي يطلبه، حتى لو كانت بيانات التوثيق صالحة. +يرجع رمز **403 Forbidden** عندما لا يكون العميل مخولًا للوصول إلى المورد المطلوب. الفرق بين 401 و403 هو أنه في 403، لا يمتلك العميل الأذونات اللازمة للمورد المحدد الذي يطلبه، حتى لو كانت لديه بيانات توثيق صحيحة. -يرجع الخادم الرمز **404 Not Found** عندما لا يمكن العثور على المورد على الخادم. ربما تم حذفه أو هناك خطأ مطبعي في عنوان URL يمنع الخادم من إيجاد المورد. قد يواجه الخادم أيضًا مشكلة مؤقتة تؤدي إلى هذا الرمز. +يرجع رمز **404 Not Found** عندما لا يمكن العثور على المورد على الخادم. ربما تم حذفه أو هناك خطأ مطبعي في عنوان URL يمنع الخادم من العثور على المورد. لا تشير استجابة 404 إلى ما إذا كانت الحالة مؤقتة أو دائمة. ## رموز أخطاء الخادم -بعد ذلك، لدينا **رموز أخطاء الخادم**. تعاد هذه الرموز من الخادم عندما لا يمكن معالجة الطلب بسبب مشكلة في جهة الخادم. +بعد ذلك، لدينا **رموز أخطاء الخادم**. تُرجع هذه الرموز من الخادم عندما لا يمكن معالجة الطلب بسبب مشكلة في جانب الخادم. -يشير الرمز **500 Internal Server Error** إلى حدوث خطأ غير متوقع في الخادم. قد يكون هذا الخطأ ناتجًا عن مجموعة واسعة من المشاكل، من مشاكل التكوين إلى المشاكل المؤقتة. +يشير رمز **500 Internal Server Error** إلى حدوث خطأ غير متوقع على الخادم. قد يكون هذا الخطأ ناجمًا عن مجموعة واسعة من المشاكل، من مشاكل التهيئة إلى مشاكل مؤقتة. يرجع الخادم الرمز **502 Bad Gateway** عندما يحاول الخادم التواصل مع خادم آخر لكنه تلقى استجابة غير صالحة من ذلك الخادم. هناك أسباب كثيرة لهذا النوع من الأخطاء. -يشير الرمز **503 Service Unavailable** إلى أن الخادم لن يكون قادرًا على التعامل مع الطلب مؤقتًا، لذا يجب على العميل المحاولة لاحقًا. تشمل الأسباب الشائعة لهذا الخطأ مهام الصيانة وحجم الطلبات الكبير الذي لا يستطيع الخادم التعامل معه حاليًا. +يشير رمز الخطأ **503 Service Unavailable** إلى أن الخادم لن يكون قادرًا على معالجة الطلب مؤقتًا، لذا يجب على العميل المحاولة مرة أخرى لاحقًا. تشمل الأسباب الشائعة لهذا الخطأ مهام الصيانة وحجم الطلبات الكبير الذي لا يستطيع الخادم التعامل معه حاليًا. تعد رموز استجابة HTTP ضرورية لفهم التواصل بين العملاء وخوادم الويب. بفهم هذه الرموز، يمكنك استكشاف أخطاء تطبيقات الويب الخاصة بك وتصحيحها. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68420be9af9d89620af7944a.md b/curriculum/challenges/arabic/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68420be9af9d89620af7944a.md index a26de305b51..4077c256665 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68420be9af9d89620af7944a.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68420be9af9d89620af7944a.md @@ -7,10 +7,14 @@ dashedName: what-is-object-oriented-programming-and-how-does-encapsulation-work # --description-- +## ما هو البرمجة الموجهة للكائنات؟ + البرمجة الموجهة للكائنات، المعروفة أيضًا بـ OOP، هي أسلوب برمجة يعامل فيه المطوِّرون كل شيء في كودهم ككائن من العالم الحقيقي. الصنف يشبه المخطط لإنشاء الكائنات. كل كائن يُنشأ من صنف يحتوي على خصائص تُعرّف البيانات وطرق تُعرّف سلوكيات الكائنات. +## إنشاء الأصناف والكائنات + في درس سابق، تعلمت كيفية إنشاء الأصناف. إليك تذكيرًا بالصِيغة النحوية: ```py @@ -41,6 +45,8 @@ print('Car 2 Brand:', car2.brand) # Car 2 Brand: Lambo print('Car 2 Color:', car2.color) # Car 2 Color: green ``` +## ما هو التغليف؟ + تمتلك البرمجة الموجهة للكائنات أربعة مبادئ رئيسية تساعدك على تنظيم وإدارة الكود بفعالية. وهي التغليف، الوراثة، التعددية الشكلية، والتجريد. سيركز بقية هذا الدرس على كيفية عمل التغليف. @@ -49,6 +55,8 @@ print('Car 2 Color:', car2.color) # Car 2 Color: green مع التغليف، يمكنك إخفاء الحالة الداخلية للكائن خلف مجموعة بسيطة من الطرق والخصائص العامة التي تعمل كأبواب. خلف هذه الأبواب توجد خصائص وطرق خاصة تتحكم في كيفية تغير البيانات ومن يمكنه رؤيتها. +## استخدام بادئة الشرطة السفلية المفردة + لنفترض أنك تريد تتبع رصيد محفظة. تريد السماح للناس بإيداع أو سحب المال من المحفظة، لكن لا يجب لأحد التلاعب بالرصيد مباشرة. في هذه الحالة، يمكنك جعل `deposit()` و `withdraw()` طرقًا عامة، وتخفي الرصيد تحت الخاصية `_balance`: @@ -69,6 +77,8 @@ class Wallet: بموجب الاصطلاح، بادئة الخاصيات والطرق بشرطة سفلية واحدة تعني أنها مخصصة للاستخدام الداخلي. لا يجب لأحد الوصول إليها مباشرة من خارج الصنف لأنها تخالف مبادئ التغليف، مما قد يؤدي إلى أخطاء برمجية. +## استخدام بادئة الشرطة السفلية المزدوجة + بينما بادئة الشرطة السفلية الواحدة مجرد اصطلاح، فإن بادئة الخاصيات والطرق بشرطتين سفليتين تمنع فعليًا الوصول إليها من خارج الصنف، مما يجعل تلك الخاصيات والطرق خاصة. ```py @@ -119,6 +129,8 @@ acct_two.deposit(150) print(acct_two.get_balance()) # 572 ``` +## تعريف الطرق الخاصة + يمكنك أيضًا تعريف طريقة خاصة `__validate` للتحقق من أن كل مبلغ إيداع أو سحب هو عدد موجب: ```py @@ -159,6 +171,8 @@ acct_one.withdraw(58) # ValueError: Insufficient funds في درس قادم، ستتعلم المزيد عن كيفية عمل الخاصيات التي تبدأ بشرطتين سفليتين. +## ملخص + باختصار، التغليف يُغلق البيانات الداخلية خلف طرق عامة واضحة. هكذا تحمي أصنافك من التلاعب وتُركّز التحقق في مكان واحد. يمكنك تحديث أو توسيع كودك بحرية، مع العلم أن الكود الخارجي يتعامل فقط مع الواجهات التي تتيحها. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68c128cbd77e4ba9ed671937.md b/curriculum/challenges/arabic/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68c128cbd77e4ba9ed671937.md index dadc7cc0ff8..bd7c414411c 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68c128cbd77e4ba9ed671937.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68c128cbd77e4ba9ed671937.md @@ -7,8 +7,12 @@ dashedName: what-are-getters-and-setters # --description-- +## ما هي الدوال الجالبة والمضبوطة (Getters and Setters)؟ + الـ Getters و Setters هي طرق تتيح لك التحكم في كيفية وصول وتعديل خصائص الصنف. مع getters تسترجع قيمة، ومع setters تعيّن قيمة. +## ما هي الخصائص؟ + تتم هذه العمليات من خلال ما يُعرف بالخصائص. هي التي تربط بين getters و setters، وتسمح بالوصول إلى البيانات. تتصرف الخصائص مثل الخصائص العادية لكنها تعمل كطرق تحت الغطاء. فكر فيها كبيانات تعرفها كطرق، لكنها تعمل كخصائص. هذا يعني أنه يمكنك الوصول إلى الخصائص باستخدام ترميز النقطة بدلاً من الأقواس العادية أو العادية. @@ -21,10 +25,14 @@ dashedName: what-are-getters-and-setters على سبيل المثال، قد تريد حساب قيمة أو التحقق من صحة قيمة جديدة قبل حفظها. بدلًا من استدعاء طريقة لذلك، يمكنك استخدام طريقة تشبه الخاصية للقيام بذلك. +## إنشاء الخصائص باستخدام المزخرف `@property` + في بايثون، الديكوريتور هو دالة تُعدّل وظائف دوال أو أصناف أخرى دون تغيير كودها الأصلي. بينما يمكن إنشاء ديكوريتورات مخصصة، هذا يتجاوز نطاق هذا الدرس. فقط اعرف أنه لإنشاء خاصية، تعرف طريقة وتضع فوقها الديكوريتور `@property`. هذا يحول الطريقة إلى خاصية، بحيث يمكن الوصول إليها كخاصية بينما تستدعي داخليًا الطريقة المزينة. +## إنشاء Getter + هذا يقودنا إلى getters. إليك كيفية إنشاء واحد باستخدام الديكوريتور `@property`: ```py @@ -50,6 +58,8 @@ print(my_circle.area) # 28.26 لاحظ كيف استخدمنا `_radius` بدلًا من radius داخل الصنف. الشرطة السفلية هي اصطلاح شائع في Python للدلالة على أن الخاصية خاصة. بمعنى آخر، تشير إلى أنها للاستخدام الداخلي ولا يجب الوصول إليها مباشرة من خارج الصنف. +## إنشاء Setter + لإنشاء setter لتعيين نصف القطر، على سبيل المثال، عليك تعريف طريقة أخرى بنفس الاسم واستخدام الديكوريتور `@.setter` فوقها: استخدام `self.radius` داخل `__init__` يضمن تشغيل setter أثناء إنشاء الكائن، لذا يتم التقاط قيم نصف القطر غير الصالحة فورًا. @@ -78,6 +88,8 @@ print('After modifying the radius:', my_circle.radius) # After modifying the rad في هذا المثال، setter نصف القطر لا يعيّن نصف القطر فقط، بل ينفذ تحققًا للتأكد من أن نصف القطر ليس رقمًا سالبًا. +## كيف يستدعي Python الـ Getters والـ Setters + بمجرد تعريف getters و setters، تستدعيها Python تلقائيًا خلف الكواليس كلما استخدمت صيغة الخاصية العادية: ```py @@ -87,6 +99,8 @@ my_circle.radius = 4 # This will call the setter لاحظ أنه داخل setter، لا يمكنك استخدام نفس اسم الخاصية عند تعيين قيمة جديدة. ذلك لأن `self.radius = value` سيستدعي setter داخل نفسه، مما يؤدي إلى تكرار لا نهائي وخطأ `RecursionError`. لذلك يجب دائمًا استخدام الشكل الذي يبدأ بشرطة سفلية `self._radius = value`. +## إنشاء Deleter + تمامًا كما يمكنك التحكم في كيفية وصول الخاصية عبر getter وكيفية تعديلها عبر setter، يمكنك أيضًا التحكم في كيفية حذفها باستخدام deleter. يُشغّل deleter منطقًا مخصصًا عند استخدام عبارة del على خاصية. لإنشاء واحد، تستخدم الديكوريتور `@.deleter`: @@ -134,6 +148,8 @@ except AttributeError as e: print("Error:", e) # Error: 'Circle' object has no attribute '_radius' ``` +## ملخص + النتيجة المستفادة من هذا هي: - الـ Getters تتيح لك استرجاع قيمة أو حتى حساب قيمة في الوقت الفعلي. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-recursion-and-the-call-stack-python/6a89c69c2abed81397a6c99e.md b/curriculum/challenges/arabic/blocks/lecture-understanding-recursion-and-the-call-stack-python/6a89c69c2abed81397a6c99e.md index 65bc4313d37..ed0e98e7c44 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-recursion-and-the-call-stack-python/6a89c69c2abed81397a6c99e.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-recursion-and-the-call-stack-python/6a89c69c2abed81397a6c99e.md @@ -7,6 +7,8 @@ dashedName: what-is-recursion-and-how-does-it-work # --description-- +## ما هو الاستدعاء الذاتي؟ + التكرار هو تقنية تستدعي فيها الدالة نفسها. كل استدعاء يعمل على نسخة أصغر من المشكلة الأصلية حتى يصل إلى شرط يوقف التكرار. يُسمى هذا الشرط الذي يوقف التكرار بالحالة الأساسية. يمكن للدوال المتكررة حل مشكلات ذات عمق غير معروف، مثل التنقل في شجرة الملفات. كما يمكنها أداء مهام أبسط، مثل العد التنازلي من رقم معين. @@ -20,6 +22,8 @@ def recursive_countdown(number): recursive_countdown(5) ``` +## إضافة حالة أساسية + استدعاء الدالة يطبع `5`، لكنه لا يبدأ العد التنازلي بعد. قبل أن تستدعي الدالة نفسها، يجب تعريف الحالة الأساسية. بدون حالة أساسية يمكن الوصول إليها، ستستمر الدالة في استدعاء نفسها. في النهاية، توقف Python الاستدعاءات وترجع خطأ `RecursionError`. لهذا العد التنازلي، يجب أن تتوقف الدالة عندما يكون `number` أقل من `1`: @@ -35,6 +39,8 @@ recursive_countdown(5) عبارة `if` هي الحالة الأساسية. عندما يكون `number` أقل من `1`، ينهي `return` استدعاء الدالة ذلك. +## إضافة حالة استدعاء ذاتي + لا تزال الدالة بحاجة إلى حالة متكررة. الحالة المتكررة تستدعي الدالة مرة أخرى بمعلمة تحركها نحو الحالة الأساسية. للعد التنازلي، استدعِ `recursive_countdown` مع `number - 1`: ```py @@ -49,6 +55,8 @@ recursive_countdown(5) هذا يطبع الأرقام `5`، `4`، `3`، `2`، و`1`. +## تغيير ترتيب التنفيذ + يتغير موضع الاستدعاء المتكرر عند طباعة الأرقام. إذا جاء استدعاء `print()` بعد الاستدعاء المتكرر، تطبع الدالة الأرقام بترتيب تصاعدي: ```py @@ -63,8 +71,12 @@ recursive_countdown(5) هذا يطبع الأرقام `1`، `2`، `3`، `4`، و`5`. لفهم السبب، تحتاج إلى فهم مكدس الاستدعاءات. +## ما هو مكدس الاستدعاءات؟ + مكدس الاستدعاءات هو هيكل بيانات من نوع آخر داخل أولاً، خارج أولاً تستخدمه Python لتتبع استدعاءات الدوال النشطة. عند استدعاء دالة، تضيف Python إطارًا لذلك الاستدعاء في أعلى المكدس. يحتوي الإطار على معلومات مثل معلمات الدالة والمتغيرات المحلية. +## تتبع مكدس الاستدعاءات + انظر هذا الإصدار من العد التنازلي: ```py diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-routing-in-express-js/69a918497b6424e132898217.md b/curriculum/challenges/arabic/blocks/lecture-understanding-routing-in-express-js/69a918497b6424e132898217.md index ffc9ed22849..89d454f759e 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-routing-in-express-js/69a918497b6424e132898217.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-routing-in-express-js/69a918497b6424e132898217.md @@ -1,6 +1,6 @@ --- id: 69a918497b6424e132898217 -title: كيف تنشئ معالجات مسارات قابلة للربط باستخدام app.route()؟ +title: كيف تنشئ معالجات مسارات قابلة للربط باستخدام app.route()‎؟ challengeType: 19 dashedName: how-can-you-create-chainable-route-handlers-using-approute --- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-routing-in-express-js/69a9184b42ae3947e4925016.md b/curriculum/challenges/arabic/blocks/lecture-understanding-routing-in-express-js/69a9184b42ae3947e4925016.md index 86a860b87b5..a27f96b7f8f 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-routing-in-express-js/69a9184b42ae3947e4925016.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-routing-in-express-js/69a9184b42ae3947e4925016.md @@ -7,6 +7,8 @@ dashedName: how-does-expressrouter-work # --description-- +## ما هو `express.Router()`؟ + في Express، تُعد `express.Router()` ميزة قوية تساعدك على تنظيم مساراتك إلى أجزاء أصغر ومودولية. هذا مفيد بشكل خاص مع نمو التطبيق. بدلًا من تعريف كل المسارات في ملف كبير واحد، يمكنك تقسيمها إلى ملفات منفصلة باستخدام الموجِّهات. هذا يجعل كودك أسهل في القراءة والصيانة والتوسع. @@ -17,6 +19,8 @@ dashedName: how-does-expressrouter-work بمعنى آخر، يسمح لك الموجِّه بتجميع المسارات المرتبطة معًا ثم دمجها لاحقًا في التطبيق الرئيسي. +## فوائد استخدام الموجِّهات + لاستخدام الموجِّهات عدة مزايا: **فصل الاهتمامات** @@ -29,6 +33,8 @@ dashedName: how-does-expressrouter-work **تنظيف الملف الرئيسي** بدلاً من ملء ملف `app.js` أو `server.js` الرئيسي بالعديد من تعريفات المسارات، يمكنك نقلها إلى الموجِّهات والحفاظ على تركيز الملف الرئيسي على الإعداد والتكوين. +## مثال: توجيه الطلبات إلى `/users` + لننظر إلى مثال بسيط حيث نستخدم `express.Router()` لتعريف مسارات لمسار `/users`. أولاً، هذا هو ملف `app.js`: @@ -74,6 +80,8 @@ router.get("/:id", (req, res) => { module.exports = router; ``` +## كيف يعمل المثال + الآن لنلق نظرة أقرب على كيفية عمل كل شيء. في `app.js`، نستورد `express` ونُنشئ نسخة من تطبيق Express ونعينها إلى متغير اسمه `app`. @@ -90,6 +98,7 @@ module.exports = router; * `router.get("/:id")` → `GET /users/:id`: يرد بتفاصيل المستخدم لرقم معرف معين +## تنظيم التطبيقات الأكبر استخدام `express.Router()` يحافظ على نظافة الملف الرئيسي وتركيزه على التكوين. جميع المسارات المتعلقة بالمستخدمين مجمعة في `userRoutes.js`. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86e9f96f6bbcd0ed8c45.md b/curriculum/challenges/arabic/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86e9f96f6bbcd0ed8c45.md index 5aefe44aecb..c96821d93d3 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86e9f96f6bbcd0ed8c45.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86e9f96f6bbcd0ed8c45.md @@ -11,7 +11,7 @@ HTTPS تعني بروتوكول نقل النص الفائق الآمن. هو ا كما تعلمت في بعض المحاضرات السابقة، ينقل HTTP البيانات بين متصفحك وموقع الويب. HTTP العادي يرسل هذه البيانات كنص عادي، لذا يمكن لأي شخص اعتراض تلك البيانات النصية. -لهذا السبب، يستخدم HTTPS بروتوكول تشفير يُسمى أمان طبقة النقل (TLS) لتأمين نقل البيانات. يقوم TLS بتشفير قناة الاتصال بين نقطتين. كانت الأنظمة القديمة تستخدم طبقة المقابس الآمنة (SSL)، التي لا تزال العديد من منصات استضافة الويب تستخدمها اليوم. +لهذا السبب، يستخدم HTTPS بروتوكول تشفير يُسمى أمان طبقة النقل (TLS) لتأمين نقل البيانات هذا. يقوم TLS بتشفير قناة الاتصال بين نقطتين. استبدل TLS بروتوكول طبقة المقابس الآمنة (SSL) الأقدم، رغم أن العديد من منصات استضافة الويب لا تزال تشير إلى SSL في إعداداتها اليوم. التشفير يحول تلك البيانات إلى شفرة غير قابلة للقراءة لا يملك مفاتيح فك تشفيرها سوى متصفح المستخدم وخادم الويب. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86eac73558aaa2679c15.md b/curriculum/challenges/arabic/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86eac73558aaa2679c15.md index f5bbc82e2ea..9cc859b15b3 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86eac73558aaa2679c15.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86eac73558aaa2679c15.md @@ -7,6 +7,8 @@ dashedName: how-are-cookies-stored-and-what-are-the-security-and-privacy-implica # --description-- +## ما هي الكوكيز؟ + الكوكيز هي ملفات نصية صغيرة تحفظها مواقع الويب على جهازك لتتذكر بعض المعلومات عنك. إليك عملية استقبال وتخزين الكوكيز: @@ -18,10 +20,14 @@ dashedName: how-are-cookies-stored-and-what-are-the-security-and-privacy-implica تتيح هذه العملية للموقع تذكر جلسة تسجيل الدخول، وعناصر سلة التسوق، والتفضيلات والإعدادات، وغيرها من المعلومات المهمة. +## مخاطر أمان تخزين الكوكيز + تُدخل طريقة التخزين مخاطر أمان كبيرة. إذا حصل مخترق على وصول مادي إلى جهازك أو استخدم برمجيات خبيثة لقراءة ملفاتك المحلية، يمكنه سرقة كوكيز الجلسة الخاصة بك. مع كوكيز جلسة مسروقة، يمكن للمهاجم تسجيل الدخول إلى حساباتك من كمبيوتر مختلف تمامًا دون معرفة كلمة المرور. +## الحماية باستخدام علامات الأمان + لحماية المستخدمين ومنع سرقة الكوكيز، يستخدم المطوّرون علامات أمان محددة عند تعيين الكوكيز: تمنع العلامة `HttpOnly` جافاسكريبت من قراءة ملف الكوكيز. هذا القيد يمنع المهاجمين من سرقة رموز الجلسة عبر هجمات البرمجة عبر المواقع (Cross-Site Scripting). @@ -33,12 +39,16 @@ dashedName: how-are-cookies-stored-and-what-are-the-security-and-privacy-implica - `SameSite=Strict` يمنع المتصفح من إرسال الكوكيز في أي طلب عبر موقع. - `SameSite=Lax` يسمح بالكوكيز في التنقل الآمن على المستوى الأعلى، مثل النقر على رابط، لكنه يمنعها في إرسال النماذج عبر المواقع وطلبات API. +## التتبع من طرف ثالث + للكوكيز أيضًا تداعيات كبيرة على الخصوصية. تتعقب الكوكيز من الطرف الأول أفعالك فقط على الموقع الذي تختاره لزيارته. أما الكوكيز من الطرف الثالث فتتبعك عبر مواقع مختلفة تمامًا. تضع شبكات الإعلانات هذه الكوكيز على آلاف المواقع الشهيرة. أثناء تصفحك للإنترنت، تقرأ شبكة الإعلانات نفس كوكيز الطرف الثالث مرارًا لبناء ملف شخصي مفصل عن اهتماماتك الشخصية، وتاريخ البحث، وعاداتك على الإنترنت. يخلق هذا التتبع الخفي قلقًا كبيرًا على الخصوصية لأنه يسمح للشركات بمراقبة حياتك الرقمية دون علمك النشط. +## القوانين والحمايات الافتراضية + بسبب هذه التهديدات، تتطلب قوانين الخصوصية مثل GDPR من المواقع عرض لافتات موافقة على الكوكيز لتعرف ما الذي يفعله الموقع بالكوكيز التي يضعها. تمنحك هذه القوانين الحق القانوني في رفض كوكيز التتبع. بالإضافة إلى ذلك، تحظر المتصفحات الحديثة الآن كوكيز التتبع من الطرف الثالث افتراضيًا لتوفير حماية خصوصية تلقائية للمستخدمين. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e910842f3322350bc8d93.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e910842f3322350bc8d93.md index 83fa5cef2ae..6c52ae59c85 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e910842f3322350bc8d93.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e910842f3322350bc8d93.md @@ -9,7 +9,7 @@ dashedName: what-is-the-terminal-and-how-does-it-differ-from-the-command-line دعنا نتعلم عن الطرفية، وكيف تختلف عن سطر الأوامر. -سطر الأوامر هو واجهة مُدخَل نصي أساسية تتيح للمستخدم إدخال "أوامر"، عادةً على شكل سلسلة من الأحرف، وإرسالها أو تنفيذها، عادةً بالضغط على مفتاح Enter. سترى غالبًا واجهات سطر الأوامر داخل الطرفية. +سطر الأوامر هو واجهة إدخال نصية أساسية تتيح للمستخدم إدخال "أوامر"، عادةً على شكل سلسلة من الأحرف، وإرسالها أو تنفيذها، عادةً بالضغط على مفتاح Enter. سترى غالبًا واجهات سطر الأوامر داخل الطرفية. الطرفية هي تطبيق خاص يقدم واجهة سطر أوامر لتنفيذ أوامر على مستوى النظام تتجاوز عمليات القراءة/الكتابة الأساسية. قد تسمع أيضًا عن "محاكيات الطرفية"، وهي تطبيقات تغلف واجهة طرفية أساسية لتقديم ميزات أو وظائف إضافية. لكن لأغراض عامة، يمكنك اعتبارها "طرفيات" أيضًا. @@ -17,23 +17,21 @@ dashedName: what-is-the-terminal-and-how-does-it-differ-from-the-command-line لكن كيف يمكنك الوصول إلى الطرفية على نظامك؟ -إذا كنت تستخدم إصدارًا حديثًا من Windows، فربما لديك خياران مختلفان. يقدم Windows تطبيقين مختلفين للأصداف مباشرة: Powershell وCommand Prompt. +إذا كنت تستخدم إصدارًا حديثًا من Windows، فستجد على الأرجح خيارين مختلفين. يوفر Windows تطبيقين مميزين للـ shell مباشرةً: PowerShell وCommand Prompt. -كل من هذين الصدَفين يأتي مع تطبيق طرفية خاص به (يشارك اسم الصَدَف نفسه)، لذا يمكنك استخدام قائمة التطبيقات لبدء طرفية Powershell أو طرفية Command Prompt. +كل من هذين الـ shell يأتي مع تطبيق طرفية خاص به (يشارك اسم الـ shell المعني)، لذا يمكنك استخدام قائمة التطبيقات لبدء طرفية PowerShell أو طرفية Command Prompt. -يقدم Windows أيضًا محاكي طرفية حديث نسبيًا اسمه Microsoft Terminal. +يوفر Windows أيضًا محاكي طرفية حديثًا نسبيًا يُسمى Windows Terminal. -يمكنك تثبيت هذا التطبيق من متجر Windows، ثم تشغيله كما تفعل مع طرفيات Powershell أو Command Prompt. ميزة Microsoft Terminal أنه يسمح لك بالوصول إلى صدَفي Powershell وCommand Prompt من نفس التطبيق، بالإضافة إلى صدَف Linux الخاص بك إذا قمت بتكوين Windows Subsystems for Linux. +يمكنك تثبيت هذا التطبيق من متجر Windows، ثم تشغيله كما تفعل مع طرفيات PowerShell أو Command Prompt. ميزة Windows Terminal أنه يسمح لك بالوصول إلى كل من shell الخاص بـ PowerShell وCommand Prompt من نفس التطبيق، بالإضافة إلى shell Linux الخاص بك إذا قمت بتكوين Windows Subsystem for Linux. -يقدم MacOS طرفية تُسمى ببساطة "Terminal". يمكنك الوصول إليها عبر البحث السريع أو من خلال مشغل التطبيقات. - -يدعم MacOS أيضًا محاكيات طرفية من جهات خارجية، مثل iTerm أو Ghostty. يمكنك تثبيت هذه التطبيقات من مواقعها الرسمية. +على macOS، هناك طرفية تُسمى ببساطة "Terminal". يمكنك الوصول إليها من خلال البحث السريع أو من خلال مشغل التطبيقات. كما يوجد دعم لمحاكيات طرفية من جهات خارجية، مثل iTerm أو Ghostty. يمكنك تثبيت هذه التطبيقات من صفحاتها الرئيسية. في Linux، الطرفية الافتراضية (وكيفية تشغيلها) تعتمد بشكل كبير على التوزيعة وبيئة سطح المكتب التي تستخدمها. هناك دعم كبير لمحاكيات طرفية من جهات خارجية أيضًا. على سبيل المثال، يمكنك إعداد kitty في Arch Linux - ويمكنك تشغيله باستخدام مدير التطبيقات مثل wofi. يُعتبر Linux الأكثر تنوعًا في تطبيقات الطرفية التي يمكنك الاختيار منها. يمكن تثبيت معظمها عبر مدير الحزم الخاص بتوزيعتك. -قد يبدو التمييز بين "الطرفية" و"الصدَف" و"سطر الأوامر" دقيقًا أحيانًا. وفي الغالب، يمكن استخدام هذه المصطلحات بالتبادل. لكن من المهم معرفة أن لكل منها معنى محدد، وما هو هذا المعنى. +قد يبدو التمييز بين "الطرفية" و"الـ shell" و"سطر الأوامر" دقيقًا أحيانًا. وفي الغالب، يمكن استخدام هذه المصطلحات بالتبادل. لكن من المهم معرفة أن لكل منها معنى محدد، وما هو هذا المعنى. # --questions-- @@ -111,7 +109,7 @@ dashedName: what-is-the-terminal-and-how-does-it-differ-from-the-command-line ## --text-- -في Windows، ما الميزة التي يقدمها Microsoft Terminal مقارنة بالخيارات التقليدية؟ +ما الميزة التي يقدمها Windows Terminal على الخيارات التقليدية في Windows؟ ## --answers-- @@ -119,11 +117,11 @@ dashedName: what-is-the-terminal-and-how-does-it-differ-from-the-command-line ### --feedback-- -فكر في الوظائف التي يقدمها Microsoft Terminal والتي لا توفرها الطرفيات التقليدية في Windows. +فكر في الوظائف التي يوفرها Windows Terminal والتي لا توفرها الطرفيات التقليدية في Windows. --- -يسمح بالوصول إلى صدَفي Powershell وCommand Prompt من نفس التطبيق. +يسمح بالوصول إلى كل من shell الخاص بـ PowerShell وCommand Prompt من نفس التطبيق. --- @@ -131,7 +129,7 @@ dashedName: what-is-the-terminal-and-how-does-it-differ-from-the-command-line ### --feedback-- -فكر في الوظائف التي يقدمها Microsoft Terminal والتي لا توفرها الطرفيات التقليدية في Windows. +فكر في الوظائف التي يوفرها Windows Terminal والتي لا توفرها الطرفيات التقليدية في Windows. --- @@ -139,7 +137,7 @@ dashedName: what-is-the-terminal-and-how-does-it-differ-from-the-command-line ### --feedback-- -فكر في الوظائف التي يقدمها Microsoft Terminal والتي لا توفرها الطرفيات التقليدية في Windows. +فكر في الوظائف التي يوفرها Windows Terminal والتي لا توفرها الطرفيات التقليدية في Windows. ## --video-solution-- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e9437536d762823fefab3.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e9437536d762823fefab3.md index b32baa9ac43..902d6c8bb69 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e9437536d762823fefab3.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e9437536d762823fefab3.md @@ -11,20 +11,32 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- يمكن لاختصارات الطرفية وسطر الأوامر أن تساعدك على تبسيط سير عملك وزيادة إنتاجيتك إلى أقصى حد. بالنسبة لنظامي Linux وmacOS، اللذين يعودان جذورهما إلى Unix، ستكون العديد من هذه الاختصارات متشابهة. لكن بالنسبة لنظام Windows، ستكون هناك بعض الاختلافات. +## اختصارات سهم للأعلى و سهم للأسفل + الاختصار الأول هو مفتاح سهم للأعلى. الضغط على هذا المفتاح يسمح لك بالتنقل للخلف عبر سجل الأوامر، أمرًا واحدًا في كل مرة. ثم يمكن استخدام مفتاح سهم للأسفل للتنقل للأمام عبر سجل الأوامر. هذان المفتاحان يتيحان لك التنقل بسرعة بين الأوامر التي نفذتها سابقًا للعثور على الأمر الذي تحتاج إلى تشغيله مرة أخرى. -تقدم العديد من الصدوع أيضًا ميزة الإكمال التلقائي، التي تقترح أوامر بناءً على ما بدأت بكتابته. يمكن استخدام مفتاح Tab لملء بقية الاقتراح، مما يملأ سطر الأوامر بسرعة بالصيغة النحوية الكاملة. تختلف طريقة توليد هذه الاقتراحات من صدع لآخر. على سبيل المثال، في zsh تعتمد هذه الاقتراحات على سجل الأوامر الأخير. أما في PowerShell، فتعتمد على الأوامر والمتغيرات والمعلمات المتاحة (مع وزن أقل لمدى استخدامها مؤخرًا). +## الإكمال التلقائي باستخدام مفتاح Tab + +تقدم العديد من الصدفات أيضًا ميزة الإكمال التلقائي، حيث تقترح أوامر بناءً على ما بدأت بكتابته. يمكن استخدام مفتاح Tab لملء بقية الاقتراح، مما يملأ سطر الأوامر بسرعة بالصيغة النحوية الكاملة. ما يتم اقتراحه يعتمد على الصدفة، والأمر الذي تكتبه، وكيفية تكوين الصدفة الخاصة بك. على سبيل المثال، عند كتابة اسم أمر، يقترح Bash و zsh أوامر مطابقة، وعند كتابة معلمة، عادةً ما يقترحان أسماء ملفات ومجلدات مطابقة. يمكن لـ PowerShell إكمال الأوامر، وأسماء المعلمات، والمتغيرات، ومسارات الملفات. + +## اختصار Control + L أحيانًا قد ينتج عن أمر ما الكثير من المخرجات على الطرفية. قد يعيق هذا الضجيج الإضافي سير عملك أو يسبب إزعاجًا. في الطرفيات المبنية على *nix الموجودة في أجهزة Linux وmacOS، يمكنك الضغط على Control + L لمسح الشاشة بالكامل والبدء بموجه نظيف وجديد. في PowerShell، يقوم Control + L أيضًا بمسح الشاشة افتراضيًا، ويمكنك تشغيل الأمر `cls` لنفس النتيجة. -إذا احتجت إلى مقاطعة أمر لإيقاف تنفيذه، يمكنك استخدام Control + C لقتل العملية. هذا سينهي الأمر ويُنشئ موجهًا جديدًا، مما يسمح لك بالاستمرار في العمل على ما تحتاج إليه. بالنسبة لمستخدمي PowerShell، يُستخدم Control + C أيضًا لنسخ النص - ولن يعمل لإنهاء عملية إلا عندما لا يكون هناك نص محدد للنسخ. +## اختصار Control + C + +إذا كنت بحاجة إلى مقاطعة أمر لإيقاف تنفيذه، يمكنك الضغط على Control + C. يرسل هذا طلب مقاطعة إلى الأمر الذي يعمل في المقدمة، والذي عادةً ما يوقفه ويعيدك إلى موجه جديد، مما يسمح لك بالاستمرار في العمل على ما تحتاج إليه. بعض البرامج تتعامل مع هذا الطلب بنفسها، فقد تطلب منك التأكيد أو الاستمرار في التشغيل بدلاً من ذلك. بالنسبة لمستخدمي PowerShell، يُستخدم Control + C أيضًا لنسخ النص - ولن يعمل لمقاطعة أمر إلا عندما لا يكون السياق غامضًا (مثل عدم تحديد نص للنسخ). + +## اختصارات الطرفية المبنية على *nix الاختصارات التالية متاحة فقط في الطرفيات المبنية على *nix، ولا يوجد لها بديل في PowerShell. -قد تحتاج أحيانًا إلى تعدد المهام، مما يسمح لعملية أو أمر بالعمل في الخلفية أثناء عملك على شيء آخر. الضغط على Control + Z يضع العملية الحالية في مهمة خلفية ويعيدك إلى سطر الأوامر لتواصل عملك. عندما تحتاج إلى إعادة التركيز على المهمة الخلفية، يمكنك استخدام `fg` لاستعادتها. +قد تحتاج أحيانًا إلى تعدد المهام، مع إيقاف أمر مؤقتًا أثناء العمل على آخر. الضغط على Control + Z يعلق الأمر الذي يعمل في المقدمة ويعيدك إلى سطر الأوامر، حيث يمكنك متابعة عملك. الأمر المعلق متوقف مؤقتًا، وليس قيد التشغيل. إذا أردت أن يستمر في العمل في الخلفية، استخدم الأمر `bg`. وعندما تحتاج إلى إعادته إلى المقدمة، استخدم الأمر `fg`. وأخيرًا، قد تحتاج إلى تشغيل أوامر مرتين متتاليتين. يمكنك الضغط على مفتاح سهم للأعلى للتنقل للخلف إلى الأمر الذي تم تشغيله سابقًا، أو يمكنك كتابة علامتي تعجب (`!!`) في سطر الأوامر والضغط على Enter - هذا سيشغل آخر أمر تم تنفيذه تلقائيًا. +## مرجع اختصارات واجهة سطر الأوامر + @@ -46,9 +58,9 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- - + - + @@ -58,12 +70,12 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- - + - + - + @@ -123,11 +135,11 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- ### --feedback-- -هذا الاختصار يسمح لك بتعدد المهام أثناء تشغيل عملية. +يتيح لك هذا الاختصار إيقاف أمر مؤقتًا والعودة إليه لاحقًا. --- -يضع العملية الحالية في الخلفية. +يعلق العملية الحالية في المقدمة. --- @@ -135,7 +147,7 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- ### --feedback-- -هذا الاختصار يسمح لك بتعدد المهام أثناء تشغيل عملية. +يتيح لك هذا الاختصار إيقاف أمر مؤقتًا والعودة إليه لاحقًا. --- @@ -143,7 +155,7 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- ### --feedback-- -هذا الاختصار يسمح لك بتعدد المهام أثناء تشغيل عملية. +يتيح لك هذا الاختصار إيقاف أمر مؤقتًا والعودة إليه لاحقًا. ## --video-solution-- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e944b821130283dc83b2e.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e944b821130283dc83b2e.md index 47678ad266b..f555e15e041 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e944b821130283dc83b2e.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e944b821130283dc83b2e.md @@ -9,14 +9,20 @@ dashedName: what-is-bash-and-what-are-some-bash-commands دعنا نتعلم عن Bash وبعض أوامره الأساسية. +## ما هو Bash؟ + Bash تعني Bourne Again SHell، وهي على الأرجح أكثر واجهات الأوامر شيوعًا التي ستواجهها في بيئات شبيهة بـ Unix. لذلك، من المفيد جدًا أن تفهم كيفية التنقل في هذه الواجهة واستخدام الأوامر الشائعة. +## أوامر التنقل في نظام الملفات + الأمر الأول هو `pwd`، الذي يطبع الدليل الحالي للعمل في الطرفية. يشير "الدليل الحالي للعمل" إلى الدليل الذي تشير إليه الطرفية حاليًا، وهو أمر مهم معرفته للعديد من هذه الأوامر الأخرى. من الممكن تمامًا أن تكون الطرفية تشير إلى دليل خاطئ. يسمح لك الأمر `cd` بتغيير الأدلة. يمكنك تحديد مسار مطلق يبدأ بشرطة مائلة للأمام (`/`)، أو مسار نسبي بدون بادئة، واستخدام صيغة النقطتين (`..`) للصعود إلى الدليل الأب. الأمر التالي هو `ls`، الذي يعرض محتويات الدليل الحالي للعمل. هذا مفيد لمعرفة ما إذا كان هناك ملف أو مجلد في دليلك. يأخذ أمر `ls` أيضًا علامات لعرض الملفات المخفية (العلامة `-a`)، أذونات الملفات (العلامة `-l`)، وميزات أخرى. ستتعلم المزيد عن علامات الأوامر في الدرس التالي. يمكنك أيضًا استخدام `less` أو `cat` لعرض محتويات ملف. +## أوامر إدارة الملفات + ماذا لو لم يحتوي الدليل على الملف أو المجلد الذي تحتاجه؟ هناك أوامر تسمى `mkdir` و `touch` تسمح لك بإنشائها. ينشئ `mkdir` دليلًا جديدًا أو مجلدًا، و`touch` ينشئ ملفًا جديدًا. كلا الأمرين يقبلان اسم الملف أو المجلد الذي تريد إنشاؤه. على سبيل المثال، `touch readme.md` ينشئ ملف Markdown جديد باسم `readme.md`. ربما لم يكن يجب تسمية ملفك الجديد `readme.md`، بل يجب أن يكون `readthis.md`. لحسن الحظ، يسمح لك الأمر `mv` بنقل (أو إعادة تسمية) ملف. يأخذ اسم الملف القديم واسم الملف الجديد. @@ -25,8 +31,12 @@ Bash تعني Bourne Again SHell، وهي على الأرجح أكثر واجه يمكن استخدام الأمر `cp` لنسخ ملف أو مجلد إلى موقع جديد. على عكس الأمر `mv`، لا يحذف الأمر `cp` الملف الأصلي - ولنسخ مجلد، ستحتاج إلى تمرير العلامة `-r`. +## إخراج النص في وحدة التحكم + يمكن اعتبار الأمر `echo` معادل Bash لدالة `console.log()` أو `print()`. يأخذ `echo` معلمة سلسلة نصية، ملفوفة بين علامات اقتباس، ويطبعها في الطرفية. قد يبدو هذا سخيفًا لتشغيله في الطرفية فقط للحصول على نص في الطرفية، لكن يمكنك ربط `echo` برمز تحكم. يسمح الرمز `>` بتحديد اسم ملف لإنشائه أو استبداله بالسلسلة الجديدة، مثل `echo "Naomi was here." > readme.md`، والرمز `>>` يضيف إلى الملف. +## أوامر Bash الأخرى + هناك العديد من أوامر Bash الأخرى المتاحة لك، مثل `head`، `tail`، `chown`، و `chmod`. سيكون من المستحيل تغطيتها جميعًا في هذا الدرس. لكن يمكنك استخدام الأمر `man` لرؤية الدليل أو صفحة المساعدة لأي أمر تقريبًا. من المحتمل أن تتذكر الأوامر التي تستخدمها بشكل متكرر. وللباقي، يمكنك دائمًا مراجعة صفحة الدليل. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e947ae3ea7d2867c3d0e1.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e947ae3ea7d2867c3d0e1.md index a495cecebcc..e5fb2beca7e 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e947ae3ea7d2867c3d0e1.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e947ae3ea7d2867c3d0e1.md @@ -21,25 +21,31 @@ dashedName: what-are-some-command-options-and-flags ميزة هذه الخيارات القصيرة هي أنه يمكنك ربط عدة أعلام معًا. بدلًا من `ls --all --human-readable --size` يمكنك استخدام الحروف المفردة كلها مرة واحدة مع `ls -ahs`. -بعض الخيارات تتوقع تمرير قيمة لها. +بعض الخيارات تتوقع تمرير قيمة لها. طريقة تمرير هذه القيمة تعتمد على ما إذا كان الخيار يتطلب قيمة أم يقبلها بشكل اختياري فقط. -عند استخدام الخيارات بصيغة طويلة، عادةً تحتاج إلى استخدام علامة المساواة. في هذه الصيغة، تُلصق القيمة مباشرةً بالخيار باستخدام رمز المساواة (`=`). إليك مثالًا لتعديل سلوك `ls` ليشمل أو يستبعد الألوان: +عندما يتطلب الخيار بصيغة قصيرة قيمة، عادةً تفصل القيمة بمسافة. على سبيل المثال، هذا هو الخيار بصيغة قصيرة لتعيين `width` لنتيجة `ls`: ```bash -ls --color=never +ls -w 50 ``` -عند استخدام الخيارات بصيغة قصيرة، عادةً تفصل القيمة بمسافة. على سبيل المثال، هذه هي الخيارات بصيغتيها الطويلة والقصيرة لتعيين `width` لنتيجة `ls`: +عندما يتطلب الخيار بصيغة طويلة قيمة، تقبل أدوات GNU مثل `ls` القيمة إما بعد رمز يساوي (`=`) أو مفصولة بمسافة. كلا الأمرين يضبطان نفس العرض: ```bash -ls -w 50 +ls --width=50 ``` ```bash -ls --width=50 +ls --width 50 +``` + +بعض الخيارات بصيغة طويلة تقبل القيمة بشكل اختياري فقط. في هذه الحالة، يجب إرفاق القيمة بالخيار باستخدام رمز يساوي (`=`). على سبيل المثال، خيار `--color` في `ls` يمكن استخدامه بمفرده، أو مع قيمة تشمل أو تستثني الألوان: + +```bash +ls --color=never ``` -لاحظ كيف تستخدم الصيغة القصيرة `-w 50`، بينما تستخدم الصيغة الطويلة `--width=50`. هذا التمييز مهم لتجنب تمرير قيمة الخيار كمعلمة موضعية بدلًا من ذلك. +إذا كتبت `ls --color never` بدلاً من ذلك، سيعامل `ls` كلمة `never` كمعلمة موضعية، أي اسم ملف ليتم عرضه، بدلاً من أن تكون قيمة لخيار `--color`. من المهم معرفة هذا التمييز لتجنب تمرير قيمة الخيار كمعلمة موضعية عن طريق الخطأ. لكن إذا لم تكن متأكدًا، تذكر أنه يمكنك عادةً استخدام علم `--help` لرؤية الصيغة النحوية المتوقعة للخيارات! @@ -119,7 +125,7 @@ ls --width=50 ## --text-- -عند استخدام خيار بصيغة طويلة يتطلب قيمة، ما الصيغة النحوية التي تُستخدم عادةً؟ +عندما يقبل الخيار بصيغة طويلة القيمة بشكل اختياري فقط، مثل `--color` مع `ls`، ما الصيغة التي يجب استخدامها لتمرير القيمة؟ ## --answers-- @@ -127,7 +133,7 @@ ls --width=50 ### --feedback-- -تذكر مثال تعيين `width` باستخدام الخيار بصيغة طويلة. +تذكر ماذا يحدث للقيمة في الأمر `ls --color never`. --- @@ -139,7 +145,7 @@ ls --width=50 ### --feedback-- -تذكر مثال تعيين `width` باستخدام الخيار بصيغة طويلة. +تذكر المثال الخاص بإيقاف الألوان باستخدام خيار `--color`. --- @@ -147,7 +153,7 @@ ls --width=50 ### --feedback-- -تذكر مثال تعيين `width` باستخدام الخيار بصيغة طويلة. +تذكر المثال الخاص بإيقاف الألوان باستخدام خيار `--color`. ## --video-solution-- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687f0a1d5b7c4f21a9d8e123.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687f0a1d5b7c4f21a9d8e123.md index 99d9de7d0f2..7b96c14910c 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687f0a1d5b7c4f21a9d8e123.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-command-line-and-working-with-bash/687f0a1d5b7c4f21a9d8e123.md @@ -7,12 +7,16 @@ dashedName: how-do-you-configure-your-system-language-for-bash-and-postgresql-wo # --description-- +## لماذا يهم تخطيط لوحة المفاتيح لديك؟ + تعلم كيف تؤثر لغة النظام وإعدادات لوحة المفاتيح على ورش عمل Bash وPostgreSQL. تتوقع العديد من أدوات البرمجة أن تستخدم الأوامر أحرف لوحة مفاتيح إنجليزية قياسية. في ورش عمل Bash وPostgreSQL، هذا مهم جدًا للرموز مثل الفواصل المنقوطة (`;`)، وعلامات الاقتباس، والشرط المائلة، وغيرها من الأحرف الخاصة. إذا كان نظام التشغيل أو تخطيط لوحة المفاتيح لديك يستخدم لغة غير الإنجليزية، فقد تتصرف بعض الأحرف بشكل مختلف عن المتوقع. هذا قد يؤدي إلى أخطاء مربكة عند إدخال أوامر SQL أو أوامر الطرفية. +## التبديل إلى تخطيط لوحة مفاتيح الولايات المتحدة + للحصول على أفضل تجربة أثناء العمل في هذه الورش، يُنصح بالتبديل مؤقتًا إلى تخطيط لوحة مفاتيح الإنجليزية (الولايات المتحدة) أثناء إكمال الدورة. هذا مفيد خصوصًا إذا كانت أوامر Bash أو PostgreSQL تُنتج أحرفًا غير متوقعة أو أخطاء صيغة نحوية عند كتابة رموز مثل `;` أو `\`. يستخدم GitHub Codespaces تخطيط لوحة المفاتيح المحلي لديك، لذا فإن تغيير التخطيط على جهازك سيؤثر أيضًا على الكتابة داخل Codespaces. @@ -48,6 +52,8 @@ setxkbmap -query setxkbmap us ``` +## اختبار تخطيط لوحة المفاتيح لديك + بعد التبديل بين التخطيطات، اختبر الأحرف التالية في مربع نص أو الطرفية: ```md @@ -58,7 +64,9 @@ setxkbmap us تعامل بعض التخطيطات غير الإنجليزية مع أحرف مثل `'` و`"` كأحرف ميتة، أي أنها تنتظر ضغطة مفتاح تالية بدلاً من الكتابة فورًا. بعد التبديل إلى تخطيط US، يجب أن تُكتب هذه الأحرف فورًا. إذا لم يظهر الحرف فورًا، فهذا دليل على أن التخطيط لم يتبدل بالكامل. -إذا كنت تستخدم تخطيط لوحة مفاتيح مادي غير US مثل AZERTY أو QWERTZ أو متغيرات QWERTY إقليمية، فقد تكون مفاتيح الرموز في مواقع فيزيائية مختلفة. في هذه الحالة، استخدم لوحة المفاتيح على الشاشة أو عارض لوحة المفاتيح في نظام التشغيل لتحديد مواقع مفاتيح مثل `;`، `/`، `\`، `|`، `'`، و`"` بعد التبديل إلى تخطيط US. +## استخدام لوحة مفاتيح فعلية غير أمريكية + +إذا كنت تستخدم تخطيط لوحة مفاتيح فعلية غير أمريكية مثل AZERTY أو QWERTZ أو نسخ QWERTY الإقليمية، فقد تكون مفاتيح الرموز في مواقع فعلية مختلفة. في هذه الحالة، استخدم لوحة المفاتيح على الشاشة أو عارض لوحة المفاتيح في نظام التشغيل لتحديد مواقع مفاتيح مثل ;، /، \\، |، '، و" بعد التبديل إلى تخطيط الولايات المتحدة. يساعد استخدام تخطيط لوحة مفاتيح الإنجليزية (الولايات المتحدة) على ضمان أن أوامر Bash وPostgreSQL تعمل تمامًا كما هو متوقع طوال الورشة. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67d2ff1996e4ae9e67170502.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67d2ff1996e4ae9e67170502.md index 8c630cf620d..dde4503cc7e 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67d2ff1996e4ae9e67170502.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67d2ff1996e4ae9e67170502.md @@ -9,6 +9,8 @@ dashedName: what-is-unit-testing أثناء تصميم تطبيقاتك، غالبًا ما يكون لديك سلسلة من الدوال الصغيرة المسؤولة عن شيء واحد. يُعرف هذا بمبدأ "المسؤولية الواحدة". عندما يكون لديك سلسلة من الدوال الصغيرة، من الأفضل اختبار هذه الدوال للتأكد من أن كل شيء يعمل كما هو متوقع. في هذا الدرس، سنلقي نظرة على كيفية إنشاء اختبار وحدة باستخدام إطار العمل الشائع Jest. +## الدالة التي يجب اختبارها + في هذا المثال، سننشئ دالة مسؤولة عن إرجاع سلسلة نصية مُنسقة حديثًا: ```js @@ -20,6 +22,8 @@ export function getFormattedWord(str) { تحتوي دالة `getFormattedWord` على معلمة تسمى `str` وستتحقق أولًا مما إذا كانت `str` فارغة. إذا كانت كذلك، فستُرجع سلسلة نصية فارغة. وإلا، فستُرجع سلسلة جديدة حيث تُكتب الحرف الأول بحرف كبير. نحن نصدر هذه الدالة حتى نتمكن من استخدامها في ملف اختبار. +## كتابة اختبارك الأول + في ملف منفصل باسم `getFormattedWord.test.js`، يمكننا كتابة بعض الاختبارات للتحقق من أن الدالة تقوم بما يُفترض بها القيام به. في أعلى ملف `getFormattedWord.test.js`، نحتاج أولًا إلى استيراد الدالة بهذه الطريقة: @@ -38,6 +42,8 @@ test('capitalizes the first letter of a word', () => { تُستخدم دالة `expect` لاختبار قيمة. تُدمج مع matcher، وهي دالة تتحقق مما إذا كانت القيمة تتصرف كما هو متوقع. في هذه الحالة، الـ matcher هو `toBe()`. لدى Jest مجموعة متنوعة من matchers لمساعدتك في اختبار القيم الحقيقية، والسلاسل النصية، والأرقام، والمزيد. +## تشغيل اختباراتك + إحدى الطرق لتشغيل اختباراتك هي إضافة سكربت npm إلى ملف `package.json` الخاص بك. إليك مثالًا على سكربت لإطار العمل Jest: ```js @@ -59,6 +65,8 @@ Time: 0.103 s, estimated 1 s Ran all test suites. ``` +## كيف يبدو الاختبار الفاشل + لرؤية كيف يبدو اختبار فاشل، يمكننا عمدًا كسر الاختبار بتحديث الدالة إلى ما يلي: ```js @@ -97,6 +105,8 @@ Time: 0.121 s, estimated 1 s Ran all test suites. ``` +## إضافة اختبار آخر + الآن يمكننا تحديث دالتنا مرة أخرى إلى الأصلية هنا: ```js @@ -116,6 +126,8 @@ test("returns an empty string when no argument is provided", () => { هناك اختبارات أخرى يمكنك إضافتها لجعل الأمور أكثر متانة، لكن هذين الاختبارين الأولين مقدمة جيدة لاختبار الوحدة. +## أُطُر العمل الشائعة للاختبار + عندما يتعلق الأمر باختبار تطبيقات JavaScript، تشمل أطر العمل الشائعة للاختبار Jest وMocha وVitest. اختبار الوحدة مهم لأنه يساعدك على اكتشاف المزيد من الأخطاء البرمجية في برامجك، ويضمن أن كل شيء يعمل كما هو متوقع. كما يمكن أن يكون شكلًا من أشكال التوثيق لتطبيقك لأنه يهدف إلى تمثيل السلوك المتوقع لكودك. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67db30fedfa0b22a1a2a570c.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67db30fedfa0b22a1a2a570c.md index bd56eda22ed..085192bed9a 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67db30fedfa0b22a1a2a570c.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67db30fedfa0b22a1a2a570c.md @@ -27,18 +27,32 @@ dashedName: what-is-the-software-development-life-cycle-and-how-does-it-relate-t لنلقِ نظرة أقرب على كل هذه المراحل بتفصيل أكبر. +## مرحلة التخطيط + في مرحلة التخطيط، يجمع فريق التطوير المتطلبات للعمل المقترح من أصحاب المصلحة. صاحب المصلحة هو شخص له مصلحة مباشرة في نجاح المنتج أو الخدمة. من أمثلة أصحاب المصلحة المستثمرون، المالكون، أو حتى الموظفون الآخرون. تشمل مرحلة التخطيط أيضًا تقدير تكاليف العمل وإنشاء جدول زمني لإنجاز العمل. +## مرحلة التصميم + المرحلة التالية هي مرحلة التصميم. في هذه المرحلة، يقوم فريق البرمجيات بتفصيل المتطلبات وتحديد أفضل الطرق للحلول. يشمل ذلك تحديد الأدوات الخارجية التي يمكن استخدامها للمساعدة، وما هي الأدوات الداخلية التي يجب بناؤها لإنجاز المهمة. +## مرحلة التنفيذ + بعد مرحلة التصميم، تأتي مرحلة التنفيذ. تتضمن هذه المرحلة تقسيم المتطلبات إلى مهام قابلة للإدارة يوزعها الفريق فيما بينهم ويبنونها. +## مرحلة الاختبار + عند الانتهاء من مرحلة التنفيذ، ينتقل فريق البرمجيات إلى مرحلة الاختبار. تشمل هذه المرحلة الاختبار اليدوي والآلي للعمل الجديد. أحيانًا يختبر الفريق التطبيق طوال مرحلة التطوير بأكملها لاكتشاف وإصلاح أي مشكلات تظهر. +## مرحلة التشغيل + المرحلة التالية هي مرحلة التشغيل. هنا ينشر الفريق التغييرات الجديدة إلى بيئة بناء أو اختبار. يسمح ذلك للفريق باختبار التطبيق أكثر وإصلاح أي مشكلات قبل أن تذهب التغييرات إلى الإنتاج. التطبيق الإنتاجي هو التطبيق الذي يستخدمه المستخدمون النهائيون. +## مرحلة الصيانة + المرحلة الأخيرة هي مرحلة الصيانة. تتضمن إصلاح أي مشكلات تظهر من العملاء في التطبيق الإنتاجي. كما تشمل مراقبة النظام لأي تحسينات محتملة على البرمجيات. +## نماذج الشلال والمرنة + أخيرًا، هناك نماذج مختلفة لدورة حياة تطوير البرمجيات تُستخدم في الصناعة، مثل نموذج الشلال (Waterfall) ونموذج أجايل (Agile). نموذج الشلال يتطلب إكمال كل مرحلة من مراحل الدورة قبل بدء المرحلة التالية. بالمقابل، يركز نموذج أجايل على التطوير التكراري بتقسيم العمل إلى دفعات (sprints) ليتمكن الفريق من إجراء تغييرات سريعة وتسليم العمل تدريجيًا. من خلال المرور بدورة حياة تطوير البرمجيات، يمكن لفريق التطوير وأصحاب المصلحة أن يكونوا على نفس الصفحة فيما يتعلق بالمتطلبات، تقديرات التكاليف، والجداول الزمنية. هذا يعزز التعاون والتواصل بشكل أكثر كفاءة. diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67db31349f3ace2c5c803c33.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67db31349f3ace2c5c803c33.md index 1d79cc7e017..4b40094e82c 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67db31349f3ace2c5c803c33.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-different-types-of-testing/67db31349f3ace2c5c803c33.md @@ -9,6 +9,8 @@ dashedName: what-are-bdd-and-tdd هناك نوعان من أساليب الاختبار يجب أن تعرفهما في تطوير البرمجيات. هذان الأسلوبان هما TDD (التطوير المدفوع بالاختبار) و BDD (التطوير المدفوع بالسلوك). +## التطوير الموجه بالاختبار (TDD) + لنلقِ نظرة أولاً على TDD. التطوير المدفوع بالاختبار هو منهجية تركز على كتابة الاختبارات أولاً قبل بناء الميزات في التطبيق. إليك العملية النموذجية لـ TDD: @@ -29,8 +31,12 @@ dashedName: what-are-bdd-and-tdd بينما تختار بعض فرق البرمجيات اتباع نهج TDD، يُعد TDD موضوعًا مثيرًا للجدل في الصناعة. ستجد العديد من المقالات والفيديوهات التي تدافع عنه وتعارضه في الوقت نفسه. بغض النظر عن رأيك في هذا النهج، من المهم أن تكون على دراية به لأنك قد تواجهه في سيناريوهات واقعية. +## التطوير الموجه بالسلوك (BDD) + الأسلوب الثاني للاختبار الذي سنستعرضه هو التطوير المدفوع بالسلوك (BDD). التطوير المدفوع بالسلوك هو أسلوب يربط سلسلة من الاختبارات بأهداف العمل. يجب كتابة هذه الاختبارات بلغة يفهمها كل من الفنيين وغير الفنيين. +### لغة Gherkin + عند اختبار سلوكيات محددة في تطبيق برمجي، يستخدم BDD عادة لغة Gherkin، التي تُستخدم في الأعمال لوصف السلوكيات والسيناريوهات. تستخدم لغة Gherkin عبارات Given و When و Then عند وصف السيناريوهات. إليك مثال: @@ -43,12 +49,16 @@ dashedName: what-are-bdd-and-tdd **Then** يجب حفظ منشور المدونة وعرضه على الصفحة الرئيسية بالعنوان والمحتوى والطابع الزمني الصحيح. +### كتابة سيناريوهات BDD + أولاً، تريد تعريف سيناريو. تشمل السيناريوهات مثالاً تسجيل المستخدم الدخول إلى تطبيق أو تقديم طلب على موقع ويب. في هذا المثال، السيناريو هو لمستخدم ينشئ منشور مدونة جديد على موقع. بعد تعريف السيناريو، يجب أن تبدأ بعبارة Given. هذه توفر سياقًا لمكان بدء المستخدم قبل تنفيذ الإجراء. تُستخدم عبارة When لتمثيل الإجراء الذي يقوم به المستخدم. أخيرًا، تُستخدم عبارة Then لتمثيل النتيجة المرجوة من الإجراء السابق الذي قام به المستخدم. بمجرد تعريف جميع السيناريوهات، يمكنك كتابة اختبارات لكل سيناريو. +### أُطُر اختبار + أمثلة على أُطُر اختبار BDD تشمل Cucumber و JBehave و SpecFlow. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-http-request-response-model/68dd97fbd18ede5ae983e342.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-http-request-response-model/68dd97fbd18ede5ae983e342.md index eddf5af7ff7..0a380fa29bd 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-http-request-response-model/68dd97fbd18ede5ae983e342.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-http-request-response-model/68dd97fbd18ede5ae983e342.md @@ -37,7 +37,7 @@ dashedName: what-are-the-different-kinds-of-assets-that-are-returned-in-an-http- | --- | --- | | HTML | text/html | | CSS | text/css | -| JavaScript | application/javascript | +| JavaScript | text/javascript | | JPEG | image/jpeg | | PNG | image/png | | GIF | image/gif | diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-the-web-standards-model/69fc757399f4066e674a5161.md b/curriculum/challenges/arabic/blocks/lecture-understanding-the-web-standards-model/69fc757399f4066e674a5161.md index 7615a09c4f2..adaccb0938e 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-the-web-standards-model/69fc757399f4066e674a5161.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-the-web-standards-model/69fc757399f4066e674a5161.md @@ -7,29 +7,37 @@ dashedName: what-does-the-lifecycle-of-web-standards-features-look-like # --description-- +## ما هو دورة حياة الميزة؟ + في الدرس السابق، استعرضنا عملية إنشاء معايير الويب: كيف تُكتب المقترحات، وتُراجع، وفي النهاية تُعتمد. دورة حياة ميزة معيار الويب مرتبطة بذلك، لكنها على مستوى أكثر تفصيلاً. تتبع ميزة واحدة منذ لحظة تحديد شخص ما لمشكلة وحتى إصدارها في كل متصفح رئيسي (وربما إهمالها في النهاية). فكر في العملية كدليل القواعد، ودورة الحياة كالأحداث الفعلية التي تحدث أثناء لعب اللعبة. -1. ## الاقتراح - تبدأ كل ميزة بمشكلة اهتم بها شخص ما بما يكفي ليكتبها. يقدم مطوِّر أو مهندس متصفح أو شركة مشكلة على GitHub أو شرحًا يصف ما لا يستطيع الويب فعله حاليًا ولماذا يجب أن يفعل ذلك. في هذه المرحلة، تكون الفكرة غير محددة، مع وجود أسئلة أكثر من الإجابات. الهدف ببساطة هو معرفة ما إذا كان هناك من يشارك نفس المشكلة. +## 1. الاقتراح + +تبدأ كل ميزة بمشكلة اهتم بها شخص ما بما يكفي ليكتبها. يقدم مطوِّر، مهندس متصفح، أو شركة مشكلة على GitHub أو شرحًا يصف ما لا يستطيع الويب فعله حاليًا ولماذا يجب أن يفعل ذلك. في هذه المرحلة، تكون الفكرة غير محددة، مع وجود أسئلة أكثر من الأجوبة. الهدف ببساطة هو معرفة ما إذا كان هناك من يشارك نفس المشكلة. + +## 2. الحضانة + +إذا لاقى الاقتراح صدى، يدخل فترة من النقاش المفتوح والتصميم المبكر. تُرسم الطرق المتنافسة، تُجمع حالات الاستخدام، ويختبر المجتمع الفكرة تحت الضغط. تموت العديد من الاقتراحات هنا، ربما لأن المشكلة ضيقة جدًا، أو لا يوجد حل يرضي الجميع. الناجون يظهرون بشكل أوضح ويحصلون على اهتمام بعض بائعي المتصفحات. + +## 3. المواصفة + +يُكتب الاقتراح الناجح كمواصفة رسمية. يجب تعريف كل حالة حافة، حالة خطأ، وتفاعل مع الميزات الحالية بوضوح. هذه هي النقطة التي تلتقي فيها الفكرة الجيدة بالواقع الصعب. يجب أن تتحول المفاهيم الغامضة إلى قواعد دقيقة يمكن لمهندسين مستقلين قراءتها وتنفيذها بشكل مطابق. + +## 4. اختبار التوافقية -1. ## الحضانة - إذا لاقى الاقتراح صدى، يدخل فترة من النقاش المفتوح والتصميم المبكر. تُرسم الطرق المتنافسة، وتُجمع حالات الاستخدام، ويختبر المجتمع الفكرة تحت الضغط. تموت العديد من الاقتراحات هنا، ربما لأن المشكلة ضيقة جدًا أو لا يوجد حل يرضي الجميع. الناجون يظهرون بشكل أوضح ويحظون على الأقل ببعض اهتمام بائعي المتصفحات. +قبل اعتبار الميزة مستقرة، يجب أن تتصرف بنفس الطريقة في كل متصفح. مجموعة اختبارات منصة الويب من W3C هي الأداة الرئيسية للتحقق من ذلك. هي مجموعة مشتركة من الاختبارات التي يشغلها Chrome وFirefox وSafari وغيرهم على تطبيقاتهم. تعني النتائج المتباينة إما أن المواصفة غامضة، أو أن هناك خطأ برمجي. يجب حل أي منهما قبل تقدم الميزة. -1. ## المواصفة - يُكتب الاقتراح الناجح كمواصفة رسمية. يجب تعريف كل حالة طرفية، وحالة خطأ، وتفاعل مع الميزات الحالية بوضوح. هذه هي النقطة التي تلتقي فيها الفكرة الجيدة بالواقع الصعب. يجب أن تتحول المفاهيم الغامضة إلى قواعد دقيقة يمكن لمهندسين مستقلين قراءتها وتنفيذها بشكل متطابق. +## 5. الإنهاء -1. ## اختبار التوافقية - قبل اعتبار الميزة مستقرة، يجب أن تتصرف بنفس الطريقة في كل متصفح. مجموعة اختبارات منصة الويب الخاصة بـ W3C هي الأداة الرئيسية للتحقق من ذلك. هي مجموعة مشتركة من الاختبارات التي يشغلها Chrome وFirefox وSafari وغيرهم ضد تطبيقاتهم. تعني النتائج المتباينة إما أن المواصفة غامضة أو أن هناك خطأ برمجي. يجب حل أي منهما قبل تقدم الميزة. +بمجرد أن تجتاز عدة تطبيقات مستقلة الاختبارات، تُنهى الميزة. بالنسبة لـ W3C، تصبح توصية، وبالنسبة لـ TC39، تصل للمرحلة 4، وتُدرج بشكل مستقر في المعيار الحي لـ WHATWG. تُرفع الأعلام وتُطرح الميزة للمستخدمين. في هذه المرحلة، تصبح جزءًا من منصة الويب الأساسية، يمكن لكل مطوِّر الاعتماد عليها إلى أجل غير مسمى. -1. ## الإنهاء - بمجرد أن تجتاز عدة تطبيقات مستقلة الاختبارات، تُنهى الميزة. بالنسبة لـ W3C، تصبح توصية، ولـ TC39، تصل إلى المرحلة 4، وتُدرج بشكل مستقر في المعيار الحي لـ WHATWG. تُرفع الأعلام وتُطرح الميزة للمستخدمين. في هذه المرحلة، تصبح جزءًا من منصة الويب الأساسية، يمكن لكل مطوِّر الاعتماد عليها إلى أجل غير مسمى. +## 6. الإهمال -1. ## الإهمال - لا يشيخ كل معيار بشكل جيد. تحل بعض الميزات محلها ميزات أفضل، ويتبين أن بعضها له آثار أمنية أو خصوصية لم تكن واضحة في البداية. عندما تحتاج ميزة إلى الإزالة، تُهمل رسميًا. أي تُدعم لكنها تُعلَن كشيء يجب على المطوِّرين التوقف عن استخدامه. في النهاية، تُزال من المواصفة. الإزالة من المتصفحات بطيئة وحذرة، لأن الوعد الأساسي للويب هو استمرار عمل الصفحات القديمة. تبقى بعض الميزات المهملة في المتصفحات لعقود فقط من أجل التوافقية مع الإصدارات السابقة. +لا يشيخ كل معيار بشكل جيد. تحل ميزات أفضل محل بعضها، ويكتشف أن بعضها له آثار أمنية أو خصوصية لم تكن واضحة في البداية. عندما تحتاج ميزة إلى الإزالة، تُهمل رسميًا. أي تُدعم لكنها تُعلَّم على أنها شيء يجب على المطوِّرين التوقف عن استخدامه. في النهاية، تُزال من المواصفة. الإزالة من المتصفحات بطيئة وحذرة، لأن الوعد الأساسي للويب هو استمرار عمل الصفحات القديمة. تبقى بعض الميزات المهملة في المتصفحات لعقود فقط من أجل التوافقية العكسية. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-variables-and-data-types/67fe8597975ea634042cad8f.md b/curriculum/challenges/arabic/blocks/lecture-understanding-variables-and-data-types/67fe8597975ea634042cad8f.md index 9774ebd74a3..ec998de2683 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-variables-and-data-types/67fe8597975ea634042cad8f.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-variables-and-data-types/67fe8597975ea634042cad8f.md @@ -7,6 +7,8 @@ dashedName: how-do-you-declare-variables-and-what-are-naming-conventions-to-name # --description-- +## إعلان المتغيرات + في بايثون، المتغيرات تشبه صناديق معنونة لتخزين البيانات من أنواع مختلفة والإشارة إليها. لإنشاء متغير، اكتب اسمه على اليسار، متبوعًا بمعامل التعيين (`=`) والقيمة التي تريد تخزينها على اليمين. إليك مثالًا على كيفية إنشاء متغيري `name` و `age`: ```python @@ -16,6 +18,8 @@ age = 25 في المثال أعلاه، المتغير `name` يحمل القيمة `'John Doe'`. هذه القيمة هي سلسلة نصية، وهي مجموعة من الأحرف تُستخدم لتمثيل النص. تُكتب السلاسل النصية بعلامات اقتباس مفردة أو مزدوجة، مثل `'Hello'` أو `"Hello"`. في الدروس القادمة، ستتعلم المزيد عن التعامل مع السلاسل النصية في بايثون. +## اتباع قواعد التسمية + عند تسمية المتغيرات في بايثون، هناك بعض القواعد المهمة التي يجب أن تضعها في اعتبارك: - يجب أن تبدأ أسماء المتغيرات بحرف أو بشرطة سفلية (`_`) فقط، وليس برقم. @@ -31,6 +35,8 @@ age = 25 SyntaxError: invalid syntax ``` +## اتباع اصطلاحات التسمية + الآن دعنا نستعرض بعض اصطلاحات التسمية الشائعة للمتغيرات في بايثون. أولًا، يجب أن تكون أسماء المتغيرات بأحرف صغيرة، مع فصل الكلمات بشرطة سفلية. هذا يُسمى نمط snake case: @@ -53,6 +59,8 @@ user_age = 30 x = 56 # What do you mean by x? ``` +## كتابة التعليقات + رمز الشباك (`#`) والنص الذي يليه يشكلان تعليقًا. التعليقات تتيح لك إضافة ملاحظات وتوضيحات إلى كودك. في بايثون، تبدأ التعليقات برمز الباوند (`#`)، وتتجاهل اللغة كل شيء بعد رمز `#` في ذلك السطر: diff --git a/curriculum/challenges/arabic/blocks/lecture-understanding-variables-and-data-types/6a03f5d143c8688a9265c0a0.md b/curriculum/challenges/arabic/blocks/lecture-understanding-variables-and-data-types/6a03f5d143c8688a9265c0a0.md index e392ca4fbbc..317f0aab414 100644 --- a/curriculum/challenges/arabic/blocks/lecture-understanding-variables-and-data-types/6a03f5d143c8688a9265c0a0.md +++ b/curriculum/challenges/arabic/blocks/lecture-understanding-variables-and-data-types/6a03f5d143c8688a9265c0a0.md @@ -1,6 +1,6 @@ --- id: 6a03f5d143c8688a9265c0a0 -title: كيف تعمل الدالتان type() و isinstance()؟ +title: كيف تعمل الدالتان type()‎ و isinstance()‎؟ challengeType: 19 dashedName: how-do-the-type-and-isinstance-functions-work --- diff --git a/curriculum/challenges/arabic/blocks/lecture-what-is-css/672acc03c257524d6a5151e8.md b/curriculum/challenges/arabic/blocks/lecture-what-is-css/672acc03c257524d6a5151e8.md index 9591a97ac90..792f2863a4a 100644 --- a/curriculum/challenges/arabic/blocks/lecture-what-is-css/672acc03c257524d6a5151e8.md +++ b/curriculum/challenges/arabic/blocks/lecture-what-is-css/672acc03c257524d6a5151e8.md @@ -7,10 +7,14 @@ dashedName: how-do-width-and-height-work # --interactive-- +## مقدمة إلى العرض والارتفاع + في CSS، تُستخدم الخاصيتان `width` و`height` للتحكم في أبعاد العناصر على صفحة الويب. يمكن تعريف هذه الخصائص بوحدات مختلفة مثل البكسل (`px`)، النسب المئوية (`%`)، وحدات إطار العرض (`vw`، `vh`)، والمزيد. +## الخاصيتان `width` و `height` + تحدد الخاصية `width` عرض العنصر. إذا لم تحدد عرضًا، فالقيمة الافتراضية تكون `auto`. هذا يسمح للمتصفح بتحديد عرض العنصر بناءً على محتواه، والوالد، ونوع العرض. بالنسبة لعنصر `div`، تجعل `width: auto` العنصر يتمدد ليملأ العرض الكامل لحاويته الوالد. تحدد الخاصية `height` ارتفاع العنصر. بالمثل، يكون الارتفاع `auto` افتراضيًا، مما يعني أنه سيتكيف مع المحتوى الموجود بداخله. @@ -40,6 +44,8 @@ dashedName: how-do-width-and-height-work البكسل هو وحدة قياس ثابتة الحجم في CSS، توفر تحكمًا دقيقًا في الأبعاد. +## الخاصيتان `min-width` و `min-height` + تحدد خاصية `min-width` الحد الأدنى لعرض العنصر. حتى لو كان المحتوى بداخله أصغر، لن ينكمش العنصر إلى أقل من هذه القيمة. تحدد الخاصية `min-height` الحد الأدنى لارتفاع العنصر. تضمن ألا يصبح العنصر أقصر من القيمة المحددة. @@ -73,6 +79,8 @@ dashedName: how-do-width-and-height-work تذكر، إذا كانت `min-width` أو `min-height` أكبر من `width` أو `height`، فإنها تتجاوز القيم الأصغر. هذا يضمن ألا تصبح العناصر صغيرة جدًا، وهو أمر مهم للحفاظ على تصميم متسق وسهل الاستخدام. +## الخاصيتان `max-width` و `max-height` + تحدد الخاصية `max-width` الحد الأقصى لعرض العنصر، حتى إذا كان هناك مساحة كافية ليكون أعرض. تحدد الخاصية `max-height` الحد الأقصى لارتفاع العنصر، بغض النظر عن حجم المحتوى. @@ -104,6 +112,8 @@ dashedName: how-do-width-and-height-work تذكر، عندما تكون `max-width` أو `max-height` أصغر من `width` أو `height`، فإنها تأخذ الأسبقية. هذا مهم للتحكم في الحد الأقصى لحجم العناصر في تخطيطاتك. +## أسبقية الخاصيات + تعطي CSS أولوية للخاصيتين `min-width` و`min-height` على `width` و`height`. بينما تحدد `max-width` و`max-height` الأبعاد إذا تجاوزت القيم الحدود المحددة. على سبيل المثال، إذا عرّفت `width` بقيمة `600px` و`max-width` بقيمة `500px`، فسيقتصر عرض العنصر على `500px`. حيث يتجاوز `max-width` القيمة الأكبر، مما يحافظ على العنصر ضمن الحد الأقصى المحدد. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-backgrounds-and-borders/672aa669960f6a596081fcad.md b/curriculum/challenges/arabic/blocks/lecture-working-with-backgrounds-and-borders/672aa669960f6a596081fcad.md index 3562f7d4287..1f53dc34acc 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-backgrounds-and-borders/672aa669960f6a596081fcad.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-backgrounds-and-borders/672aa669960f6a596081fcad.md @@ -7,6 +7,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen # --interactive-- +## مقدمة إلى خصائص الخلفية + عند العمل مع صور الخلفية في CSS، لديك عدة خصائص للتحكم في كيفية عرض هذه الصور. الخصائص الرئيسية التي سنركز عليها هي `background-size`، و`background-repeat`، و`background-position`، و`background-attachment`. @@ -27,6 +29,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen يُعيّن كود CSS أعلاه صورة خلفية لقطة لعنصر `body`. +## خاصية `background-size` + إذا أردت تحديد حجم صورة الخلفية، يمكنك استخدام خاصية `background-size`. يمكنك استخدام القيمة `contain` لتكبير الصورة إلى أكبر حجم ممكن دون قص أو تمديد. @@ -65,6 +69,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen ::: +## خاصية `background-repeat` + في الأمثلة السابقة، ربما لاحظت أن صورة الخلفية كانت تتكرر باستمرار. افتراضيًا، تتكرر صور الخلفية أفقيًا وعموديًا لملء العنصر بالكامل. لكن يمكنك التحكم في هذا السلوك. @@ -122,6 +128,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen ::: +## خاصية `background-position` + لوضع صورة خلفية على الشاشة، يمكنك استخدام خاصية `background-position`. تسمح خاصية `background-position` بتحديد مكان ظهور صورة الخلفية داخل العنصر. يمكنك استخدام كلمات مفتاحية مثل `top`، `bottom`، `left`، `right`، و`center`، أو قيم بكسل أو نسب مئوية محددة. @@ -146,6 +154,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen يضع كود CSS هذا صورة الخلفية في مركز العنصر أفقيًا وفي الأعلى عموديًا. +## خاصية `background-attachment` + أخيرًا، تحدد خاصية `background-attachment` ما إذا كانت صورة الخلفية تتحرك مع المحتوى عند التمرير أو تبقى ثابتة عند التمرير. القيم الرئيسية هي `scroll` (افتراضيًا)، حيث تتحرك صورة الخلفية مع المحتوى، و`fixed`، حيث تبقى صورة الخلفية في نفس الموضع على الشاشة. @@ -168,6 +178,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen يُعيّن كود CSS هذا صورة الخلفية لتبقى ثابتة في مكانها حتى عند تمرير الصفحة. +## الخاصية المختصرة `background` + إذا أردت دمج بعض الخصائص في سطر واحد، يمكنك فعل ذلك باستخدام خاصية الاختصار `background`. إليك مثال: diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-code-editors-and-ides/672d26269456511aa3db614d.md b/curriculum/challenges/arabic/blocks/lecture-working-with-code-editors-and-ides/672d26269456511aa3db614d.md index 9ec632a9b7c..f148fa9e28a 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-code-editors-and-ides/672d26269456511aa3db614d.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-code-editors-and-ides/672d26269456511aa3db614d.md @@ -7,8 +7,12 @@ dashedName: what-is-a-code-editor-and-ide # --description-- +## ما هي محررات الكود وبيئات التطوير المتكاملة؟ + قد تظن أنهما نفس الشيء، لكن ليس تمامًا. محرر الكود هو أي تطبيق يسمح لك بتحرير ملفات الكود. أما بيئة التطوير المتكاملة (IDE) فهي تطبيق كامل يسمح لك بترجمة الكود، وتشغيله، وتصحيح الأخطاء أثناء تحريره. +## استكشاف بيئات التطوير المتكاملة الشهيرة + بعض الأمثلة ستساعد في التوضيح. أولًا، دعنا نلقي نظرة على بعض بيئات التطوير المتكاملة الشهيرة. Visual Studio هي بيئة تطوير متكاملة من مايكروسوفت توفر مجموعة شاملة من الأدوات لبناء التطبيقات وتصحيح أخطائها ونشرها عبر منصات مختلفة. @@ -17,6 +21,8 @@ dashedName: what-is-a-code-editor-and-ide Android Studio، الذي طورته Google، هو بيئة تطوير متكاملة مصممة خصيصًا لبناء، وتصحيح الأخطاء، واختبار تطبيقات Android. +## استكشاف محررات الكود الشهيرة + هذه مجرد أمثلة قليلة على بيئات التطوير المتكاملة. الآن، لنلقِ نظرة على بعض محررات الكود الشهيرة. Visual Studio Code هو محرر كود مفتوح المصدر وخفيف الوزن من مايكروسوفت يدعم مجموعة واسعة من لغات البرمجة ويوفر ميزات مثل تصحيح الأخطاء، تمييز الصيغة النحوية، والتحكم في الإصدارات عبر الإضافات. @@ -27,6 +33,8 @@ Visual Studio Code هو محرر كود مفتوح المصدر وخفيف ال قد لاحظت كيف يركز محررو الكود بشكل أساسي على محتوى النص في الملف، بينما تتيح بيئات التطوير المتكاملة أدوات مختلفة لإدارة الكود الخاص بك. +## استكشاف المحررات السحابية + كل هذه الأمثلة برامج محلية يمكنك تشغيلها على جهاز الكمبيوتر الخاص بك، لكن هناك أيضًا محررات قائمة على السحابة يمكنك استخدامها. المحرر المستند إلى السحابة هو أداة عبر الإنترنت تسمح للمستخدمين بكتابة وتحرير وإدارة الكود أو النص مباشرة من خلال متصفح الويب دون الحاجة إلى تثبيت برامج محليًا. @@ -39,6 +47,8 @@ Replit هو منصة عبر الإنترنت توفر بيئة تعاونية ل StackBlitz هو محرر آخر قائم على السحابة. يعمل مباشرة في المتصفح ويتيح لك بناء واختبار ومشاركة مشاريع الويب دون الحاجة إلى إعداد محلي. +## اختيار المحرر المناسب + وهناك العديد من الخيارات الأخرى. بعض الخيارات، مثل Visual Studio Code، قابلة للتوسيع بشكل كبير ويمكنها العمل مع العديد من أنواع المشاريع واللغات. خيارات أخرى قد تكون مخصصة لمجموعة جزئية صغيرة من اللغات أو أنواع المشاريع. التطبيق الذي تستخدمه قد يختلف حسب المشروع المحدد. يجب أن تستكشف الخيارات لترى ما يناسب احتياجاتك أفضل. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-code-editors-and-ides/672d456f4ac35950b300e93f.md b/curriculum/challenges/arabic/blocks/lecture-working-with-code-editors-and-ides/672d456f4ac35950b300e93f.md index a3de3305e2e..af74ebb0c95 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-code-editors-and-ides/672d456f4ac35950b300e93f.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-code-editors-and-ides/672d456f4ac35950b300e93f.md @@ -7,8 +7,12 @@ dashedName: what-are-several-useful-keyboard-shortcuts-for-maximizing-productivi # --description-- +## اختصارات موروثة من نظام التشغيل + من المحتمل أنك تعرف بالفعل بعض الاختصارات الأساسية، التي ترثها من نظام التشغيل الخاص بك. اختصارات مثل Ctrl + S (ويندوز/لينكس) أو Cmd + S (ماك) للحفظ، وCtrl + C أو Cmd + C للنسخ، وCtrl + V أو Cmd + V للصق تعمل كلها في VS Code. +## اختصارات خاصة بالتطبيق + لكن هناك بعض الاختصارات الخاصة بالتطبيق والتي يمكنها رفع إنتاجيتك. يجدر بالذكر أن بعض هذه الاختصارات قد تختلف حسب نظام التشغيل. على سبيل المثال، Shift + Alt + F يشغّل أداة التنسيق المهيأة لديك (مثل Prettier لمشروع جافاسكريبت) على الملف المفتوح حاليًا. @@ -21,8 +25,12 @@ dashedName: what-are-several-useful-keyboard-shortcuts-for-maximizing-productivi أو ربما لا ترى كودك؟ Ctrl + Plus (ويندوز/لينكس)، أو Cmd + Plus (ماك)، يزيد تكبير المحرر، وCtrl + Minus (ويندوز/لينكس)، أو Cmd + Minus (ماك)، يقلل التكبير. +## اختصار التحرير متعدد الأسطر + ميزة مفيدة أخرى في VS Code هي التحرير متعدد الأسطر، الذي يسمح بإجراء تغييرات عبر عدة أسطر دفعة واحدة. على سبيل المثال، يمكنك وضع عدة مؤشرات باستخدام Ctrl + Alt + Down وCtrl + Alt + Up (ويندوز)، Shift + Alt + Down وShift + Alt + Up (لينكس)، أو Option + Cmd + Down وOption + Cmd + Up (ماك)، لتمديد المؤشر إلى أسطر متتالية. يمكنك أيضًا الضغط مع الاستمرار على Alt (ويندوز/لينكس) أو Option (ماك) والنقر لإضافة مؤشرات على أسطر منفصلة حيثما تحتاجها. بمجرد وضع المؤشرات، أي شيء تكتبه أو تحذفه سيطبق على كل تلك المواقع في نفس الوقت، مما يوفر الكثير من الوقت عند العمل مع كود متكرر. +## لوحة الأوامر ومرجع اختصارات لوحة المفاتيح + أخيرًا، إذا نسيت أيًا من هذه الاختصارات، لديك دائمًا Ctrl + Shift + P (ويندوز/لينكس) أو Cmd + Shift + P (ماك)، التي تفتح لوحة الأوامر لتختار ما تحتاجه.
اختصارات ومُدخلات سطر الأوامر
Linux، macOS، وPowerShell
إكمال اقتراح (الإكمال التلقائي باستخدام Tab)إكمال اقتراح (الإكمال باستخدام Tab) TabLinux، macOS، وPowerShell (مصدر الاقتراح يختلف حسب الصدع - على سبيل المثال، يستخدم zsh سجل الأوامر الأخير، بينما يستخدم PowerShell الأوامر والمتغيرات والمعلمات المتاحة)Linux و macOS و PowerShell (تعتمد الاقتراحات على الصدفة، والأمر الذي تكتبه، وتكوينك)
مسح الطرفية
مقاطعة عملية جارية Control + CLinux، macOS، وPowerShell (في PowerShell يُستخدم أيضًا لنسخ النص، وينهي العملية فقط عندما لا يكون هناك نص محدد للنسخ)Linux و macOS و PowerShell (في PowerShell يُستخدم أيضًا لنسخ النص، ويقاطع الأمر فقط عندما لا يكون هناك نص محدد للنسخ)
نقل عملية إلى الخلفيةتعليق العملية في المقدمة Control + ZLinux وmacOS فقط، لا يوجد بديل في PowerShellLinux و macOS فقط، لا يوجد بديل في PowerShell (استخدم bg لاستئنافها في الخلفية أو fg لاستئنافها في المقدمة)
إعادة تشغيل الأمر السابق
diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-code-quality-and-execution-concepts/6732c6c72d3738614e1230a2.md b/curriculum/challenges/arabic/blocks/lecture-working-with-code-quality-and-execution-concepts/6732c6c72d3738614e1230a2.md index 6c7bbb1e7a2..b591110f1c9 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-code-quality-and-execution-concepts/6732c6c72d3738614e1230a2.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-code-quality-and-execution-concepts/6732c6c72d3738614e1230a2.md @@ -9,10 +9,14 @@ dashedName: what-are-linters-and-formatters-and-how-can-they-help-you-with-code- في عالم تطوير البرمجيات، من المهم الحفاظ على كود نظيف ومتسق وخالٍ من الأخطاء. هنا تأتي أهمية أدوات الفحص والتنسيق. هذه الأدوات ضرورية للمطورين لضمان جودة الكود واتساقه عبر المشاريع والفرق. +## ما هو الـ Linter؟ + لنبدأ بأدوات الفحص. أداة الفحص هي أداة تحليل كود ثابتة تُشير إلى أخطاء البرمجة، والأخطاء البرمجية، وأخطاء الأسلوب، والبُنى المشبوهة. مصطلح lint يأتي من أداة يونكس تفحص الكود المصدري للغة C. توجد اليوم أدوات فحص لمعظم لغات البرمجة بما في ذلك JavaScript. تساعد أدوات الفحص بعدة طرق. أولاً، تكتشف الأخطاء المحتملة قبل وقت التشغيل. على سبيل المثال، قد تشير أداة الفحص إلى استخدام متغير غير مُعلن أو استدعاء دالة بعدد معلمات خاطئ. كما تفرض معايير الترميز وأفضل الممارسات. قد تشمل هذه القواعد التنسيق، واستخدام الفواصل المنقوطة، أو الحد الأقصى لطول السطر. وأخيرًا، تساعد في الحفاظ على الاتساق عبر قاعدة الكود خاصة عندما يعمل عدة مطورين على نفس المشروع. +## تدقيق الكود باستخدام ESLint + أداة فحص شهيرة لـ JavaScript هي ESLint. إليك مثالًا بسيطًا لما قد تشير إليه ESLint: ```js @@ -23,10 +27,14 @@ function doSomething(x) { في هذا الكود، المتغير `z` غير مُعلن، لذا ستشير ESLint إلى الخطأ `z` is not defined. أيضًا، الجملة الأخيرة تفتقد فاصلة منقوطة، والتي قد تشير إليها ESLint في محرر الكود. +## ما هو الـ Formatter؟ + أما أدوات التنسيق فهي أدوات تعيد تنسيق كودك تلقائيًا ليتوافق مع دليل أسلوب محدد. بينما يمكن لأدوات الفحص إصلاح بعض المشاكل تلقائيًا، فإن أدوات التنسيق مصممة خصيصًا لإعادة كتابة الكود ليتطابق مع أسلوب محدد مسبقًا. تضمن أدوات التنسيق أسلوب كود متسق عبر المشروع أو الفريق بأكمله بغض النظر عن تفضيلات المطورين الفردية. كما توفر الوقت والطاقة الذهنية التي تُصرف على التنسيق اليدوي. وأخيرًا، تجعل مراجعات الكود أكثر كفاءة عبر القضاء على النقاشات حول أسلوب الكود. +## تنسيق الكود باستخدام Prettier + أداة التنسيق الشهيرة لـ JavaScript هي Prettier. إليك مثالًا على كيفية تنسيق Prettier للكود. هذا هو الكود قبل التنسيق: ```js @@ -45,10 +53,14 @@ function longFunction(argument1, argument2, argument3) { } ``` +## دمج الـ Linters و Formatters + يمكن دمج كل من أدوات الفحص والتنسيق في سير عمل التطوير بطرق مختلفة. يمكن تضمينها في عملية البناء أو إضافتها كمكونات إضافية لمحرر النصوص أو بيئة التطوير المتكاملة، مما يوفر تغذية راجعة فورية أثناء كتابة الكود. استخدام أدوات الفحص والتنسيق معًا يحسن بشكل كبير جودة الكود واتساقه. على سبيل المثال، قد تستخدم ESLint لاكتشاف الأخطاء المحتملة وفرض ممارسات ترميز معينة، ثم تستخدم Prettier للتعامل مع جميع مهام التنسيق. يقوم العديد من فرق التطوير بإعداد هذه الأدوات كجزء من تكوين المشروع، غالبًا مع hooks قبل الالتزام تُشغّل أداة الفحص وأداة التنسيق قبل السماح بالالتزام بالكود. هذا يضمن أن كل الكود في المستودع يلتزم بمعايير الفريق للجودة والأسلوب. +## ملخص + باختصار، أدوات الفحص والتنسيق هي أدوات قوية تساعد في الحفاظ على جودة الكود، واكتشاف الأخطاء المحتملة مبكرًا، وضمان الاتساق عبر قواعد الكود. من خلال أتمتة هذه الجوانب من مراجعة الكود، تسمح للمطورين بالتركيز أكثر على حل المشكلات وأقل على مناقشة أسلوب الكود. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-code-reviews-branching-deployment-and-ci-cd/688291b65db00473e1136725.md b/curriculum/challenges/arabic/blocks/lecture-working-with-code-reviews-branching-deployment-and-ci-cd/688291b65db00473e1136725.md index 4478f97a0ab..ba010782378 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-code-reviews-branching-deployment-and-ci-cd/688291b65db00473e1136725.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-code-reviews-branching-deployment-and-ci-cd/688291b65db00473e1136725.md @@ -7,16 +7,22 @@ dashedName: what-is-ci-cd-and-how-does-ci-work-with-github-actions # --description-- +## ما هو CI/CD؟ + تشير CI إلى التكامل المستمر، وCD تشير إلى التسليم المستمر أو النشر المستمر. معًا، تتيح هذه العمليات نشر التغييرات على تطبيقك تلقائيًا بعد التأكد من أن تلك التغييرات تعمل بشكل صحيح. في خط أنابيب التكامل المستمر (CI)، قد تُشغّل أداة التدقيق والاختبارات على الكود. عادةً ما تعمل خطوط أنابيب CI على طلبات السحب لضمان أن التغييرات التي أُجريت لا تُسبب تعطل التطبيق، وأيضًا على فرع `main` لضمان جاهزيته للنشر. قد يُشغّل خط أنابيب CD أيضًا على طلبات السحب، إذا أعددت بيئة معاينة لتتمكن من مشاهدة التغييرات مباشرة. لكنك ستشغّله أيضًا على فرع `main` لنشر التغييرات باستمرار بمجرد قبولها ودمجها. +## ما هي GitHub Actions؟ + لكن كيف تعمل هذه الأمور فعليًا مع GitHub Actions؟ أولًا، نحتاج لفهم ما هي GitHub Actions. توفر GitHub Actions مشغلات مؤقتة (فكر فيها كحاسوب مؤقت) تتيح لك تنفيذ أوامر محددة. تُكوّن Actions باستخدام ملف YAML. يمكنك أن تملك ملفات متعددة لتحديد إجراءات مختلفة للتشغيل. على سبيل المثال، قد يكون لديك ملف واحد لـ CI وآخر لـ CD. +## مثال على ملف تكوين GitHub Actions + لنلقِ نظرة على مثال أساسي لـ CI: ```yml @@ -61,6 +67,8 @@ jobs: run: pnpm run test ``` +## أجزاء ملف التكوين + هذا كثير، فلنقسّمه. ننظر إلى القسم الأول: ```yml @@ -121,10 +129,16 @@ on: لدينا قسم `Install Dependencies` الذي يثبت حزم npm. وقسم `Lint Source Files` يشغّل أداة التدقيق، وقسم `Verify Build` يتأكد من أن كود TypeScript يمكن تجميعه، وقسم `Run Tests` يشغّل اختبارات الوحدة. +## السلوك الافتراضي لـ GitHub Actions + الأمر المهم الذي يجب معرفته عن الإجراءات هو أنه، افتراضيًا، إذا فشلت إحدى هذه الخطوات، تُتخطى الخطوات المتبقية ويُعلَن تشغيل العملية كفشل. +## موقع ملف تكوين GitHub Actions + أين تضع ملفات YAML الخاصة بك لتشغيل هذه الإجراءات؟ يجب أن توضع في مجلد `.github/workflows` داخل مستودعك حتى يجدها GitHub ويستخدمها. +## الخطوة التالية + هناك الكثير من الأشياء الإضافية التي يمكن للإجراءات فعلها، وأشجعك على قراءة الوثائق واستكشاف الإجراءات الموجودة في مشاريع مثل مستودع freeCodeCamp. لكن الآن، يجب أن تكون لديك فهم جيد لأساسيات GitHub Actions وCI/CD! # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-colors-in-css/672bc51370c789be459186b4.md b/curriculum/challenges/arabic/blocks/lecture-working-with-colors-in-css/672bc51370c789be459186b4.md index eed2c0ebf29..efeb39cecfc 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-colors-in-css/672bc51370c789be459186b4.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-colors-in-css/672bc51370c789be459186b4.md @@ -7,6 +7,8 @@ dashedName: what-is-the-rgb-color-model # --interactive-- +## مقدمة إلى نموذج ألوان RGB + عند العمل مع الألوان في CSS، من الضروري فهم نموذج ألوان RGB. يشير RGB إلى الأحمر والأخضر والأزرق — الألوان الأساسية للضوء. تُدمج هذه الألوان الثلاثة بشدة مختلفة لإنشاء مجموعة واسعة من الألوان. نموذج ألوان RGB هو نموذج ألوان إضافي، ما يعني أن الألوان تُنشأ بدمج الضوء بشدات متفاوتة. @@ -17,6 +19,8 @@ dashedName: what-is-the-rgb-color-model - يُمثّل اللون الأبيض بـ `rgb(255, 255, 255)`، مما يعني شدة ضوء كاملة لكل الألوان الثلاثة. - يُمثّل اللون الأحمر بـ `rgb(255, 0, 0)`، مع شدة كاملة للأحمر ولا شيء للأخضر أو الأزرق. +## دالة `rgb()` في CSS + في CSS، تتيح لك الدالة `rgb()` تعريف الألوان باستخدام نموذج ألوان RGB. تأخذ الدالة ثلاث قيم، كل واحدة تمثل شدة الضوء الأحمر والأخضر والأزرق على التوالي. هذه هي الصيغة النحوية الأساسية: ```css @@ -44,6 +48,8 @@ p { سيغير هذا الكود لون نص الفقرة إلى الأحمر لأن قيمة الأحمر مضبوطة على `255`، بينما القيمتان الأخضرو والأزرق مضبوطة على `0`. +## الشفافية مع دالة `rgba()` + يوفر CSS أيضًا دالة `rgba()`، التي تضيف قيمة رابعة — ألفا — تتحكم في شفافية اللون. تتراوح قيمة الألفا من `0` (شفاف تمامًا) إلى `1` (غير شفاف تمامًا). إليك مثالًا على استخدام `rgba()`: :::interactive_editor @@ -63,6 +69,8 @@ div { سيطبق هذا الكود خلفية زرقاء نصف شفافة على عنصر `div` لأن قيم الأحمر والأخضر مضبوطة على `0`، وقيمة الأزرق مضبوطة على `255`، وقيمة ألفا مضبوطة على `0.5` (شفافية 50%). +## لماذا تستخدم نموذج ألوان RGB؟ + نموذج ألوان RGB مفيد جدًا للوسائط الرقمية لأنه يتوافق مباشرة مع كيفية عرض الشاشات للألوان. تستخدم الشاشات وحدات بكسل صغيرة حمراء وخضراء وزرقاء لإنشاء الألوان التي تراها. بالتحكم في شدة هذه البكسلات عبر قيم RGB، يمكنك تحقيق مجموعة واسعة من الألوان لتصميم الويب الخاص بك. بالإضافة إلى ذلك، يعد نموذج RGB مثاليًا عند العمل مع التصاميم الديناميكية. على سبيل المثال، إذا أردت إنشاء رسوم متحركة أو تأثيرات لونية تتطلب تغييرات في الوقت الحقيقي، فإن مرونة دالة RGB تتيح لك تعديل الألوان برمجيًا. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-css-flexbox/672bd658c0e190f674a5e057.md b/curriculum/challenges/arabic/blocks/lecture-working-with-css-flexbox/672bd658c0e190f674a5e057.md index 81b58c18929..43b07fb6229 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-css-flexbox/672bd658c0e190f674a5e057.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-css-flexbox/672bd658c0e190f674a5e057.md @@ -586,6 +586,7 @@ div { #third-div { background-color: #4da3b2; align-self: stretch; + height: auto; } ``` diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-css-grid/673226a62eb2121da41a3d68.md b/curriculum/challenges/arabic/blocks/lecture-working-with-css-grid/673226a62eb2121da41a3d68.md index 0e1d4aa4028..b51ad5c4cde 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-css-grid/673226a62eb2121da41a3d68.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-css-grid/673226a62eb2121da41a3d68.md @@ -1,6 +1,6 @@ --- id: 673226a62eb2121da41a3d68 -title: ما هي دالة minmax() وكيف تعمل؟ +title: ما هي دالة minmax()‎ وكيف تعمل؟ challengeType: 19 dashedName: what-is-the-minmax-function-and-how-does-it-work --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bcc9c4a6dd6d7dd3e6357.md b/curriculum/challenges/arabic/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bcc9c4a6dd6d7dd3e6357.md index b4769ef7052..8c3bfe172e7 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bcc9c4a6dd6d7dd3e6357.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bcc9c4a6dd6d7dd3e6357.md @@ -13,15 +13,23 @@ dashedName: what-is-the-css-box-model مساحة المحتوى هي الجزء الداخلي الأعمق من الصندوق. هي المساحة التي تحتوي على المحتوى الفعلي للعنصر مثل النص أو الصور. +![مخطط نموذج صندوق CSS يُظهر صندوق المحتوى البرتقالي في المركز، محاط بثلاثة حدود خارجية متداخلة غير معنونة](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-is-the-css-box-model-1.png) + الحشو هو المنطقة التي تلي مساحة المحتوى مباشرة. هو المساحة بين مساحة المحتوى وحدود العنصر. باستخدام الحشو يمكنك إضافة مساحة حول المحتوى لتحسين قابليته للقراءة. يمكنك تعيين قيم مختلفة للحشو العلوي واليميني والسفلي واليساري باستخدام خاصية `padding`. +![مخطط نموذج صندوق CSS يبرز مساحة المحتوى البرتقالية المحاطة بمنطقة الحشو الزرقاء، محاطة بحدود صندوق خارجية غير معنونة](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-is-the-css-box-model-2.png) + هذا مثال باستخدام الخاصية المختصرة `padding`، حيث نعيّن الحشو العلوي إلى خمسة عشر بكسل، والحشو الأيمن إلى خمسة بكسلات، والحشو السفلي إلى بكسلين، والحشو الأيسر إلى ثمانية بكسلات: ```css padding: 15px 5px 2px 8px; ``` -الحدود هي الحافة الخارجية أو الإطار المرئي للعنصر في نموذج الصندوق في CSS. هي الحدود البصرية للعنصر. يمكنك تخصيص نمط الحدود، عرضها، لونها، وخصائص أخرى باستخدام خاصية `border`. إليك مثالًا حيث نعيّن الحدود بعرض خمسة بكسلات، والنمط إلى solid، واللون إلى الأزرق: +الحدود هي الحافة الخارجية أو الإطار لعناصر نموذج صندوق CSS. إنها الحدود المرئية للعنصر. يمكنك تخصيص نمط الحدود، العرض، اللون وخصائص أخرى باستخدام الخاصية `border`. + +![مخطط نموذج صندوق CSS يبرز مساحة المحتوى البرتقالية، منطقة الحشو الزرقاء، ومنطقة الحدود الزرقاء الداكنة، محاطة بحدود صندوق خارجية غير معنونة](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-is-the-css-box-model-3.png) + +إليك مثال حيث نحدد الحدود بعرض خمسة بكسلات، والنمط صلب، واللون أزرق: ```css border: 5px solid blue; @@ -41,6 +49,8 @@ border-color: blue red green black; أخيرًا، الهامش هو المساحة خارج حدود العنصر. يحدد المسافة بين العنصر والعناصر الأخرى المحيطة به. يمكنك تعيين قيم هامش مختلفة للجهات العلوية واليمنى والسفلية واليسرى للعنصر باستخدام خاصية `margin`. +![مخطط نموذج صندوق CSS بأربع مناطق متداخلة. من المركز: مساحة المحتوى البرتقالية، منطقة الحشو الزرقاء، منطقة الحدود الزرقاء الداكنة، ومنطقة الهامش الرمادية الخارجية](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-is-the-css-box-model-4.png) + في هذا المثال، الهامش العلوي هو ثلاثة بكسلات، والهامش الأيمن اثنا عشر بكسلًا، والهامش السفلي تسعة بكسلات، والهامش الأيسر سبعة بكسلات: ```css diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bccebe1fc82d911c3f078.md b/curriculum/challenges/arabic/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bccebe1fc82d911c3f078.md index ab25c4a22e9..bb55559c67e 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bccebe1fc82d911c3f078.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bccebe1fc82d911c3f078.md @@ -9,6 +9,8 @@ dashedName: what-is-the-css-filter-property خاصية `filter` في CSS هي أداة قوية تتيح لك تطبيق تأثيرات رسومية على العناصر في صفحة الويب. تفيد بشكل خاص في تعديل العرض البصري للصور، والخلفيات، وحتى النصوص دون تعديل الأصل. +## صيغة `filter` + يمكن استخدام خاصية `filter` لإنشاء تأثيرات متنوعة مثل التمويه، وتحويل الألوان، وتعديل التباين. دعنا نناقش كيف تعمل خاصية الفلتر ونستعرض بعض الأمثلة الشائعة. الصيغة الأساسية لخاصية `filter` بسيطة: ```css @@ -19,6 +21,8 @@ selector { هنا، تمثل `function` التأثير الفلتر المحدد الذي تريد تطبيقه، و`amount` عادةً قيمة تحدد شدة التأثير. الآن دعنا نلقي نظرة على بعض دوال الفلتر الشائعة واستخداماتها. +## دالة `blur` + :::interactive_editor ```html @@ -36,6 +40,8 @@ img { تطبق دالة `blur` تمويه غاوسي على العنصر، وتُحدد القيمة بالبكسل وتمثل نصف قطر التمويه. ستطبق هذه القاعدة في CSS تمويهًا بمقدار 2 بكسل على جميع الصور في الصفحة. يمكن أن يكون تأثير `blur` مفيدًا لإنشاء عمق في التصميم أو لإخفاء أجزاء من الصورة. +## دالة `brightness` + تُعدل دالة `brightness` سطوع العنصر. قيمة `0%` تجعل العنصر أسود تمامًا، بينما القيم التي تزيد عن `100%` تزيد السطوع. :::interactive_editor @@ -55,6 +61,8 @@ img { تزيد هذه القاعدة في CSS سطوع عنصر الصورة بنسبة `50%`. يمكن استخدام تعديلات السطوع لجعل الصور تبرز أو لإنشاء تأثير باهت. +## دالة `grayscale` + تحول دالة `grayscale` العنصر إلى تدرج رمادي. تُحدد القيمة كنسبة مئوية، حيث `100%` تعني تدرج رمادي كامل و`0%` تترك الصورة دون تغيير. :::interactive_editor @@ -74,6 +82,8 @@ img { ستحول هذه القاعدة عنصر الصورة إلى تدرج رمادي كامل. يمكن استخدام `grayscale` لإنشاء مظهر قديم أو لتقليل التركيز على عناصر معينة في الصفحة. +## دالة `sepia` + تطبق دالة `sepia` نغمة سيبيا على العنصر. مثل التدرج الرمادي، تستخدم قيمة مئوية: :::interactive_editor @@ -93,6 +103,8 @@ img { تطبق هذه القاعدة تأثير سيبيا بنسبة `80%` على عنصر الصورة. تأثير السيبيا رائع لإنشاء مظهر قديم أو كلاسيكي. +## دالة `hue-rotate` + تطبق دالة `hue-rotate` تدويرًا للون على العنصر. تُحدد القيمة بالدرجات وتمثل دورانًا حول دائرة الألوان. :::interactive_editor @@ -112,6 +124,8 @@ img { تدور هذه القاعدة لون عنصر الصورة بمقدار `90` درجة. يمكن استخدام تدوير اللون لإنشاء تأثيرات نفسية أو لتعديل نظام الألوان العام للصورة. +## دمج الفلاتر + واحدة من أقوى ميزات خاصية `filter` هي القدرة على دمج تأثيرات متعددة. يمكنك تطبيق عدة فلاتر على نفس العنصر بفصلها بمسافات: :::interactive_editor diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d1a99d10fd509c88faf3bf.md b/curriculum/challenges/arabic/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d1a99d10fd509c88faf3bf.md index 3d3439bf5d4..075439fb518 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d1a99d10fd509c88faf3bf.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d1a99d10fd509c88faf3bf.md @@ -11,10 +11,14 @@ dashedName: how-does-data-fetching-work-in-react لنلقِ نظرة على كيفية عمل جلب البيانات في React والخيارات المختلفة المتاحة لك لجلب البيانات. +## خيارات جلب البيانات + React لا تفرض طريقة معينة لجلب بياناتك، وهذا يعني على المستوى الأساسي، يمكنك استخدام واجهة Fetch API المدمجة، التي تدعمها جميع المتصفحات الحديثة. يمكنك أيضًا استخدام Axios وSWR. Axios هي مكتبة طلبات HTTP قائمة على الوعود مبنية فوق كائن XMLHttpRequest، وSWR هو hook في React لجلب البيانات أنشأه فريق Vercel. +## جلب البيانات باستخدام Fetch API + لنبدأ بمثال. تحتاج أولًا إلى استيراد الـ `useState` و `useEffect` hooks: ```js @@ -31,6 +35,8 @@ const [error, setError] = useState(null); المتغير `loading` يتتبع ما إذا كانت البيانات لا تزال تُجلب. المتغير `data` يمثل البيانات نفسها، والمتغير `error` يلتقط أي أخطاء قد تحدث أثناء عملية جلب البيانات. +### الجلب داخل `useEffect` + بما أن جلب البيانات هو تأثير جانبي، فمن الأفضل استخدام Fetch API داخل hook `useEffect`. إليك مثال على ذلك: @@ -52,6 +58,8 @@ useEffect(() => { هذا الـ `useEffect` يجلب البيانات باستخدام Fetch API ويضبط جميع الحالات. +### استخدام `async`/`await` + يمكنك تحسين الأمور باستخدام `async`/`await` بدلاً من صيغة `.then()`. هذا يعني أنه يجب أن يكون لديك دالة منفصلة داخل `useEffect` لأنك لا تستطيع إضافة بادئة `async` على `useEffect` مباشرة: ```js @@ -77,6 +85,8 @@ useEffect(() => { }, []); ``` +### المكوِّن الكامل + بعدها يمكنك استخدام كل تلك الحالات لعرض البيانات من API. إليك الكود الكامل: @@ -132,6 +142,8 @@ export default FetchPosts; في واجهة المستخدم، سترى `Loading...` على الشاشة أثناء جلب البيانات، ثم تظهر البيانات أو الخطأ حسب نجاح جلب البيانات. +## جلب البيانات باستخدام Axios + تذكر أننا تحدثنا أيضًا عن جلب البيانات باستخدام Axios وSWR. لنلقِ نظرة على مثال باستخدام Axios. أولًا ستحتاج إلى تثبيت Axios من سطر الأوامر هكذا: @@ -173,6 +185,8 @@ useEffect(() => { ربما لاحظت أنه لا يوجد سطر `await res.json()` في هذا المثال. ذلك لأن Axios يقوم بتحليل JSON تلقائيًا، فلا حاجة لذلك. +## جلب البيانات باستخدام SWR + المثال الأخير الذي سننظر إليه هو استخدام hook `useSWR` لجلب البيانات. تمامًا كما هو الحال مع Axios، ستحتاج إلى تثبيت SWR هكذا: @@ -235,6 +249,8 @@ const FetchTodos = () => { export default FetchTodos; ``` +## إنشاء هوك `useFetch` + كما تعلمت في درس سابق عن الـ custom hooks، جلب البيانات هو منطق يمكنك استخراجه إلى hook مخصص. لذلك، إذا كنت تجلب البيانات في مكونات وصفحات متعددة، فمن الأفضل إنشاء hook `useFetch`. إليك hook `useFetch` الذي يستخدم SWR لجلب البيانات: diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d2f4ddb4a4306fdf5bbaee.md b/curriculum/challenges/arabic/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d2f4ddb4a4306fdf5bbaee.md index 7923c500150..3373e4e1375 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d2f4ddb4a4306fdf5bbaee.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d2f4ddb4a4306fdf5bbaee.md @@ -15,6 +15,8 @@ dashedName: what-is-memoization-and-how-does-the-usememo-hook-work يحل React هذه المشكلة باستخدام عملية تسمى التذكر (memoization)، وهي تقنية تخزن القيم والدوال مؤقتًا لمنع إعادة الحسابات غير الضرورية، ليصبح تطبيقك أسرع وأكثر تجاوبًا. +## ما هي تقنية التذكر المؤقت (Memoization)؟ + بالتعريف، التذكر هو تقنية تحسين تُخزن فيها نتائج استدعاءات الدوال المكلفة (تُتذكر) بناءً على معلمات محددة. عند توفير نفس المعلمات مرة أخرى، تُعاد النتيجة المخزنة بدلاً من إعادة حساب الدالة. تتم عملية التذكر بهذه الطريقة: @@ -27,6 +29,8 @@ dashedName: what-is-memoization-and-how-does-the-usememo-hook-work - إذا لم تكن موجودة، احسب النتيجة، خزّنها في المخزن المؤقت، ثم أعدها. +## أدوات التذكر المؤقت في React + لتحسين تجربة المطوِّر مع التذكر، يوفر React ثلاث أدوات – `React.memo` (أو `memo`)، `useMemo` و`useCallback`. كما قد تتوقع، كل من `useMemo` و`useCallback` هما خطافان، لكن `React.memo` هو غلاف مكوِّن، مكوِّن رتبة عليا (HOC). @@ -37,6 +41,8 @@ dashedName: what-is-memoization-and-how-does-the-usememo-hook-work إذا كنت تتساءل ما هي القيم المحسوبة ومراجع الدوال، فالقيم المحسوبة تشير إلى نتيجة تنفيذ دالة، بينما مراجع الدوال هي المؤشرات إلى الدوال – كائن الدالة في الذاكرة. +## صيغة استخدام الخطاف `useMemo` + لنرَ كيف تستخدم الخطاف `useMemo` أولاً. إليك الصيغة النحوية الأساسية للخطاف `useMemo`: ```js @@ -50,6 +56,8 @@ const memoizedValue = useMemo( يمكنك أن ترى أن كل ما تحتاجه هو تغليف الخطاف `useMemo` حول الدالة. +## مثال: مكوِّن `ExpensiveSquare` + سيستقبل هذا المكوِّن `ExpensiveSquare` خاصية `num` التي سيستخدمها لحساب المربع: ```jsx @@ -98,6 +106,8 @@ export default App; الـ `timer` في `useEffect`، الذي يعمل كل ثانية، سيجعل دالة `calculateSquare` تُنفذ في كل مرة تعمل فيها، حتى عندما لا تزيد متغير الحالة `num`. +## استخدام `useMemo` لتجنب إعادة الحسابات + لحل هذه المشكلة، يمكننا استخدام الخطاف `useMemo` بتغليف استدعاء الدالة بداخله وتحديد المتغير `num` كاعتماد: ```jsx diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-data-in-react/6734e3ceee2da4b0301719b7.md b/curriculum/challenges/arabic/blocks/lecture-working-with-data-in-react/6734e3ceee2da4b0301719b7.md index 08777b8469d..2788977290d 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-data-in-react/6734e3ceee2da4b0301719b7.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-data-in-react/6734e3ceee2da4b0301719b7.md @@ -29,10 +29,14 @@ function Greeting() { } ``` +## لماذا نستخدم الخصائص؟ + بينما سيعمل هذا الكود بشكل جيد ويعرض النتيجة `Hi Jessica!` على الشاشة، إلا أنه ليس مكوِّنًا مرنًا جدًا. ماذا لو أردنا عرض اسم مختلف مثل Naomi أو Tom أو Oliver؟ هنا تأتي أهمية الخصائص في React. الخصائص، وهي اختصار لـ properties، هي الطريقة التي تمرر بها المكوِّنات الأب البيانات إلى المكوِّن الفرعي. يمكن أن تكون الخصائص من أي نوع: سلاسل نصية، أرقام، قيم منطقية، كائنات، أو مصفوفات. +## تمرير الخصائص إلى مكوِّن فرعي + لنحدّث مثالنا السابق ليقبل الآن خاصية `name`: ```jsx @@ -52,6 +56,8 @@ function Greeting(props) { ثم، داخل مكوِّن الأب `App`، نمرر القيمة إلى الخاصية `name` لكي تُمرر إلى المكوِّن الفرعي. ستكون النتيجة نفسها على الشاشة كما في السابق، لكننا أنشأنا مكوِّنًا أكثر مرونة. +### إعادة استخدام المكوِّن الفرعي + الآن لدينا القدرة على إعادة استخدام المكوِّن الفرعي عدة مرات وتمرير أسماء مختلفة في كل مرة: ```jsx @@ -67,6 +73,8 @@ function App() { } ``` +## تفكيك الخصائص + يمكنك أيضًا اختيار استخدام التفكيك في الخصائص لجعلها أكثر قابلية للقراءة. إليك كيف يمكنك إعادة كتابة مكوِّن `Greeting`: ```jsx @@ -77,6 +85,8 @@ function Greeting({ name }) { يحقق هذا الكود نفس النتيجة لكنه يوضح بشكل أفضل الخصائص التي يتوقع المكوِّن استلامها. +## الخاصية `children` + يوفر React أيضًا خاصية خاصة تسمى `children`. أي JSX تضعه بين وسم الفتح ووسم الإغلاق لمكوِّن يُمرر إلى المكوِّن كـ `children`. على سبيل المثال: @@ -105,6 +115,8 @@ function App() { يُستخدم هذا النمط غالبًا لتكوين المكوِّنات، حيث يلتف مكوِّن حول عناصر واجهة مستخدم أخرى. +## تمرير خصائص متعددة باستخدام معامل النشر + أحيانًا، قد يكون لديك الكثير من الخصائص التي يجب تمريرها كمُدخلات. بدلًا من تمريرها واحدة تلو الأخرى، يمكنك استخدام معامل النشر (`...`) بعد تحويلها إلى كائن. إليك مثال على مكوِّن فرعي جديد يسمى `DeveloperCard`: diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-data-in-react/673500b41af8500191febedc.md b/curriculum/challenges/arabic/blocks/lecture-working-with-data-in-react/673500b41af8500191febedc.md index 44815745dbf..945e768b9e1 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-data-in-react/673500b41af8500191febedc.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-data-in-react/673500b41af8500191febedc.md @@ -9,6 +9,8 @@ dashedName: how-do-you-render-lists-in-react عرض القوائم مهمة أساسية في تطبيقات الويب باستخدام React، وتُستخدم لعرض البيانات للمستخدمين. في React، تُستخدم طريقة `map` لتحويل مصفوفة من البيانات إلى مصفوفة من عناصر JSX يمكن عرضها في واجهة المستخدم. +## عرض القوائم باستخدام `map` + إليك مثالًا على مكوِّن يسمى `FruitList` يعرض قائمة من الفواكه: ```jsx @@ -24,10 +26,14 @@ function FruitList() { في هذا المثال، تقوم دالة `map` بالتكرار على كل عنصر في مصفوفة `fruits`. لكل ثمرة، تُنشئ عنصر `li` جديد يحتوي على اسم الثمرة. ثم تُعرض مصفوفة عناصر `li` الجديدة داخل وسم الأب `ul`. +## الخاصية `key` + مع ذلك، عند عرض القوائم في React، من المهم ألا تنسى خاصية `key` لكل عنصر في القائمة. يجب أن تكون القيمة فريدة دائمًا، وتساعد React على تحديد العناصر التي تغيرت أو أُضيفت أو أُزيلت، وهذا ضروري لعرض القائمة وتحديثها بكفاءة. إذا نسيت خاصية key، ستظهر تحذيرات في وحدة التحكم، لكنها لن تسبب خطأً قاتلًا. قد يستمر التطبيق في العرض والعمل، لكن قد تواجه أخطاء برمجية دقيقة، خاصة عند تغير القائمة. هذه الأخطاء قد يصعب معالجتها لأن واجهة المستخدم قد تبدو صحيحة في البداية. +### استخدام الفهرس كمفتاح + خطأ شائع هو استخدام فهرس المصفوفة كـ key، مثل هذا: ```jsx @@ -36,10 +42,14 @@ function FruitList() { رغم أن هذا يُخمد التحذير، إلا أنه يُعتبر نمطًا خاطئًا عمومًا. استخدام الفهرس كـ key قد يسبب مشاكل عند إعادة ترتيب القائمة أو فرزها أو تصفيتها. تستخدم React الخاصية key لتتبع العناصر. إذا تغير ترتيب القائمة، قد تعيد React استخدام حالة المكوِّن بشكل خاطئ أو تفشل في تحديث DOM بكفاءة لأن المفاتيح (الفهارس) تبقى نفسها حتى لو تغير المحتوى في ذلك الفهرس. +### استخدام معرفات مستقرة وفريدة + أفضل الممارسات هي استخدام معرف فريد ومستقر لكل عنصر. عادةً يكون هذا معرفًا من قاعدة البيانات، مثل UUID أو معرف قاعدة بيانات. إذا لم يكن لديك معرف فريد في بياناتك، يمكنك توليد واحد عند إنشاء البيانات (مثلًا باستخدام `crypto.randomUUID()` أو مكتبة مثل `uuid`)، أو استخدام تركيبة من الحقول التي تضمن التفرد. مع ذلك، يجب تجنب توليد المفاتيح أثناء العرض (مثلًا `key={Math.random()}`)، لأن ذلك يجعل React يعيد إنشاء عناصر DOM في كل عرض ويعيد تعيين حالتها. +### إضافة المفاتيح إلى المثال + لنُعدّل مثالنا ليشمل المفاتيح: ```jsx @@ -57,6 +67,8 @@ function FruitList() { في هذا المثال المعاد هيكلته، نُنشئ مفتاحًا فريدًا لكل عنصر في القائمة بدمج اسم الثمرة مع فهرسها. هذا يضمن أن لكل عنصر مفتاح مميز، مما يساعد React على إدارة القائمة وتحديثها بكفاءة عند إضافة أو إزالة أو إعادة ترتيب العناصر. +## عرض قوائم من الكائنات + تسمح React أيضًا بعرض هياكل أكثر تعقيدًا. على سبيل المثال، قد يكون لديك مصفوفة من الكائنات تمثل المستخدمين، كل منهم له خصائص متعددة تريد عرضها: ```jsx diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac3c5d0e9fd31835ff772.md b/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac3c5d0e9fd31835ff772.md index ea344a096bf..3028a04b496 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac3c5d0e9fd31835ff772.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac3c5d0e9fd31835ff772.md @@ -11,14 +11,26 @@ dashedName: how-to-create-move-and-delete-files-and-folders-using-explorer-finde لإنشاء ملف على Windows باستخدام Explorer، يمكنك النقر على خيار "جديد" في أعلى اليسار. سيعرض لك هذا قائمة بأنواع الملفات المختلفة التي يمكنك إنشاؤها. -يمكنك أيضًا إنشاء الملفات في التطبيقات الخاصة بها. لننشئ ملف نصي لنوضح لك العملية. +![مستكشف ملفات Windows مع تمييز زر "جديد" بمربع وبرسمة سهم برتقالي في الأعلى إلى اليسار، ومستند نصي جديد محدد في مجلد ملفات freeCodeCamp.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-1.png) + +يمكنك أيضًا إنشاء الملفات في التطبيقات الخاصة بها. + +![مستكشف ملفات Windows يعرض مجلد ملفات freeCodeCamp داخل المستندات، مع تحديد مستند نصي جديد.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-2.png) + +لننشئ ملف نصي لنوضح لك العملية. عندما تنقر على "جديد" وتحدد نوع الملف، سترى ملف نصي جديد في المجلد الحالي باسم افتراضي. يمكنك إعادة تسميته إذا أردت. +![أيقونة مستند نصي مع اسم الملف demo.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-3.png) + عملية إنشاء المجلدات هي نفسها تمامًا. انقر على زر "جديد" في أعلى اليسار ثم اختر خيار "مجلد" أو انقر بزر الفأرة الأيمن على مكان فارغ واذهب إلى "جديد" ثم اختر "مجلد". سترى مجلدًا جديدًا فارغًا في موقعك الحالي. +![مستكشف ملفات Windows يعرض مجلدًا جديدًا باسم New folder في مجلد ملفات freeCodeCamp.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-4.png) + ### إعادة تسمية الملفات والمجلدات +![شريط أدوات مستكشف ملفات Windows مع زر إعادة التسمية، يظهر كحرف A بجانب مؤشر نص، مميز بمربع أخضر.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-5.png) + يمكنك إعادة تسمية الملفات والمجلدات بتحديدها ثم النقر على خيار "إعادة التسمية" في الأعلى. عندما يُظلل اسم الملف الحالي، يمكنك البدء بكتابة الاسم الجديد. اضغط Enter لتأكيد التغييرات. بدلاً من ذلك، يمكنك النقر بزر الماوس الأيمن على الملف أو المجلد واختيار خيار "إعادة التسمية" أو استخدام اختصار لوحة المفاتيح F2. اكتب الاسم الجديد واضغط Enter لتأكيد التغييرات. @@ -29,13 +41,21 @@ dashedName: how-to-create-move-and-delete-files-and-folders-using-explorer-finde يمكنك أيضًا تحديد الملف أو المجلد واختيار خيار "قص" في الأعلى. +![شريط أدوات مستكشف ملفات Windows مع زر القص، يظهر كمقص، مميز بمربع أخضر.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-6.png) + ثم اذهب إلى المجلد الوجهة والصقه بالنقر على زر "لصق" في الأعلى. إذا كنت قد نسخت أو قصصت الملف سابقًا، سيكون هذا الزر مفعّلًا. +![شريط أدوات مستكشف ملفات Windows مع زر اللصق، يظهر كمفكرة، مميز بمربع أخضر.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-7.png) + يمكنك أيضًا فعل ذلك بالنقر بزر الفأرة الأيمن على مكان فارغ ثم النقر على أيقونة اللصق. هذا سيزيل الملف أو المجلد من موقعه الأصلي. ### حذف الملفات والمجلدات -لحذف ملف أو مجلد، انقر عليه ثم انقر على أيقونة سلة المهملات في الأعلى. ستجد أيضًا خيار "حذف" إذا نقرت بزر الفأرة الأيمن عليه. +لحذف ملف أو مجلد، انقر عليه ثم انقر على أيقونة سلة المهملات في الأعلى. + +![شريط أدوات مستكشف ملفات Windows مع زر الحذف، يظهر كرمز سلة مهملات، مميز بمربع أخضر.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-8.png) + +ستجد أيضًا خيار "حذف" إذا نقرت بزر الفأرة الأيمن عليه. ## استخدام Finder على macOS @@ -49,30 +69,58 @@ Finder هو مدير الملفات الافتراضي على macOS. على سبيل المثال، لإنشاء ملف نصي بسيط، يمكنك فتح TextEdit وحفظ ملفك. العملية تعمل بنفس الطريقة لأي نوع ملف. -هناك عدة طرق لفتح TextEdit. واحدة منها هي الذهاب إلى Launchpad. ثم ابحث عن تطبيق يمكنك من خلاله إنشاء نوع الملف الذي تهتم به. في هذه الحالة، سيكون "TextEdit". انقر على الأيقونة لفتح التطبيق. +هناك عدة طرق لفتح TextEdit. واحدة منها هي الذهاب إلى Launchpad. + +![أيقونة Launchpad في macOS، مربع مستدير يحتوي على شبكة من مربعات التطبيقات الملونة.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-9.png) + +ثم ابحث عن تطبيق يمكنك من خلاله إنشاء نوع الملف الذي تهتم به. في هذه الحالة، سيكون "TextEdit". انقر على الأيقونة لفتح التطبيق. + +![حقل البحث في Launchpad يحتوي على النص TextEdit، مع أيقونة تطبيق TextEdit أسفله.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-10.png) بمجرد دخولك التطبيق، يجب أن ترى خيارًا لحفظ ملفك في قائمة File. تقع هذه القائمة في أعلى اليسار، بجانب أيقونة قائمة Apple. +![TextEdit مفتوح مع مستند فارغ. سهم أخضر يشير إلى شريط قوائم macOS في الأعلى، الذي يعرض TextEdit، ملف، تحرير، تنسيق، عرض، نافذة، ومساعدة.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-11.png) + في أحد خيارات قائمة التطبيق، يجب أن ترى أمرًا لحفظ الملف. عادةً ما يكون هذا تحت قائمة File. +![تكبير لشريط قوائم macOS يظهر شعار Apple، ثم TextEdit، ملف، تحرير، تنسيق، عرض، نافذة، ومساعدة.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-12.png) + بجانبه، سترى اختصار لوحة المفاتيح لحفظ الملف. عادةً ما يكون Command + S على macOS. +![قائمة ملف TextEdit مفتوحة، مع تمييز خيار حفظ وإظهار اختصار Command + S على اليمين.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-13.png) + عند حفظ الملف لأول مرة، سترى نافذة حوار حيث يمكنك كتابة اسم الملف واختيار موقعه. عادةً ما يضيف التطبيق امتداد الملف تلقائيًا لكن يمكنك تغييره قبل حفظ الملف. -بعد حفظ الملف، يمكنك فتح Finder بالنقر على أيقونة Finder في Dock. يجب أن ترى ملفك الجديد في المجلد الذي حفظته فيه. +![نافذة حفظ TextEdit مع Untitled.txt في حقل حفظ باسم، متصفح مجلد، وأزرار إلغاء وحفظ في الأسفل.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-14.png) + +بعد حفظ الملف، يمكنك فتح Finder بالنقر على أيقونة Finder في Dock. + +![أيقونة Finder في Dock الخاص بـ macOS، وجه مبتسم أزرق وأبيض.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-15.png) + +يجب أن ترى ملفك الجديد في المجلد الذي حفظته فيه. + +![نافذة Finder تعرض مجلد ملفات freeCodeCamp يحتوي على ملف واحد، demo.txt.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-16.png) ### إنشاء المجلدات لإنشاء مجلد جديد، يجب أن تذهب إلى الموقع الذي تريد إنشاء المجلد فيه وتنقر بزر الفأرة الأيمن على مكان فارغ. سترى قائمة خيارات. الخيار الأول هو "مجلد جديد". +![قائمة سياق Finder مفتوحة على مساحة فارغة، مع تمييز خيار مجلد جديد في أعلى القائمة.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-17.png) + إذا نقرت عليه، يمكنك تعيين اسم للمجلد الجديد. اكتب الاسم واضغط Enter للتأكيد. +![مجلد جديد في Finder باسم untitled folder، مع تمييز اسمه للتحرير.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-18.png) + +![نفس المجلد بعد إعادة تسميته إلى freeCodeCamp.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-19.png) + ### نقل الملفات والمجلدات هناك عدة طرق لنقل الملفات والمجلدات في Finder. إذا كنت تحتاج إلى نقلها إلى مجلد مدرج في قسم "المفضلات" في Finder، يمكنك فقط سحبها وإفلاتها. +![نافذة Finder مع سحب demo.txt إلى Documents في الشريط الجانبي للمفضلات، موضح بأسهم خضراء.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-20.png) + إذا كنت تحتاج إلى نقلها إلى مجلد مختلف، لديك خياران. يمكنك إما فتح المجلد الوجهة كتَبويب وسحب الملف أو المجلد وإفلاته في التبويب. @@ -83,10 +131,18 @@ Finder هو مدير الملفات الافتراضي على macOS. لحذف ملف أو مجلد، يمكنك النقر بزر الفأرة الأيمن عليه واختيار "نقل إلى المهملات". +![قائمة سياق Finder لملف demo.txt مع تمييز خيار النقل إلى المهملات.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-21.png) + +![قائمة سياق Finder لمجلد freeCodeCamp مع تمييز خيار النقل إلى المهملات.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-22.png) + يمكنك أيضًا سحبها وإفلاتها في أيقونة المهملات على Dock. هذا يعادل نفس الشيء. +![أيقونة المهملات في Dock الخاص بـ macOS، سلة مليئة بورق مجعد.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-23.png) + عندما يكون الملف أو المجلد في سلة المهملات، يمكنك النقر بزر الفأرة الأيمن عليه لحذفه فورًا أو يمكنك تفريغ المهملات لإزالة جميع الملفات والمجلدات المحذوفة نهائيًا. +![نافذة مهملات Finder مع قائمة السياق المفتوحة لملف demo.txt، تعرض فتح، فتح باستخدام، إعادة، حذف فورًا، وتفريغ المهملات.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-24.png) + ## ملخص اختصارات لوحة المفاتيح
diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac3f129efbf327742eb33.md b/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac3f129efbf327742eb33.md index 455c046d90b..8f83b20cfb1 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac3f129efbf327742eb33.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac3f129efbf327742eb33.md @@ -13,10 +13,14 @@ dashedName: how-to-search-for-files-and-folders-on-your-computer للبحث من شريط المهام، اكتب اسم الملف أو المجلد الذي تبحث عنه. يمكنك أيضًا البحث باستخدام الكلمات المفتاحية. سترى النتائج من جميع أنحاء جهاز الكمبيوتر وOneDrive. +Windows 11 taskbar with Start button, search bar, Task View, and Chrome icon + إذا أردت رؤية المستندات فقط، يمكنك النقر على تبويب "المستندات". لديك أيضًا تبويبات للتطبيقات ونتائج الويب. بديل آخر هو استخدام البحث في مستكشف الملفات. ستجده في أعلى يمين نافذة المستكشف، حيث ترى "بحث في المستندات". +Windows File Explorer with the Search Documents box highlighted on the top right + لديك ثلاث خيارات لتحديد نطاق البحث: - يمكنك البحث من Home للعثور على الملفات من جهاز الكمبيوتر ومن السحابة بسرعة. @@ -27,15 +31,37 @@ dashedName: how-to-search-for-files-and-folders-on-your-computer هذه هي طريقة البحث عن الملفات والمجلدات على Windows. الآن لنرَ كيف تفعل ذلك على macOS. -أولًا، يمكنك استخدام Spotlight، أداة تساعدك في العثور على الملفات على جهاز Mac. لفتح Spotlight، اذهب إلى شريط القوائم في الأعلى يمينًا وابحث عن أيقونة العدسة المكبرة. إذا لم ترَ هذه الأيقونة في شريط القوائم، يمكنك إضافتها في إعدادات Control Center. +أولًا، يمكنك استخدام Spotlight، أداة تساعدك في العثور على الملفات على جهاز Mac الخاص بك. لفتح Spotlight، اذهب إلى شريط القوائم في الأعلى على اليمين وابحث عن أيقونة العدسة المكبرة. + +macOS menu bar featuring system icons including the magnifying glass Spotlight icon + +إذا لم ترَ هذه الأيقونة في شريط القوائم، يمكنك إضافتها من إعدادات مركز التحكم. + +اذهب إلى الإعدادات، صنّف حسب "مركز التحكم"، انقر على هذا الخيار ثم مرر للأسفل حتى تجد خيار "Spotlight". + +macOS Control Center settings window showing Spotlight set to Show in Menu Bar + +يمكنك أيضًا استخدام اختصار لوحة المفاتيح لفتح Spotlight: Command + Spacebar. -اذهب إلى الإعدادات، صفِّ حسب "مركز التحكم"، انقر على هذا الخيار ثم مرر للأسفل حتى تجد خيار "Spotlight". يمكنك أيضًا استخدام اختصار لوحة المفاتيح لفتح Spotlight: Command + Spacebar. +عند فتح Spotlight، سترى بحث Spotlight، حيث يمكنك البحث عن أي ملف أو مجلد بكتابة اسمه. -عند فتح Spotlight، سترى بحث Spotlight حيث يمكنك البحث عن أي ملف أو مجلد بكتابة اسمه. عند البدء بالكتابة، سترى النتائج مجمعة حسب الفئة، بما في ذلك الاقتراحات، المجلدات، العروض التقديمية، الصور، المستندات، والبحثات ذات الصلة. +macOS Spotlight Search bar open on screen + +عندما تبدأ بالكتابة، سترى النتائج مجمعة حسب الفئة، بما في ذلك الاقتراحات، المجلدات، العروض التقديمية، الصور، المستندات، والبحثات ذات الصلة. يمكنك أيضًا توسيع فئة معينة بالنقر على "عرض المزيد". -طريقة أخرى للبحث عن الملفات التي فتحتها مؤخرًا هي فتح Finder بالنقر على أيقونة Finder في Dock. ثم اذهب إلى "Recents" في شريط جانبي Finder. هناك ستجد كل الملفات التي شاهدتها مؤخرًا. +macOS Spotlight Search displaying search results for freeCodeCamp + +طريقة أخرى للبحث عن الملفات التي فتحتها مؤخرًا هي فتح Finder بالنقر على أيقونة Finder في Dock. + +macOS Dock featuring the blue Finder icon alongside Launchpad and Google Chrome icons + +ثم، اذهب إلى "المحفوظات" في شريط Finder الجانبي. + +macOS Finder sidebar with the Recents option highlighted under Favorites + +وهناك، ستجد كل الملفات التي شاهدتها مؤخرًا. هذه هي طريقة البحث عن الملفات والمجلدات على macOS. باستخدام هذه الأدوات، يمكنك تحسين سير عملك والعثور على الملفات والمجلدات التي تحتاجها بسرعة كبيرة. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac403a9ba7732b31c6480.md b/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac403a9ba7732b31c6480.md index c74283248d2..106bf9bdcbc 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac403a9ba7732b31c6480.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-file-systems/672ac403a9ba7732b31c6480.md @@ -63,6 +63,8 @@ WOFF هو تنسيق خط حديث، صُمم خصيصًا لأغراض تطوي عادةً ما تُكتب هذه الملفات بتنسيق يسمى Markdown. باستخدام Markdown، يمكنك إنشاء مستندات منظمة تحتوي على عناوين، وعناوين فرعية، وروابط، وصور، وقوائم، وأكثر. لملفات Markdown امتداد `.md` أو `.markdown`. +![لقطة شاشة لملف README.md الخاص بـ freeCodeCamp معروض على GitHub، تُظهر عنوانًا وفقرة تمهيدية وجدول محتويات يحتوي على روابط لأقسام تشمل الشهادات والمساهمة.](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-are-some-common-file-types-you-will-work-with-in-web-applications-1.png) + هنا يمكنك العثور على ملف `README` لمستودع freeCodeCamp على GitHub: `https://github.com/freeCodeCamp/freeCodeCamp/blob/main/README.md` يمكنك إنشاء هذا الهيكل التفصيلي والتنسيق باستخدام Markdown. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-forms/672a4cd3d59756726657efb8.md b/curriculum/challenges/arabic/blocks/lecture-working-with-forms/672a4cd3d59756726657efb8.md index 33e847368ce..7c6813bc6b6 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-forms/672a4cd3d59756726657efb8.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-forms/672a4cd3d59756726657efb8.md @@ -13,6 +13,8 @@ dashedName: what-are-the-different-types-of-buttons ``` +## نوع `button` + تشمل أمثلة أخرى لاستخدام عنصر `button` إرسال نموذج، عرض نافذة منبثقة، أو تبديل قائمة جانبية مفتوحة ومغلقة. يحتوي عنصر `button` على خاصية `type` التي تتحكم في سلوك الزر عند تفعيله. القيمة الأولى الممكنة لخاصية `type` هي النوع `button`. إليك مثالًا على استخدام عنصر `button` مع النوع `button` ونص `Show Alert`: ```html @@ -40,6 +42,8 @@ btn.addEventListener("click", () => alert("You clicked on the alert button")); ::: +## نوعا `submit` و `reset` + قيمة أخرى ممكنة لخاصية `type` هي القيمة `submit`. إليك مثالًا على استخدام عنصر `button` مع النوع `submit`. :::interactive_editor @@ -73,6 +77,8 @@ btn.addEventListener("click", () => alert("You clicked on the alert button")); في هذا المثال المعدل، يُستخدم عنصر `label` وعنصر `input` لجمع عنوان البريد الإلكتروني للمستخدم. عند نقر المستخدم على زر إعادة التعيين، يمسح كل بيانات المُدخَل الخاصة به. من المهم ملاحظة أن أزرار إعادة التعيين عادةً ليست فكرة جيدة لأنها قد تؤدي إلى إعادة تعيين البيانات عن طريق الخطأ. أيضًا، وجود عدة أزرار في النموذج قد يزدحم واجهة المستخدم. +## استخدام عنصر `input` كزر + طريقة أخرى لإنشاء أزرار في HTML هي استخدام عنصر `input`. يحتوي عنصر `input` أيضًا على خاصية `type` بالقيم الممكنة `submit` و`reset` و`button`. إليك مثالًا على استخدام عنصر `input` مع تعيين `type` إلى `button`: :::interactive_editor @@ -97,6 +103,8 @@ document.addEventListener("DOMContentLoaded", () => { ::: +## الفرق الرئيسي بين `input` و `button` + تُستخدم خاصية `value` لعرض نص الزر. فما الفرق بين استخدام عنصري `input` و`button`؟ عناصر `input` هي عناصر فارغة، مما يعني أنها لا يمكن أن تحتوي على عقد فرعية مثل النص، ويمكن أن يكون لها وسم بداية فقط. من ناحية أخرى، يوفر عنصر `button` مرونة أكبر لأنه يمكنك تسكين نصوص وصور وأيقونات بداخله. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-forms/672a4ce6dab9eb735828b48b.md b/curriculum/challenges/arabic/blocks/lecture-working-with-forms/672a4ce6dab9eb735828b48b.md index 0cdeb7bd1d1..a20d6a632ed 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-forms/672a4ce6dab9eb735828b48b.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-forms/672a4ce6dab9eb735828b48b.md @@ -9,12 +9,16 @@ dashedName: what-is-client-side-form-validation-in-html-forms عندما يملأ المستخدم نموذجًا على موقعك، من المهم أن يملأ كل المعلومات اللازمة بالتنسيق الصحيح. تحتوي عناصر التحكم في نماذج HTML، مثل المدخلات، على الكثير من التحقق المدمج الذي يمكنك استخدامه لفحص البيانات غير الصالحة. هذا يساعد على ضمان تصحيح المستخدم لهذه الأخطاء قبل إرسال المعلومات ومعالجتها من قبل الخادم. +## التحقق على جانب العميل وجانب الخادم + مصطلح "جانب العميل" يشير إلى كل ما يحدث على جهاز أو كمبيوتر المستخدم، مثل الجزء من الموقع أو التطبيق الذي تتفاعل معه مباشرة. يشمل ذلك التخطيط، التصميم، وأي ميزات تفاعلية. مصطلح "جانب الخادم" يشير إلى كل ما يحدث على الخادم، الكمبيوتر، أو النظام الذي يستضيف الموقع أو التطبيق. يشمل ذلك معالجة البيانات، تشغيل التطبيقات، والتعامل مع الطلبات القادمة من جهاز المستخدم. بينما التحقق على جانب العميل مهم، تحتاج أيضًا إلى التحقق على جانب الخادم لأمان إضافي. يمكن للمستخدمين الخبيثين تجاوز فحوصات جانب العميل، لذا فإن وجود إجراءات قوية على جانب الخادم ضروري. ستتعلم المزيد عن ذلك في وحدة لاحقة. الآن، دعنا نلقي نظرة على بعض أمثلة التحقق من صحة النموذج على جانب العميل. +## الخاصية `required` + أحد الأمثلة الشائعة على التحقق المدمج في النماذج هو استخدام الخاصية `required` في المدخلات. تحدد الخاصية `required` أن المستخدم يحتاج إلى ملء هذا الجزء من النموذج قبل إرساله. إليك مثالًا على استخدام الخاصية `required` في مدخل البريد الإلكتروني. انقر على زر `Submit Form` دون إدخال عنوان بريد إلكتروني وسترى رسالة منبثقة تطلب منك ملء الحقل. @@ -33,6 +37,8 @@ dashedName: what-is-client-side-form-validation-in-html-forms كل متصفح له مجموعة أنماط خاصة به لعرض رسالة التنبيه هذه. +## التحقق المدمج للبريد الإلكتروني + ميزة أخرى لاستخدام مدخل البريد الإلكتروني هي أن مدخلات البريد الإلكتروني تحتوي على تحقق أساسي لضمان تنسيق عناوين البريد الإلكتروني بشكل صحيح. على سبيل المثال، إذا كتبت كلمات عشوائية ونقرت على الإرسال، سيعرض المتصفح تنبيهًا يفيد بفقدان علامة `@`. اكتب `abc` في حقل البريد الإلكتروني وانقر على زر الإرسال. يجب أن ترى رسالة منبثقة لأنها ليست عنوان بريد إلكتروني صالحًا. @@ -51,6 +57,8 @@ dashedName: what-is-client-side-form-validation-in-html-forms من المهم ملاحظة أن المتصفحات تتحقق فقط من صحة أساسية لعناوين البريد الإلكتروني القياسية. يعود إليك إضافة طبقات إضافية من التحقق، والتي ستتعلمها في وحدات لاحقة. +## الخاصيتان `minlength` و `maxlength` + أشكال أخرى من التحقق لمدخلات البريد الإلكتروني هي استخدام الخاصيتين `minlength` و `maxlength`. إليك مثالًا يستخدم التحقق الإضافي. اكتب `b@m` في الحقل وانقر على زر الإرسال. سترى رسالة منبثقة لأنها لا تفي بالحد الأدنى للطول المطلوب. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-generics-and-type-narrowing/67d301a5f536d1a9e5df1a8c.md b/curriculum/challenges/arabic/blocks/lecture-working-with-generics-and-type-narrowing/67d301a5f536d1a9e5df1a8c.md index e7fc3b89548..df85ae95dba 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-generics-and-type-narrowing/67d301a5f536d1a9e5df1a8c.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-generics-and-type-narrowing/67d301a5f536d1a9e5df1a8c.md @@ -9,6 +9,8 @@ dashedName: what-is-type-narrowing-and-how-does-it-work ستواجه أحيانًا قيمة بنوع عام وتحتاج إلى تضييقها إلى نوع أكثر تحديدًا. على سبيل المثال، قد تحتاج إلى التأكد من أن كائنًا يطابق واجهة قمت بتعريفها. أو أن سلسلة نصية موجودة ضمن قائمة محددة من القيم. هناك عدة طرق لتحقيق ذلك. +## التضييق باستخدام القيمة الحقيقية + الأولى هي التضييق بناءً على القيمة الصحيحة. انظر إلى مثالنا من الدرس السابق: ```js @@ -39,6 +41,8 @@ console.log(email.value); بهذه الطريقة، نرجع خطأ إذا كانت `email` قيمة خاطئة. `null` هي قيمة خاطئة. رمي الخطأ ينهي التنفيذ المنطقي لهذا الكود، مما يعني أنه عند الوصول إلى استدعاء `console.log()` يعرف TypeScript أن `email` لا يمكن أن تكون `null`. +## التسلسل الاختياري + التسلسل الاختياري هو أيضًا شكل من أشكال تضييق النوع، على نفس المبدأ بأن الوصول إلى الخاصية لا يمكن أن يحدث إذا كانت قيمة `email` هي `null`. ```js @@ -46,6 +50,8 @@ const email = document.querySelector("#email"); console.log(email?.value); ``` +## التضييق باستخدام `typeof` + لكن ماذا عن الأنواع الأخرى؟ يمكنك أيضًا تضييق الأنواع باستخدام عامل `typeof`. لننظر إلى مثال لمتغير قد يكون سلسلة نصية أو رقمًا: ```js @@ -64,6 +70,8 @@ if (typeof myVal === "number") { بما أننا استخدمنا كلمة `typeof`، يعرف TypeScript الآن أن `myVal` يجب أن يكون رقمًا، ويمكننا إجراء العمليات الحسابية بأمان. +## التضييق باستخدام `instanceof` + لكن ماذا عن أنواع الكائنات الأكثر تعقيدًا؟ إذا كان الكائن من صنف، يمكنك استخدام كلمة `instanceof` لتضييق النوع. نعود إلى مثالنا مع `querySelector()`: ```js @@ -82,6 +90,8 @@ if (email instanceof HTMLInputElement) { قد يبدو هذا الأسلوب مشابهًا للأسلوب السابق، لكن `instanceof` هو تحقق وقت التشغيل - مما يعني، إذا أخطأنا في نوع TypeScript، فإن كود JavaScript الخاص بنا سيؤكد أن `email` هو عنصر `input`. +## تحويل النوع وحراس النوع + بعد ذلك، لننظر إلى مثال حيث نسترجع كائن `User` من API ونحاول طباعة المعلومات: ```js @@ -100,6 +110,8 @@ printAge(myUser); سنحصل على خطأ من المُجمّع عند محاولة تمرير `myUser` إلى الدالة، لأنه رغم معرفتنا أن API يعيد الكائن الصحيح، فإن TypeScript لا يعرف ذلك. وطريقة `.json()` لا تقبل نوعًا عامًا. +### تحويل النوع + الطريقة "السريعة" لحل هذه المشكلة هي تحويل النوع: ```js @@ -116,6 +128,8 @@ const myUser = await request.json() as User; printAge(myUser); ``` +### كتابة حارس نوع + لكن كلما حولت النوع، فأنت تضعف قدرة TypeScript على اكتشاف الأخطاء المحتملة. لذلك بدلًا من تحويل النوع، يمكنك كتابة حارس نوع: ```js diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-higher-order-functions-and-callbacks/673362e43d57b51f1ad2d466.md b/curriculum/challenges/arabic/blocks/lecture-working-with-higher-order-functions-and-callbacks/673362e43d57b51f1ad2d466.md index 320057b8de3..333fceafb6a 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-higher-order-functions-and-callbacks/673362e43d57b51f1ad2d466.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-higher-order-functions-and-callbacks/673362e43d57b51f1ad2d466.md @@ -1,6 +1,6 @@ --- id: 673362e43d57b51f1ad2d466 -title: كيف تعمل طريقتا every() و some()؟ +title: كيف تعمل طريقتا every()‎ و some()‎؟ challengeType: 19 dashedName: how-do-the-every-and-some-methods-work --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-html-tools/672a511bb408ec81c592eb68.md b/curriculum/challenges/arabic/blocks/lecture-working-with-html-tools/672a511bb408ec81c592eb68.md index 3a8fd54c6b2..a427ea8f4ef 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-html-tools/672a511bb408ec81c592eb68.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-html-tools/672a511bb408ec81c592eb68.md @@ -39,10 +39,14 @@ DOM تعني نموذج كائن المستند. هو هيكل شجري يمثل عند فتح أدوات المطوِّر في Google Chrome، سترى عدة تبويبات. التبويب الأول يسمى `Elements`. يعرض هذا التبويب هيكل HTML للصفحة التي تتصفحها. +Chrome developer tools with the Elements tab open, showing the page's HTML structure and an anchor element whose href is https://www.freecodecamp.org/larn/. + التبويب الثاني يسمى `Console`. يعرض هذا التبويب أي أخطاء قد تحدث في الصفحة. في حالة وجود رابط مكسور، يمكنك التحقق من وحدة التحكم لرؤية رسائل الخطأ الخاصة بالرابط المكسور. الرسالة الشائعة التي تظهر هي خطأ 404، الذي يشير إلى أن الصفحة غير موجودة. +Chrome developer tools with the Console tab open, showing a 404 Not Found error for https://www.freecodecamp.org/larn, along with other related 404 errors. + هذا يخبرنا أن المشكلة في عنوان URL داخل عنصر وسم الرابط. عند فحص قيمة `href` سترى وجود خطأ مطبعي. الرسالة في وحدة التحكم تظهر الآن `/larn` مع خطأ 404، لكن العنوان الصحيح يجب أن يكون `/learn`. عند تصحيح الرابط، سيعمل كما هو متوقع. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-json/6732b79c6aa77826855a3f11.md b/curriculum/challenges/arabic/blocks/lecture-working-with-json/6732b79c6aa77826855a3f11.md index fb0c7467f73..f47dd30ae6b 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-json/6732b79c6aa77826855a3f11.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-json/6732b79c6aa77826855a3f11.md @@ -1,6 +1,6 @@ --- id: 6732b79c6aa77826855a3f11 -title: كيف تعمل دالتا JSON.parse() و JSON.stringify()؟ +title: كيف تعمل دالتا JSON.parse()‎ و JSON.stringify()‎؟ challengeType: 19 dashedName: how-do-json-parse-and-json-stringify-work --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e38cdf93ee5a00c79676.md b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e38cdf93ee5a00c79676.md index ad2c1606fa2..0b7221ab6ed 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e38cdf93ee5a00c79676.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e38cdf93ee5a00c79676.md @@ -9,6 +9,8 @@ dashedName: what-are-some-common-methods-used-for-lists في الدرس السابق، تعرّفت على نوع بيانات القائمة وتعلمت كيفية الوصول إلى عناصر القائمة وكذلك تقطيع القائمة. في هذا الدرس، ستستمر في التعرف على القوائم وبعض الطرق الشائعة المرتبطة بها مثل `append()` و`pop()` و`sort()`. +## إضافة عناصر باستخدام `append()` + أول طريقة سننظر إليها هي الطريقة `append()`. تُستخدم هذه الطريقة لإضافة عنصر إلى نهاية القائمة. إليك مثالًا على استخدام الطريقة `append()` لإضافة الرقم `6` إلى قائمة الأرقام: ```py @@ -29,6 +31,8 @@ print(numbers) # [1, 2, 3, 4, 5, [6, 8, 10]] لاحظ كيف أن قائمة `even_numbers` بأكملها مسكنة داخل قائمة `numbers`. +## إضافة عناصر متعددة باستخدام `extend()` + لكن إذا أردت إضافة كل الأرقام الفردية من قائمة `even_numbers` إلى نهاية قائمة `numbers`، فيمكنك استخدام الطريقة `extend()`. الطريقة `extend()` مشابهة للطريقة `append()`، لكن مع `extend()` يمكنك إضافة عدة عناصر من قائمة إلى أخرى. إليك مثالًا على إضافة الأرقام `6` و`8` و`10` من قائمة إلى نهاية قائمة `numbers`: @@ -43,6 +47,8 @@ print(numbers) # [1, 2, 3, 4, 5, 6, 8, 10] كما ترى، القائمة المسكنة اختفت وأصبحت مجرد قائمة أرقام. +## إدخال عناصر عند فهرس محدد + لإدخال عنصر في فهرس محدد داخل القائمة، يمكنك استخدام الطريقة `insert()`. تقبل هذه الطريقة معلمتين: الفهرس الذي تريد إدخال العنصر الجديد فيه والعنصر الذي تريد إدخاله. إليك مثالًا على استخدام الطريقة `insert()`: @@ -56,6 +62,8 @@ print(numbers) # [1, 2, 2.5, 3, 4, 5] الكود التالي سيدخل الرقم `2.5` في الفهرس `2` داخل قائمة `numbers`. +## إزالة عناصر من قائمة + إذا أردت إزالة عنصر من قائمة، يمكنك استخدام الطريقة `remove()`. تأخذ الطريقة `remove()` قيمة العنصر الذي تريد إزالته كمعلمة: ```py @@ -88,6 +96,8 @@ numbers = [1, 2, 3, 4, 5] numbers.pop() # The number 5 is returned ``` +## مسح قائمة + إذا كنت بحاجة إلى تفريغ القائمة، يمكنك استخدام الطريقة `clear()` بهذه الطريقة: ```py @@ -97,6 +107,8 @@ numbers.clear() print(numbers) # [] ``` +## ترتيب قائمة + الطريقة التالية التي سننظر إليها هي الطريقة `sort()`. تُستخدم هذه الطريقة لترتيب العناصر في مكانها. إليك مثالًا على ترتيب قائمة أرقام عشوائية في مكانها: ```py @@ -120,6 +132,8 @@ print(sorted_numbers) # [1, 2, 19, 35, 41, 67] كل من الطريقة `sort()` والدالة `sorted()` تقبلان معلمتين اختياريتين هما `key` و`reverse`. ستتعلم المزيد عن هذه المعلمات الاختيارية في درس مستقبلي عندما تتعلم عن الصفوف المرتبة. ستتعلم أيضًا المزيد عن الدوال المدمجة الأخرى مثل `sorted()` في دروس قادمة. +## عكس قائمة + الطريقة التالية التي سننظر إليها هي الطريقة `reverse()`. هذه الطريقة تعكس قائمة العناصر في مكانها بهذه الطريقة: ```py @@ -129,6 +143,8 @@ numbers.reverse() print(numbers) # [1, 2, 3, 4, 5, 6] ``` +## إيجاد فهرس عنصر + آخر طريقة سننظر إليها هي الطريقة `index`. تُستخدم هذه الطريقة لإيجاد أول فهرس يمكن العثور فيه على عنصر داخل القائمة. إليك مثالًا على استخدام الطريقة `index` لإيجاد اللغة `'Java'` في قائمة `programming_languages`: ```py diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e3a99ba37f09b9d0059b.md b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e3a99ba37f09b9d0059b.md index c1f4be23fe0..8b575872596 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e3a99ba37f09b9d0059b.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e3a99ba37f09b9d0059b.md @@ -7,6 +7,8 @@ dashedName: what-are-tuples-and-how-do-they-work # --description-- +## ما هو الصف المرتب؟ + الصف المرتب هو نوع بيانات في Python يُستخدم لإنشاء متتالية مرتبة من القيم. يمكن أن تحتوي الصفوف المرتبة على مجموعة مختلطة من أنواع البيانات مثل هذا: ```py @@ -28,6 +30,8 @@ TypeError: 'tuple' object does not support item assignment """ ``` +## الوصول إلى عناصر الصف المرتب + للوصول إلى عنصر من صف مرتب، يمكنك استخدام ترميز الأقواس ورقم الفهرس: ```py @@ -55,6 +59,8 @@ IndexError: list index out of range """ ``` +## استخدام دالة البناء `tuple()` + طريقة أخرى لإنشاء صف مرتب هي باستخدام دالة البناء `tuple()` مثل هذا: ```py @@ -64,6 +70,8 @@ tuple(developer) # ('J', 'e', 's', 's', 'i', 'c', 'a') يمكنك تمرير متكررات مختلفة مثل السلاسل النصية والقوائم وحتى صفوف مرتبة أخرى إلى دالة البناء `tuple()`. +## التحقق مما إذا كان عنصر موجودًا في الصف المرتب + للتحقق مما إذا كان عنصر موجودًا في صف مرتب، يمكنك استخدام الكلمة المفتاحية `in` مثل هذا: ```py @@ -73,6 +81,8 @@ programming_languages = ('Python', 'Java', 'C++', 'Rust') 'JavaScript' in programming_languages # False ``` +## فك القيم من الصف المرتب + يمكنك أيضًا فك تجميع العناصر من صف مرتب تمامًا كما فعلت مع القوائم: ```py @@ -98,6 +108,8 @@ print(rest) # [34, 'Rust Developer'] هنا، القيمة في `name` هي `'Alice'`، و`rest` هي قائمة تتألف من الرقم `34` والسلسلة النصية `'Rust Developer'`. +## تقطيع الصفوف المرتبة + تمامًا كما في القائمة، يمكنك استخدام عامل القطع على صف مرتب لاستخراج جزء منه. إليك مثالًا لاستخراج العناصر `'pie'` و`'cookies'` إلى صف مرتب منفصل: ```py @@ -107,6 +119,8 @@ desserts[1:3] # ('pie', 'cookies') تذكر أن الرقم الأول يمثل فهرس البداية للاستخراج بينما الرقم الثاني يمثل فهرس النهاية. لكن لاحظ أن العنصر عند فهرس النهاية غير مشمول في الصف المرتب المستخرج. +## إزالة عناصر من الصف المرتب + إذا كنت بحاجة إلى حذف عنصر من صف مرتب، فهذا غير ممكن لأن الصفوف المرتبة غير قابلة للتغيير. لذا هذا المثال سينتج عنه خطأ: ```py @@ -120,6 +134,8 @@ TypeError: "tuple" object doesn't support item deletion """ ``` +## الاختيار بين الصفوف المرتبة والقوائم + متى قد تستخدم صف مرتب بدلًا من قائمة؟ إذا كنت بحاجة إلى مجموعة ديناميكية من العناصر حيث يمكنك الإضافة والحذف والتحديث، فعليك استخدام قائمة. إذا كنت تعلم أنك تتعامل مع مجموعة ثابتة وغير قابلة للتغيير من البيانات، فعليك استخدام صف مرتب. @@ -171,7 +187,7 @@ print(developer[1]) # ? ## --text-- -ما النتيجة لهذا الكود التالي؟ +ما النتيجة للكود التالي؟ ```py desserts = ('cake', 'pie', 'cookies', 'ice cream') @@ -212,7 +228,7 @@ desserts[1:3] ## --text-- -ما النتيجة لهذا الكود التالي؟ +ما النتيجة للكود التالي؟ ```py developer = ("Jane Doe", 23, "Python Developer") diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e4b003571c149bcda122.md b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e4b003571c149bcda122.md index 7fc2f1f45b6..b71a05c7615 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e4b003571c149bcda122.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e4b003571c149bcda122.md @@ -7,6 +7,8 @@ dashedName: what-are-the-enumerate-and-zip-functions-and-how-do-they-work # --description-- +## تتبع فهرس حلقة `for` + في الدروس السابقة تعلمت كيفية العمل مع حلقة `for`، التي تُستخدم لتكرار كتلة من الكود عددًا محددًا من المرات. إليك مثالًا على استخدام حلقة `for` لطباعة كل لغة من قائمة `languages` في وحدة التحكم: ```py @@ -28,6 +30,8 @@ for language in languages: index += 1 ``` +## استخدام الدالة `enumerate()` + بينما هذه الطريقة تعمل، هناك طريقة أسهل باستخدام دالة `enumerate()`. دالة `enumerate()` تتعقب الفهرس لقابل للتكرار وتُرجع كائن enumerate. إذا مررنا قائمة `languages` إلى دالة `enumerate()` وحولنا القيمة المرجعة إلى قائمة باستخدام دالة `list()`، فستبدو هكذا: @@ -79,6 +83,8 @@ Index 3 and language Russian Index 4 and language Chinese ``` +## استخدام الدالة `zip()` + حتى الآن كنا نكرر فقط على قائمة واحدة. لكن ماذا لو احتجت إلى التكرار على عدة قابلات للتكرار بالتوازي؟ يمكنك استخدام دالة `zip()` لذلك، التي تجمع القوائم في أزواج من العناصر وتُرجع مكررًا من صفوف مرتبة. إذا مررنا قائمة من `developers` و `ids` إلى دالة `zip()` وحولنا القيمة المرجعة إلى قائمة باستخدام دالة `list()`، فستبدو هكذا: diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e4d62ae09d1661e4cf9b.md b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e4d62ae09d1661e4cf9b.md index de587759dd0..518d3fba098 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e4d62ae09d1661e4cf9b.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/6839e4d62ae09d1661e4cf9b.md @@ -21,6 +21,8 @@ print(even_numbers) ينشئ هذا المثال قائمة جديدة فارغة تُسمى `even_numbers` ويدور عبر متتالية أرقام بين `0` و `20`. داخل الحلقة، هناك شرط يتحقق مما إذا كان العدد الحالي له باقي `0` عند قسمته على `2`. يُستخدم هذا لتحديد ما إذا كان العدد زوجيًا. إذا كان الشرط `True`، تُضاف القيمة الحالية `num` إلى نهاية قائمة `even_numbers`. أخيرًا، نطبع قائمة `even_numbers` في وحدة التحكم. +## ما هو التعميم القائم على القوائم؟ + بينما يعمل هذا الكود، هناك طريقة أكثر اختصارًا لكتابته باستخدام التوليد القائم على القوائم. يسمح لك التوليد القائم على القوائم بإنشاء قائمة جديدة في سطر واحد عبر دمج حلقة وشرط مباشرة داخل الأقواس المربعة. هذا يجعل الكود أقصر وغالبًا أسهل في القراءة. إليك المثال المعاد صياغته من قبل باستخدام الأقواس المربعة: @@ -32,6 +34,8 @@ print(even_numbers) في هذا المثال المعاد صياغته، تُنشأ قائمة `even_numbers` باستخدام سطر واحد من الكود. يقوم التوليد القائم على القوائم بالتكرار عبر الأرقام من `0` إلى `20`، ويشمل فقط الأرقام القابلة للقسمة على `2`. هذا الأسلوب أكثر اختصارًا ويُلغي الحاجة إلى حلقة وكتلة شرطية منفصلة. +## استخدام التعبيرات الشرطية في التعميم القائم على القوائم + لنلقِ نظرة على مثال آخر لنفهم بشكل أفضل كيف تعمل تراكيب القوائم: ```py @@ -48,6 +52,8 @@ print(result) [(1, 'Odd'), (2, 'Even'), (3, 'Odd'), (4, 'Even'), (5, 'Odd')] ``` +## تصفية القوائم باستخدام `filter()` + طريقة أخرى لإنشاء قائمة بدءًا من قابل للتكرار موجود هي الدالة `filter()`. إليك مثالًا لإنشاء قائمة جديدة تحتوي فقط على الكلمات التي يزيد طولها عن أربعة أحرف: ```py @@ -62,6 +68,8 @@ print(long_words) # ['mountain', 'river', 'cloud'] تُستخدم الدالة `filter()` لاختيار عناصر من قابل للتكرار تحقق شرطًا معينًا. تقبل الدالة `filter()` دالة وقابل للتكرار كمعاملات. في هذا المثال، نمرر دالة `is_long_word` إلى `filter()` للتحقق مما إذا كان عدد أحرف الكلمة الحالية أكبر من `4`. تُضاف كل الكلمات التي يزيد عدد أحرفها عن `4` إلى قائمة جديدة وتُعيَّن إلى المتغير `long_words`. +## تحويل القوائم باستخدام `map()` + بعيدًا عن الدالة `filter()`، هناك بعض الدوال الأخرى المفيدة عند العمل مع القوائم. دالة أخرى يجب معرفتها هي `map()`، التي تأخذ قابل للتكرار وتطبق دالة على كل عنصر منه. إليك مثالًا لاستخدام دالة `map()` لتحويل قائمة درجات الحرارة من سلسيوس إلى فهرنهايت: ```py @@ -76,6 +84,8 @@ print(fahrenheit) # [32.0, 50.0, 68.0, 86.0, 104.0] تمامًا مثل الدالة `filter()`، تقبل `map()` دالة وقابل للتكرار كمعاملات. تأخذ الدالة `to_fahrenheit` درجة حرارة وتحولها من سلسيوس إلى فهرنهايت. +## جمع القيم باستخدام `sum()` + الدالة الأخيرة التي سننظر إليها هي `sum()`. تُستخدم هذه الدالة للحصول على مجموع عناصر قابل للتكرار مثل قائمة أو صف مرتب. إليك مثالًا لاستخدام دالة `sum()`: ```py diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/683d6a3fe8c1060ffb1f9b78.md b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/683d6a3fe8c1060ffb1f9b78.md index 968cff434ed..1f8433a62ec 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/683d6a3fe8c1060ffb1f9b78.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-loops-and-sequences/683d6a3fe8c1060ffb1f9b78.md @@ -9,6 +9,8 @@ dashedName: what-are-some-common-methods-for-tuples في الدرس السابق، تعلمت كيفية العمل مع نوع البيانات الصف المرتب. في هذا الدرس، ستتعلم بعض الطرق الشائعة التي ستستخدمها عند العمل مع الصفوف المرتبة. +## طريقة `count()` + الطريقة الأولى التي سنغطيها هي `count()`. تُستخدم هذه الطريقة لتحديد عدد المرات التي يظهر فيها عنصر في صف مرتب. إليك مثالًا على التحقق من عدد المرات التي تظهر فيها السلسلة النصية `Rust` في صف مرتب اسمه `programming_languages`: ```py @@ -36,6 +38,8 @@ TypeError: tuple.count() takes exactly one argument (0 given) """ ``` +## طريقة `index()` + الطريقة التالية التي سننظر إليها هي طريقة `index()`. تُستخدم هذه الطريقة لإيجاد الفهرس الذي يوجد فيه عنصر معين في صف مرتب. إليك مثالًا على استخدام طريقة `index()` لإيجاد الفهرس للسلسلة النصية `Java`: ```py @@ -74,6 +78,8 @@ programming_languages.index('Python', 2, 5) # 2 النتيجة الآن هي الفهرس `2` لأننا نبدأ البحث من الفهرس `2`، ونبحث حتى الفهرس `5` لكن دون تضمينه. +## دالة `sorted()` + دالة أخرى تُستخدم كثيرًا مع الصفوف المرتبة هي دالة `sorted()`. في درس سابق تعلمت عن طريقة `sort()` للقوائم. حسنًا، يمكن استخدام دالة `sorted()` على أي قابل للتكرار بما في ذلك الصفوف المرتبة. إليك مثالًا على إنشاء قائمة جديدة من الأرقام باستخدام دالة `sorted()`: @@ -106,6 +112,8 @@ print(sorted(programming_languages, reverse=True)) # ['Rust', 'Rust', 'Python', 'Python', 'Java', 'C++'] ``` +## الخلاصة + الصفوف المرتبة نوع بيانات شائع في Python. فهم كيفية التعامل معها، إلى جانب بعض الطرق والدوال المفيدة، سيساعدك على كتابة كود أكثر كفاءة. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-loops/6732c05595ca7d422b9e55ff.md b/curriculum/challenges/arabic/blocks/lecture-working-with-loops/6732c05595ca7d422b9e55ff.md index fc8aa2a1adb..e2964c713b1 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-loops/6732c05595ca7d422b9e55ff.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-loops/6732c05595ca7d422b9e55ff.md @@ -7,10 +7,14 @@ dashedName: what-is-the-for-in-loop-and-when-should-you-use-it # --interactive-- +## ما هو حلقة `for...in`؟ + تُستخدم حلقة `for...in` بشكل أفضل عندما تحتاج إلى التكرار على خصائص كائن. ستكرر هذه الحلقة جميع الخصائص القابلة للعدّ في الكائن، بما في ذلك الخصائص الموروثة والخصائص غير الرقمية. الخاصية الموروثة هي خاصية تُورث من سلسلة النموذج الأولي للكائن. الخاصية غير الرقمية هي خاصية ليست رقمًا أو سلسلة نصية يمكن تحويلها إلى رقم. +## صيغة حلقة `for...in` + إليك الصيغة النحوية الأساسية لحلقة `for...in`: ```js @@ -21,6 +25,8 @@ for (variable in object) { المتغير في المثال يمثل الخاصية الحالية للكائن التي يتم التكرار عليها. +## التكرار على خصائص كائن + لنلقِ نظرة على بعض الأمثلة لتفهم كيف تعمل حلقة `for...in` بشكل أفضل. في هذا المثال الأول لدينا كائن `fruit` ونريد التكرار على كل خاصية وتسجيل القيمة في وحدة التحكم. @@ -47,6 +53,8 @@ for (const prop in fruit) { النتائج التي ستُسجل في وحدة التحكم ستكون `apple`، و`red`، و`0.99`. +## التكرار على كائن مسكن + في هذا المثال الثاني، لدينا كائن مسكن ونريد التكرار على كل خاصية وتسجيل القيمة في وحدة التحكم. :::interactive_editor @@ -79,6 +87,8 @@ John { street: '123 Main St', city: 'Anytown', state: 'CA' } ``` +## تسكين حلقات `for...in` + إذا أردت التكرار على خصائص كائن `address`، يمكنك تسكين حلقة `for...in` أخرى داخل الأولى. :::interactive_editor @@ -133,6 +143,8 @@ for (const prop in person) { "CA" ``` +## متى تستخدم حلقة `for...in` + تُعتبر حلقة `for...in` مفيدة عندما تحتاج إلى التكرار على خصائص كائن. لا يُنصح باستخدام حلقة `for...in` للتكرار على عناصر مصفوفة. بدلاً من ذلك، استخدم حلقة `for...of` أو طرق المصفوفة الأخرى مثل `forEach`، و`map`، و`filter`، و`reduce`، التي ستتعلمها في دروس لاحقة. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-nano/688170ebc58d8d3b1ae493a2.md b/curriculum/challenges/arabic/blocks/lecture-working-with-nano/688170ebc58d8d3b1ae493a2.md index f2eba87a565..bc1b8a9f310 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-nano/688170ebc58d8d3b1ae493a2.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-nano/688170ebc58d8d3b1ae493a2.md @@ -7,16 +7,22 @@ dashedName: what-is-nano # --description-- +## تحرير الملفات في الطرفية + عند العمل في الطرفية، لا تتوفر دائمًا محررات النصوص القياسية، لكن هناك برامج مصممة لتحرير الملفات مباشرة من داخل الطرفية. تتضمن بيئات العمل في لينكس عادة محرر نصوص. Vi أو Vim هما الأكثر شيوعًا. قد تحتاج إلى تثبيت Emacs وNano يدويًا، لكنهما متوفران بسهولة في معظم التوزيعات. التحدي مع Vim هو أن له منحنى تعلم حاد. إذا لم تكن معتادًا عليه، قد لا تعرف حتى كيف تغلق التطبيق! Emacs أسهل قليلاً في الاستخدام، لكنه يحتوي على مجموعة كبيرة من اختصارات لوحة المفاتيح. +## ما هو Nano؟ + Nano أبسط بكثير وأسهل في الاستخدام، خاصة للمبتدئين. يمكنك البدء بسرعة وتحرير ملف باستخدام Nano، ويقدم التطبيق مساعدة على الشاشة للاختصارات الأساسية. المقابل لذلك هو نقص قابلية التوسعة. على عكس Vim أو Emacs، التي يمكن توسيعها بإضافات لتصبح بيئات تطوير كاملة، Nano بسيط جدًا. +## استكشاف واجهة Nano + لنلق نظرة على ما يمكن أن يفعله Nano. لفتح ملف، يمكنك إدخال `nano ` في الطرفية. بمجرد فتح الملف، سترى إصدار Nano الذي تستخدمه واسم الملف المفتوح في أعلى الشاشة. @@ -32,6 +38,8 @@ Nano أبسط بكثير وأسهل في الاستخدام، خاصة للمب تشير الاختصارات التي تبدأ برمز المؤشر (`^`) إلى ضرورة الضغط على مفتاح Ctrl مع الحرف المحدد. أما الاختصارات التي تبدأ بـ `M-` فتتطلب الضغط على "مفتاح الميتا"، والذي في معظم الإعدادات يكون مفتاح Alt، مع الحرف المحدد. +## حفظ ملف + لتعديل ملف في Nano، تحتاج فقط إلى معرفة بعض أوامر الاختصارات. بعد إجراء تغييرات على الملف، اضغط Ctrl + O لـ "الكتابة"، أي حفظ الملف. بعد إدخال الأمر، سترى القائمة في الأسفل تتغير إلى هذا الشكل: ```bash @@ -42,6 +50,8 @@ File Name to write : اضغط Enter لحفظ الملف والعودة إلى تحريره، أو Ctrl + C لإلغاء العملية والعودة إلى التحرير. +## الخروج من Nano + أثناء التواجد في المحرر، يمكنك الضغط على Ctrl + X للخروج من Nano والعودة إلى الطرفية. إذا كان لديك تغييرات غير محفوظة عند محاولة الخروج، سترى هذا في القائمة السفلية: ```bash diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-node-core-modules/695cc6a5eefd305381ec90bc.md b/curriculum/challenges/arabic/blocks/lecture-working-with-node-core-modules/695cc6a5eefd305381ec90bc.md index 62880dc515f..cc1fcdf4ef4 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-node-core-modules/695cc6a5eefd305381ec90bc.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-node-core-modules/695cc6a5eefd305381ec90bc.md @@ -100,7 +100,7 @@ try { ## استخدام طريقة `writeFile()` -تتيح لك الطريقة `writeFile()` الكتابة إلى ملف. إذا لم يكن الملف موجودًا، تنشئه في المسار المحدد. إذا قدمت مسارًا نسبيًا، يُنشأ الملف بالنسبة إلى دليل العمل الحالي. +تسمح لك الطريقة `writeFile()` بالكتابة إلى ملف، مع استبدال أي محتوى موجود. إذا لم يكن الملف موجودًا، تُنشئه في المسار المحدد. إذا قدمت مسارًا نسبيًا، يُنشأ الملف بالنسبة إلى دليل العمل الحالي. إليك كيفية استخدام الطريقة `writeFile()`: @@ -265,7 +265,7 @@ Error deleting file: Error: ENOENT: no such file or directory, unlink 'article.m ## --text-- -أي طريقة في وحدة Node fs تتيح لك كتابة محتوى إلى ملف، وإنشاؤه إذا لم يكن موجودًا؟ +أي طريقة في وحدة Node `fs` تتيح لك كتابة محتوى إلى ملف، مع استبدال أي محتوى موجود وإنشاء الملف إذا لم يكن موجودًا؟ ## --answers-- @@ -277,7 +277,7 @@ Error deleting file: Error: ENOENT: no such file or directory, unlink 'article.m ### --feedback-- -فكر في الطريقة التي تنشئ وتكتب المحتوى إلى ملف. +فكر في الطريقة التي تستبدل أي محتوى موجود عند الكتابة إلى ملف. --- @@ -285,7 +285,7 @@ Error deleting file: Error: ENOENT: no such file or directory, unlink 'article.m ### --feedback-- -فكر في الطريقة التي تنشئ وتكتب المحتوى إلى ملف. +فكر في الطريقة التي تستبدل أي محتوى موجود عند الكتابة إلى ملف. --- @@ -293,7 +293,7 @@ Error deleting file: Error: ENOENT: no such file or directory, unlink 'article.m ### --feedback-- -فكر في الطريقة التي تنشئ وتكتب المحتوى إلى ملف. +فكر في الطريقة التي تستبدل أي محتوى موجود عند الكتابة إلى ملف. ## --video-solution-- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-node-core-modules/695cc8f280fef0cc3bed02ca.md b/curriculum/challenges/arabic/blocks/lecture-working-with-node-core-modules/695cc8f280fef0cc3bed02ca.md index abf75334940..bc11dd03df9 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-node-core-modules/695cc8f280fef0cc3bed02ca.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-node-core-modules/695cc8f280fef0cc3bed02ca.md @@ -79,7 +79,7 @@ const wrongPath = path.join("/src//", "assets", "text-files"); console.log(wrongPath); // /src/assets/text-files ``` -تحول طريقة `resolve()` متتالية من مقاطع المسار إلى مسار مطلق. تبدأ من مجلد العمل الحالي وتنتج مسارًا كاملاً يشير إلى الموقع الدقيق على الجهاز: +تُحوّل الطريقة `resolve()` متتالية من مقاطع المسار إلى مسار مطلق. تعالج المقاطع من اليمين إلى اليسار حتى تُكوّن مسارًا مطلقًا. إذا وصلت إلى البداية دون تكوين مسار مطلق، تستخدم دليل العمل الحالي: ```js const absolutePath = path.resolve("assets", "src", "text-files"); @@ -87,7 +87,7 @@ console.log(absolutePath); // /Users/user/Desktop/fCC/script-code/node/node-path/assets/src/text-files ``` -الفرق بين `join()` و`resolve()` هو أن `join()` ينشئ مسارًا نسبيًا، بينما `resolve()` يرجع مسارًا مطلقًا. +على عكس `join()` التي تجمع وتطبع مقاطع المسار ويمكن أن تُرجع مسارًا نسبيًا أو مطلقًا، تُرجع `resolve()` دائمًا مسارًا مطلقًا. أخيرًا، هناك طريقتا `parse()` و`format()`. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-numbers-and-common-number-methods/6732808f3221720adc833e81.md b/curriculum/challenges/arabic/blocks/lecture-working-with-numbers-and-common-number-methods/6732808f3221720adc833e81.md index 55d103c324c..787ee539cac 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-numbers-and-common-number-methods/6732808f3221720adc833e81.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-numbers-and-common-number-methods/6732808f3221720adc833e81.md @@ -1,6 +1,6 @@ --- id: 6732808f3221720adc833e81 -title: كيف تعمل طريقتا parseFloat() و parseInt()؟ +title: كيف تعمل طريقتا parseFloat()‎ و parseInt()‎؟ challengeType: 19 dashedName: how-do-the-parsefloat-and-parseint-methods-work --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-numbers-and-common-number-methods/673280a1c29d0a0b17316e56.md b/curriculum/challenges/arabic/blocks/lecture-working-with-numbers-and-common-number-methods/673280a1c29d0a0b17316e56.md index a1c9aac2f7d..c2dd136a283 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-numbers-and-common-number-methods/673280a1c29d0a0b17316e56.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-numbers-and-common-number-methods/673280a1c29d0a0b17316e56.md @@ -1,6 +1,6 @@ --- id: 673280a1c29d0a0b17316e56 -title: ما هي طريقة toFixed() وكيف تعمل؟ +title: ما هي طريقة toFixed()‎ وكيف تعمل؟ challengeType: 19 dashedName: what-is-the-tofixed-method-and-how-does-it-work --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8757080091969f07122.md b/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8757080091969f07122.md index 12490296e37..8cf671a88dd 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8757080091969f07122.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8757080091969f07122.md @@ -7,12 +7,18 @@ dashedName: what-is-sql-and-how-can-you-create-a-database-with-tables # --description-- +## ما هو SQL؟ + SQL تعني لغة الاستعلامات الهيكلية. تم تطويرها في السبعينيات، وكانت تُعرف في البداية باسم لغة الاستعلامات الإنجليزية الهيكلية (SEQUEL). ثم تم اختصار هذا المصطلح لاحقًا إلى SQL. SQL هي لغة برمجة تُستخدم لتخزين وإدارة البيانات في قواعد البيانات العلائقية. +## كيف تعمل قواعد البيانات العلائقية + كما تعلمت في درس سابق، تنظم قواعد البيانات العلائقية البيانات في جداول. يحتوي كل جدول على مجموعة من الصفوف والأعمدة، حيث تُمثّل خصائص البيانات وعلاقاتها. كل صف يمثل سجلًا، وكل عمود يمثل خاصية أو حقلًا محددًا لذلك السجل. +## استخدام SQL في قواعد البيانات العلائقية + باستخدام SQL، يمكنك إضافة البيانات وتغييرها وحذفها والعثور عليها واسترجاعها من قاعدة بيانات علائقية. توفر مجموعة شاملة من الأوامر للاستعلام، والترشيح، والفرز، وتجميع البيانات. تساعد SQL في تحسين أداء قاعدة البيانات من خلال استعلام البيانات الضرورية فقط، ويمكن دمجها بسهولة مع مجموعة واسعة من لغات البرمجة، لتتمكن من التفاعل مع قواعد البيانات مباشرة من تطبيقاتك. @@ -23,6 +29,8 @@ SQL هي لغة برمجة تُستخدم لتخزين وإدارة البيان تعتمد SQL على الأوامر، المعروفة عادةً بتصريحات SQL أو استعلامات SQL. +## تنفيذ أوامر SQL + بصفتك مطوِّرًا، ستكتب هذه التصريحات باستخدام عناصر لغة SQL أو الكلمات المفتاحية المحددة. تسمح لك بأداء العمليات اللازمة على قاعدة بياناتك. قبل أن تدخل أوامر SQL، تحتاج إلى فتح واجهة psql لتتفاعل مباشرة مع قاعدة بيانات PostgreSQL. في موجه الأوامر أو الطرفية، أدخل: @@ -45,6 +53,8 @@ postgres=# دعنا نستعرض بعض أوامر SQL الأساسية التي يجب أن تكون على دراية بها. ستلاحظ أنه، حسب الاصطلاح، تنتهي أوامر SQL بفاصلة منقوطة (`;`). +## إنشاء قاعدة بيانات والاتصال بها + أولًا، يمكنك استخدام هذا الأمر لإنشاء قاعدة بيانات باسم `my_database`: ```sql @@ -71,6 +81,8 @@ CREATE DATABASE my_database; my_database=# ``` +## إنشاء جدول + بمجرد إنشاء قاعدة البيانات والاتصال بها، يمكنك إنشاء جدول باستخدام الكلمات المفتاحية `CREATE TABLE`: ```sql @@ -90,6 +102,8 @@ CREATE TABLE products ( هذه بعض أوامر SQL الأساسية التي يجب أن تعرفها للبدء. +## فوائد SQL + باستخدام SQL، يمكنك بسهولة استعلام البيانات والتلاعب بها وتحليلها لاتخاذ قرارات مستنيرة وحل مشكلات العالم الحقيقي. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea899461e37199cf03cf9.md b/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea899461e37199cf03cf9.md index 216666a389b..86d2b910ba4 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea899461e37199cf03cf9.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea899461e37199cf03cf9.md @@ -7,6 +7,8 @@ dashedName: what-are-the-basic-data-types-in-sql # --description-- +## إنشاء جدول في SQL + لتعريف جدول في SQL، تحتاج إلى تحديد نوع البيانات لكل عمود. تذكر أن هذه هي الصيغة النحوية الأساسية لإنشاء جدول في SQL. لكل عمود نوع بيانات خاص به. @@ -20,6 +22,8 @@ CREATE TABLE table_name( ); ``` +## فئات أنواع البيانات في SQL + بصفتك مطوِّرًا، هدفك هو اختيار هذه الأنواع بدقة قدر الإمكان. هناك ست فئات شائعة لأنواع البيانات في SQL: @@ -33,6 +37,8 @@ CREATE TABLE table_name( في هذا الدرس، سنغطي بعض الأنواع الأكثر استخدامًا مع PostgreSQL. تختلف أنواع البيانات بين أنظمة إدارة قواعد البيانات، لكنها عمومًا متشابهة جدًا. لذا ستحتاج إلى مراجعة القائمة الكاملة في الوثائق. +## القيم الرقمية + سنبدأ بالقيم الرقمية. أولًا، لدينا نوع البيانات `INTEGER`: @@ -65,6 +71,8 @@ id INT AUTO_INCREMENT يمكنك أن ترى أن أنظمة إدارة قواعد البيانات المختلفة قد تستخدم طرقًا مختلفة لتحقيق نفس الوظيفة بالضبط في قاعدة بياناتك. +## أنواع بيانات السلاسل النصية + هذه هي أنواع البيانات الرقمية الأكثر استخدامًا، لكن أحيانًا قد تحتاج إلى تمثيل نص أو متتاليات من الأحرف. لهذا، لديك نوع البيانات `VARCHAR`. يُستخدم هذا النوع لطول سلسلة نصية متغير. يمكنك تحديد الحد الأقصى لطول الأحرف داخل أقواس عادية: @@ -81,6 +89,8 @@ name VARCHAR(50) name TEXT ``` +## التواريخ والأوقات + بالإضافة إلى الأعداد والسلاسل النصية، من الشائع أيضًا تخزين التواريخ والأوقات. على سبيل المثال، إذا أنشأت جدولًا لتخزين الأحداث، قد تحتاج إلى تخزين تاريخ كل حدث بصيغة محددة. لهذا، لديك نوع البيانات `DATE`: @@ -105,6 +115,8 @@ event_timestamp TIMESTAMP event_timestamp TIMESTAMP WITH TIME ZONE ``` +## نوع البيانات `BOOLEAN` + وأخيرًا، إذا كنت تحتاج إلى تخزين قيمة منطقية، `TRUE` أو `FALSE`، يمكنك استخدام نوع البيانات `BOOLEAN`: ```sql diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8e0cab41019dc8a728a.md b/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8e0cab41019dc8a728a.md index 5d2ac52b094..8d455119135 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8e0cab41019dc8a728a.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8e0cab41019dc8a728a.md @@ -9,6 +9,8 @@ dashedName: what-are-the-different-types-of-relationships-in-a-relational-databa كما تعلمت في الدروس السابقة، تخزن قواعد البيانات العلائقية البيانات في جداول تتكون من صفوف وأعمدة. +## الأنواع الرئيسية للعلاقات + الجانب "العلاقي" في "قواعد البيانات العلائقية" يأتي من حقيقة أن السجلات في جداول مختلفة يمكن أن تكون لها أنواع مختلفة من العلاقات. هناك خمسة أنواع رئيسية من العلاقات: @@ -19,18 +21,24 @@ dashedName: what-are-the-different-types-of-relationships-in-a-relational-databa - كثير لكثير - وعلاقات الإشارة إلى الذات (المعروفة أيضًا بالعلاقات العودية). +## علاقات واحد إلى واحد + يكون بين جدولين علاقة **واحد لواحد** عندما يمكن ربط كل سجل في الجدول الأول بسجل واحد على الأكثر في الجدول الثاني، والعكس صحيح. على سبيل المثال، لنفترض أن الشركة تعيّن مركبة واحدة فقط لكل موظف. في هذه الحالة، يمكن أن تحتوي قاعدة البيانات على جدول `employees` وجدول `vehicles`، حيث يتوافق كل سجل موظف مع سجل مركبة واحد فقط في قاعدة البيانات. +## علاقات واحد إلى متعدد ومتعدد إلى واحد + على النقيض من ذلك، تحدث علاقات **واحد لكثير** عندما يمكن ربط سجل واحد في جدول بسجل واحد أو أكثر في جدول آخر. على سبيل المثال، إذا كان لدينا جدول `customers` وجدول `orders`، يمكن أن يرتبط كل عميل بواحد أو أكثر من الطلبات، لكن كل طلب يمكن أن يرتبط بعميل واحد فقط. هذا هو نفس علاقة **كثير لواحد**، لكن من منظور معاكس. يمكن أن يرتبط طلب واحد أو أكثر بعميل واحد. +## علاقات متعدد إلى متعدد + تحدث علاقات **كثير لكثير** عندما يمكن ربط سجل في جدول بسجلات متعددة في جدول آخر والعكس صحيح. على سبيل المثال، دعنا نحلل قاعدة بيانات لمكتبة. لأغراض التبسيط، لنفترض أن هذه القاعدة تحتوي فقط على جدولين: `books` و `authors`. @@ -55,6 +63,8 @@ dashedName: what-are-the-different-types-of-relationships-in-a-relational-databa استخدام جدول التقاطع يسهل استعلام البيانات، يمنع التكرار، ويبسط مخطط قاعدة البيانات. إنها مفيدة جدًا لتنفيذ علاقات كثير لكثير. +## العلاقات ذاتية الإشارة + وأخيرًا، نجد علاقات **الإشارة إلى الذات**، التي تحدث عندما يمكن ربط سجلات جدول بسجلات أخرى في نفس الجدول. تُعرف هذه أيضًا بالعلاقة العودية. فهم هذه العلاقات ضروري لتصميم ونمذجة قواعد بيانات علائقية معقدة وفعالة. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8eba2a8b119f2ad9f8c.md b/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8eba2a8b119f2ad9f8c.md index fb8fc6339e1..d8e1ca4b784 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8eba2a8b119f2ad9f8c.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-relational-databases/687ea8eba2a8b119f2ad9f8c.md @@ -7,8 +7,12 @@ dashedName: what-are-the-different-ways-to-join-tables # --description-- +## لماذا تهم عملية `JOIN` في SQL + على الرغم من أن قواعد البيانات العلائقية تنظم البيانات في جداول منفصلة، تسمح لك عمليات `JOIN` في SQL بدمج المعلومات المرتبطة من الجداول لاستعلام البيانات. +## الأنواع المختلفة لعملية `JOIN` + هناك عدة أنواع من عملية `JOIN`، منها: - `INNER JOIN` @@ -18,6 +22,8 @@ dashedName: what-are-the-different-ways-to-join-tables - `SELF JOIN` - `CROSS JOIN` +## عملية `INNER JOIN` + لنبدأ بـ `INNER JOIN`. يقوم `INNER JOIN` بتصفية النتيجة ليشمل فقط الصفوف التي تكون فيها القيم في أعمدة الربط التي تحددها متساوية في كلا الجدولين. ببساطة، يعطيك تقاطع البيانات. @@ -79,6 +85,8 @@ product_id | product_name | category | price | origin | sale_id | produc ربط الجداول يفعل بالضبط ما يوحي به اسمه. يربط جدولين أو أكثر في جدول واحد، ولهذا نرى كل الأعمدة من كلا الجدولين، بما في ذلك `product_id` مرتين. +## عملية `FULL OUTER JOIN` + يرجع `FULL OUTER JOIN` كل الصفوف من كلا الجدولين. إذا وُجد تطابق في الأعمدة المحددة، يتم دمج البيانات وتحصل على كل الأعمدة لكل سجل متطابق. @@ -113,6 +121,8 @@ product_id | product_name | category | price | origin | sale_id | produc لكن `'T-Shirt'` يحتوي على أعمدة فارغة (`NULL`) لأن لم يُعثر على تطابق في جدول `sales` (هذا المنتج لم يُبع). +## عملية `LEFT OUTER JOIN` + يُستخدم `LEFT OUTER JOIN` للحصول على كل السجلات من الجدول الأيسر والمعلومات المطابقة من الجدول الأيمن لكل صف من الجدول الأيسر. إذا لم يُعثر على تطابق، تُملأ الأعمدة من الجدول الأيمن بقيم `NULL`. @@ -143,6 +153,8 @@ product_id | product_name | category | price | origin | sale_id | produc في هذه الحالة، هي نفسها `FULL OUTER JOIN` لأنها تشمل كل الصفوف من الجدول الأول، `products`. +## عملية `RIGHT OUTER JOIN` + يشبه `RIGHT OUTER JOIN` كثيرًا، لكن الآن نحصل على كل السجلات من الجدول الأيمن والمعلومات المطابقة من الجدول الأيسر لكل صف من الجدول الأيمن. إذا لم يكن هناك تطابق، تُملأ الأعمدة من الجدول الأيسر بقيم `NULL`. @@ -176,10 +188,16 @@ product_id | product_name | category | price | origin | sale_id | produc هذه هي عمليات `JOIN` الأكثر استخدامًا، لكن هناك اثنتان إضافيتان يجب أن تعرفهما. +## عملية `SELF JOIN` + يسمح لك `SELF JOIN` بربط الجدول بنفسه. يمكنك التفكير فيه كربط نسختين من نفس الجدول. هذا مفيد لمقارنة صفوف مختلفة داخل نفس الجدول. +## عملية `CROSS JOIN` + يربط `CROSS JOIN`، المعروف أيضًا باسم الربط الكارتيزي، كل صف من الجدول الأول مع كل صف من الجدول الثاني. لذلك، يولد كل التركيبات الممكنة للصفوف. هذه العملية لا تحتاج إلى شروط لربط الجداول. +## لماذا تستخدم عمليات `JOIN` + تُعد عمليات `JOIN` هذه أساسية للعمل مع SQL. باختيار العملية المناسبة، يمكنك استعلام البيانات التي تحتاجها بأكبر كفاءة ممكنة. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-relative-and-absolute-units/672bb851b068e3954a05b9b1.md b/curriculum/challenges/arabic/blocks/lecture-working-with-relative-and-absolute-units/672bb851b068e3954a05b9b1.md index c0759b70308..7414c8056bb 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-relative-and-absolute-units/672bb851b068e3954a05b9b1.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-relative-and-absolute-units/672bb851b068e3954a05b9b1.md @@ -1,6 +1,6 @@ --- id: 672bb851b068e3954a05b9b1 -title: ما هي دالة calc()، وكيف تعمل؟ +title: ما هي دالة calc()‎، وكيف تعمل؟ challengeType: 19 dashedName: what-is-the-calc-function --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-sql/68817041f57ce139bef36541.md b/curriculum/challenges/arabic/blocks/lecture-working-with-sql/68817041f57ce139bef36541.md index aec3385df48..bae8a32fae3 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-sql/68817041f57ce139bef36541.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-sql/68817041f57ce139bef36541.md @@ -7,12 +7,16 @@ dashedName: what-is-sql-injection-and-what-are-some-ways-to-prevent-it # --description-- +## ما هو حقن SQL؟ + حقن SQL هو ثغرة أمنية في الويب يستغل فيها المهاجمون استعلامات قاعدة البيانات التي ينفذها تطبيق الويب. على سبيل المثال، يمكن للمهاجمين إدخال كود SQL خبيث داخل الاستعلام لتنفيذ هذا الكود الخبيث في الخلفية. يحدث هذا عندما تسمح للمستخدمين بإدخال بيانات عبر نماذج تسجيل الدخول أو أشرطة البحث أو معلمات URL، ثم تستخدم تلك المُدخَلات في استيفاء سلسلة نصية أو ربطها لتوليد أمر SQL النهائي. اعتمادًا على هدف المهاجم، يمكن للكود الخبيث في SQL أن يسبب اضطرابات كبيرة في قاعدة البيانات وتطبيق الويب، مثل تجاوز عملية التوثيق، سرقة البيانات من قاعدة البيانات، أو تعديل أو حذف سجلات قاعدة البيانات. لذلك، يجب أن تأخذ هذا التهديد على محمل الجد. +## تجاوز التوثيق باستخدام حقن SQL + على سبيل المثال، لنفترض أن تطبيق الويب الخاص بك يستخدم استعلام SQL مثل هذا لتوثيق المستخدمين، حيث يضمّن اسم المستخدم وكلمة المرور التي أدخلها المستخدم مباشرة: ```sql @@ -35,6 +39,8 @@ WHERE username = " " OR TRUE اعتمادًا على تنفيذ قاعدة البيانات، قد يُرجع هذا بيانات أول مستخدم أو أي مستخدم في قاعدة البيانات ويسمح للمهاجم بتسجيل الدخول بدون بيانات اعتماد صحيحة. +## منع حقن SQL + فكيف تمنع هذا؟ هناك طريقتان رئيسيتان لمنع حقن SQL: - لا تكتب استعلامات ديناميكية باستخدام ربط السلاسل النصية. @@ -44,6 +50,8 @@ WHERE username = " " OR TRUE تقنية مهمة أخرى هي التحقق من المُدخَل. يُنصح بها كإجراء أمني ثانوي في جميع الحالات، لكنها مهمة بشكل خاص لأجزاء استعلامات SQL المتعلقة بأسماء الجداول، أسماء الأعمدة، وترتيب الفرز. إذا أمكن، يُفضل تعيين أسماء الجداول والأعمدة مباشرة في الكود الخاص بك، وليس من مُدخَل المستخدم. +## تقييد أذونات قاعدة البيانات + إذا حدث هجوم حقن SQL رغم كل التدابير الوقائية، يمكنك تقليل تأثيره على قاعدة البيانات بتقييد صلاحيات كل حساب قاعدة بيانات. امنح كل مستخدم قاعدة بيانات فقط الصلاحيات اللازمة لمهامه، ولا شيء أكثر. إذا كان الحساب يحتاج فقط لقراءة البيانات من قاعدة البيانات، امنحه صلاحية القراءة فقط. وكإجراء وقائي، لا تعطي أبدًا صلاحيات المدير لحسابات التطبيق. هذا خطر جدًا لأن المهاجم قد يحصل على وصول كامل وتحكم كامل في قاعدة البيانات. حقن SQL هجوم شائع جدًا يجب أن تكون على دراية به كمطور وأن تمنعه عند تنفيذ تطبيق الويب الخاص بك. باستخدام هذه التقنيات، يمكنك حماية قاعدة بياناتك والحفاظ على أمان بيانات المستخدمين. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-sql/6881705cd9860639e98d639d.md b/curriculum/challenges/arabic/blocks/lecture-working-with-sql/6881705cd9860639e98d639d.md index f625bf6d85b..414545a079c 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-sql/6881705cd9860639e98d639d.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-sql/6881705cd9860639e98d639d.md @@ -9,10 +9,14 @@ dashedName: what-is-the-n-plus-1-problem مشكلة N+1 هي عنق زجاجة شائع في الأداء في التطبيقات التي تعتمد على قواعد البيانات. إذا واجهت وقت تحميل طويل جدًا أثناء استخدام تطبيق، فمن المحتمل جدًا أن يكون ذلك مرتبطًا بمشكلة N+1. تحدث هذه المشكلة عندما تُجرى العديد من الاستعلامات الصغيرة على التوالي للحصول على البيانات التي طلبتها. +## لماذا تتجنب إجراء الاستعلامات في متتالية + لكن لماذا تُجري العديد من الاستعلامات على التوالي؟ قد تفعل ذلك لاستعلام قائمة من السجلات ومعلومات إضافية عن تلك السجلات. ستُجري استعلامًا أوليًا للحصول على قائمة السجلات ثم تُجري استعلامًا إضافيًا لكل سجل منها للحصول على معلومات إضافية عنه. حتى لو كنت تعتقد بشكل حدسي أن إجراء العديد من الاستعلامات الصغيرة والبسيطة سيكون أكثر كفاءة من إجراء استعلام واحد كبير ومعقد، فإن هذا عادةً ليس صحيحًا. كلما زاد عدد الاستعلامات التي تُجريها، زاد الوقت الذي ستستغرقه العملية بأكملها لأنك تحتاج إلى إرسال كل استعلام إلى الخادم، والعثور على البيانات في قاعدة البيانات، ثم استلام البيانات التي يرسلها الخادم لذلك الاستعلام. هذا يمكن أن يؤثر بشكل كبير على أداء التطبيق. +## مشكلة N+1 في التطبيق العملي + لأريك مثالًا عمليًا، لنفترض أنك تطور تطبيقًا لخدمة توصيل الطعام وتجري استعلامًا للحصول على أول 50 طلبًا في قاعدة البيانات. أولًا، ستحصل على قائمة بهذه الطلبات من جدول `orders`، مثل هذا: ```sql @@ -48,6 +52,8 @@ for (const order of orders) { قد يبدو هذا النهج بسيطًا وبديهيًا، لكن قد تتفاجأ عندما تعرف أن هذا بالضبط ما يجب عليك تجنبه. يجب أن تتجنب إجراء الاستعلامات داخل حلقة لأن إجراء العديد من الاستعلامات الصغيرة سيستغرق وقتًا أطول بكثير من إجراء استعلام واحد أكبر للحصول على كل البيانات. +## تقليل عدد الاستعلامات + يجب أن تحاول استخدام الأدوات التي توفرها SQL لتقليل عدد الاستعلامات قدر الإمكان. في هذه الحالة، يمكننا استخدام عملية `JOIN` لربط جدول `orders` بجدول `customers`. ```sql diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1a3fea729e274dc33d04d.md b/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1a3fea729e274dc33d04d.md index 679276578e3..93a4ea5dce9 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1a3fea729e274dc33d04d.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1a3fea729e274dc33d04d.md @@ -15,6 +15,8 @@ dashedName: how-do-events-work-in-react لنرَ كيف تعمل الأحداث في React حتى تبدأ باستخدامها في مشاريعك. +## كيف تختلف أحداث React عن أحداث HTML + في React، تعمل معالجات الأحداث بطريقة مشابهة لأحداث المتصفح الأصلية، لكن مع بعض التعديلات. بدلاً من استخدام أسماء خصائص الأحداث بأحرف صغيرة مثل `onclick` و`onsubmit`، يستخدم React تنسيق سنام الجمل مثل `onClick` و`onSubmit`. @@ -23,6 +25,8 @@ dashedName: how-do-events-work-in-react تُمرر دالة معالج الحدث إلى العنصر كخاصية، ويُستخدم نوع الحدث مثل `onClick` أو `onSubmit` كخاصية في JSX. +## كتابة معالِج حدث + إليك تذكير بكيفية التعامل مع حدث النقر في HTML العادي: ```html @@ -45,6 +49,8 @@ function handleClick() { في React، عادةً ما تبدأ دوال معالجات الأحداث بالبادئة `handle` للدلالة على مسؤوليتها عن التعامل مع الأحداث، مثل `handleClick` أو `handleSubmit`. +## كائن الحدث الاصطناعي + عندما يطلق فعل المستخدم حدثًا، يمرر React كائن حدث اصطناعي إلى معالجك. يتصرف هذا الكائن مثل كائن الحدث الأصلي في جافاسكريبت العادية، ويوفر خصائص مثل `type` و`target` و`currentTarget`. يمكنك تمرير `event` كمعلمة إلى دالة المعالج وتسجيله في وحدة التحكم لتفحص هيكله: @@ -55,7 +61,9 @@ function handleClick(event) { } ``` -لمنع السلوكيات الافتراضية مثل تحديث المتصفح أثناء حدث `onSubmit`، يمكنك استدعاء طريقة `preventDefault()`: +## منع السلوك الافتراضي والانتشار + +لمنع السلوكيات الافتراضية مثل تحديث المتصفح أثناء حدث `onSubmit`، يمكنك استدعاء الدالة `preventDefault()`: ```jsx function handleSubmit(event) { @@ -71,6 +79,8 @@ function handleSubmit(event) { يمكنك أيضًا إيقاف حدث من التصعيد إلى العناصر الأصلية باستدعاء `event.stopPropagation()`. +## تمرير البيانات إلى معالِجات الأحداث + أحيانًا، أثناء التعامل مع حالات خاصة مثل ميزات الحذف والتعديل، قد ترغب في تمرير بيانات إضافية إلى معالج الحدث. يمكنك فعل ذلك بتغليف المعالج في دالة سهمية مضمّنة: ```jsx @@ -97,7 +107,7 @@ function handleDelete(id) { ### --feedback-- -راجع بداية الدرس حيث نوقش هذا الجواب. +راجع بداية الدرس حيث تم مناقشة الإجابة. --- @@ -105,7 +115,7 @@ function handleDelete(id) { ### --feedback-- -راجع بداية الدرس حيث نوقش هذا الجواب. +راجع بداية الدرس حيث تم مناقشة الإجابة. --- @@ -117,7 +127,7 @@ function handleDelete(id) { ### --feedback-- -راجع بداية الدرس حيث نوقش هذا الجواب. +راجع بداية الدرس حيث تم مناقشة الإجابة. ## --video-solution-- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eaf77f510e15dfed7c14.md b/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eaf77f510e15dfed7c14.md index e79cd27eddc..764cc95a874 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eaf77f510e15dfed7c14.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eaf77f510e15dfed7c14.md @@ -15,6 +15,8 @@ dashedName: what-is-state-and-how-does-the-usestate-hook-work كلما تغير الـ State، يعيد React عرض المكوِّن دون إعادة تحميل الصفحة ليعكس تلك التغييرات في واجهة المستخدم. هذه التفاعلية تجعل تطبيقك تفاعليًا. +## دالة `useState` + الـ `useState` hook هو دالة تتيح لك إعلان متغيرات State في المكوِّنات الوظيفية. قبل وجود الـ hooks، كان يمكنك استخدام الـ State فقط في مكوِّنات الصنف. لكن مع ظهور الـ hooks منذ React 16.8، يمكنك استخدام الـ State في المكوِّنات الوظيفية عبر استخدام الـ `useState` hook. @@ -31,6 +33,8 @@ import { useState } from "react"; import React from "react"; ``` +## إعلان متغير حالة + إليك كيف تعلن عن متغير State عند استيراد `useState`: ```js @@ -49,10 +53,14 @@ const [stateVariable, setStateFunction] = React.useState(initialValue); - `setStateFunction` (دالة التعيين) تحدّث متغير الحالة - `initialValue` يحدد الحالة الابتدائية +## نطاق الحالة وقواعد استخدام الـ Hooks + لاحظ أن الـ State في مكوِّن React خاص ومعزول لكل نسخة من المكوِّن. هذا يعني أنه إذا عرضت نفس المكوِّن مرتين، فإن حالة أحدهما لا تؤثر على الآخر. كما يعني أنه إذا أردت مشاركة الـ State بين المكوِّنات، يجب رفع الـ State إلى مكوِّن أب مشترك وتمريره كـ خصائص. شيء آخر هو أن الـ hooks يجب استدعاؤها في المستوى الأعلى للمكوِّن، قبل كلمة `return` مباشرة، للحفاظ على ثبات الـ State والتأثيرات عبر عمليات العرض. هذا يعني أنه لا يمكنك استخدام الـ State داخل الحلقات أو الشروط أو الدوال المسكنة. +## مثال: مكوِّن عداد + إليك مثالًا على إدارة الـ State باستخدام الـ `useState` hook في مكوِّن `Counter`: ```jsx @@ -81,6 +89,8 @@ export default Counter; في الكود أعلاه، استوردنا الـ `useState` من React. في مكوِّن `Counter`، تمثل `count` الحالة الحالية بينما `setCount` هي الدالة المسؤولة عن تحديث الحالة. القيمة الحالية للحالة هي `0`. يحتوي تعبير `return` على العدد وزرين لتقليل وزيادة العدد بمقدار `1`. +## إدارة متغيرات حالة متعددة + يمكنك إدارة عدة أجزاء من الـ State باستدعاء الـ `useState` hook عدة مرات. هذا مهم خصوصًا عندما تكون متغيرات الـ State غير مرتبطة: ```jsx diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eb6929e68117faa6717f.md b/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eb6929e68117faa6717f.md index 6c5b76f95c7..21724895d14 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eb6929e68117faa6717f.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eb6929e68117faa6717f.md @@ -13,6 +13,8 @@ dashedName: what-is-rendering-in-react-and-how-are-components-displayed-on-the-s تتكون عملية العرض من ثلاث مراحل: التفعيل، العرض، والتثبيت. دعنا نلقي نظرة على هذه المراحل بمزيد من التفصيل. +## مرحلة التفعيل + تحدث مرحلة التفعيل عندما تكتشف React أن شيئًا ما قد تغير وأن واجهة المستخدم قد تحتاج إلى تحديث. غالبًا ما يكون هذا التغيير بسبب تحديث في الحالة أو الخصائص. على سبيل المثال، ملاحظة أن وقت العشاء قد حان يمكن أن تحفزك على الذهاب إلى المطبخ لبدء الطهي. @@ -37,6 +39,8 @@ function Counter() { export default Counter; ``` +## مرحلة العرض + بمجرد حدوث التفعيل، تدخل React مرحلة العرض. هنا، تعيد React تقييم مكوِّناتك وتحدد ما يجب عرضه. للقيام بذلك، تستخدم React نسخة خفيفة من DOM "الحقيقي". تُسمى هذه النسخة DOM الافتراضي. باستخدام DOM الافتراضي، يمكن لـ React بسرعة التحقق مما يحتاج إلى تغيير في المكوِّن. @@ -45,6 +49,8 @@ export default Counter; بالنسبة لمكوِّن `Counter`، مرحلة العرض هي النقطة التي تعيد فيها React تشغيل الدوال مع القيمة الجديدة لـ `count`. تعيد React حساب كيف يجب أن يبدو جزء `

{count}

` من المكوِّن بناءً على القيمة المحدثة لـ `count`، لكنك لن ترى أي تغييرات على الشاشة حتى المرحلة التالية – التثبيت. +## مرحلة التنفيذ + مرحلة التثبيت هي حيث يأخذ React التغييرات المُعدة من DOM الافتراضي ويطبقها على DOM الحقيقي. بعبارة أخرى، هذه هي المرحلة التي ترى فيها النتيجة النهائية على الشاشة. لتحقيق ذلك، تقارن React بين DOM الافتراضي وDOM الفعلي، وتحدد فقط الأجزاء التي تحتاج إلى تحديث، وتطبق تلك التغييرات على DOM الحقيقي لتحديث واجهة المستخدم. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-string-character-methods/672d266034b5242126271995.md b/curriculum/challenges/arabic/blocks/lecture-working-with-string-character-methods/672d266034b5242126271995.md index 6c827db2aa2..2d209df3250 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-string-character-methods/672d266034b5242126271995.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-string-character-methods/672d266034b5242126271995.md @@ -1,6 +1,6 @@ --- id: 672d266034b5242126271995 -title: ما هو ASCII، وكيف يعمل مع charCodeAt() و fromCharCode()؟ +title: ما هو ASCII، وكيف يعمل مع charCodeAt()‎ و fromCharCode()‎؟ challengeType: 19 dashedName: what-is-ascii-and-how-does-it-work-with-charcodeat-and-fromcharcode --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-strings-in-javascript/673263f4a5899da8124542fd.md b/curriculum/challenges/arabic/blocks/lecture-working-with-strings-in-javascript/673263f4a5899da8124542fd.md index 7acb2cd92be..d71a90a5427 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-strings-in-javascript/673263f4a5899da8124542fd.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-strings-in-javascript/673263f4a5899da8124542fd.md @@ -1,6 +1,6 @@ --- id: 673263f4a5899da8124542fd -title: ما هي طريقة prompt() وكيف تعمل؟ +title: ما هي طريقة prompt()‎ وكيف تعمل؟ challengeType: 19 dashedName: what-is-the-prompt-method-and-how-does-it-work --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368b1cf26253212a3cfb2.md b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368b1cf26253212a3cfb2.md index 6d290ba826c..dd2db9cfbee 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368b1cf26253212a3cfb2.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368b1cf26253212a3cfb2.md @@ -1,6 +1,6 @@ --- id: 673368b1cf26253212a3cfb2 -title: ما هي طريقة querySelectorAll()، ومتى يجب استخدامها؟ +title: ما هي طريقة querySelectorAll()‎، ومتى يجب استخدامها؟ challengeType: 19 dashedName: what-is-the-queryselectorall-method-and-when-should-you-use-it --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368c0161e6b326a7e03f0.md b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368c0161e6b326a7e03f0.md index f243a792537..1fd6c4cafe7 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368c0161e6b326a7e03f0.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368c0161e6b326a7e03f0.md @@ -1,6 +1,6 @@ --- id: 673368c0161e6b326a7e03f0 -title: كيف تنشئ عقدًا جديدة باستخدام innerHTML و createElement()؟ +title: كيف تنشئ عقدًا جديدة باستخدام innerHTML و createElement()‎؟ challengeType: 19 dashedName: how-do-you-create-new-nodes-using-innerhtml-and-createelement --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368d97e8ce232cdcd6b68.md b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368d97e8ce232cdcd6b68.md index 0af7f5dba26..bd3d3aa9bb7 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368d97e8ce232cdcd6b68.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368d97e8ce232cdcd6b68.md @@ -1,6 +1,6 @@ --- id: 673368d97e8ce232cdcd6b68 -title: كيف تضيف وتحذف العقد من DOM باستخدام appendChild() و removeChild()؟ +title: كيف تضيف وتحذف العقد من DOM باستخدام appendChild()‎ و removeChild()‎؟ challengeType: 19 dashedName: how-do-you-add-and-remove-nodes-from-the-dom-with-appendchild-and-removechild --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368f272706633516e4873.md b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368f272706633516e4873.md index a712c2dd1fd..6513d398ef2 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368f272706633516e4873.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673368f272706633516e4873.md @@ -1,6 +1,6 @@ --- id: 673368f272706633516e4873 -title: كيف تضيف خصائص باستخدام setAttribute()؟ +title: كيف تضيف خصائص باستخدام setAttribute()‎؟ challengeType: 19 dashedName: how-do-you-add-attributes-with-setattribute --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673369067f824d33a90a0534.md b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673369067f824d33a90a0534.md index edf90277519..9796f4805b4 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673369067f824d33a90a0534.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673369067f824d33a90a0534.md @@ -7,6 +7,8 @@ dashedName: how-does-the-addeventlistener-method-work # --interactive-- +## ما هي طريقة `addEventListener()`؟ + عندما ينقر المستخدم على زر أو يحدث تغيير في نموذج، يُعرف هذا بحدث. في برامجك، ستحتاج إلى طريقة للاستماع إلى هذه الأحداث والاستجابة لها. تُستخدم طريقة `addEventListener()` للاستماع إلى الأحداث. تأخذ معلمتين: الحدث الذي تريد الاستماع إليه ودالة تُستدعى عند حدوث الحدث. @@ -29,6 +31,8 @@ element.addEventListener("click", () => { }); ``` +## تمرير مرجع دالة + يمكنك أيضًا اختيار تمرير مرجع دالة هكذا: ```js @@ -41,10 +45,14 @@ element.addEventListener("click", handleClick); أحيانًا قد ترغب في إنشاء دالة منفصلة لمعالجة الحدث. هذا يجعل كودك أسهل في القراءة والصيانة. +## استخدام واجهة `EventListener` + يمكن أن تكون المعلمة listener أيضًا `null`، أو كائنًا يستخدم واجهة `EventListener`. تحدد واجهة `EventListener` طريقة واحدة تسمى `handleEvent()`. تُستدعى هذه الطريقة تلقائيًا كلما حدث الحدث الذي تستمع إليه. استخدام هذه الواجهة يسمح لنفس الكائن بالتعامل مع عدة أحداث إذا لزم الأمر. في معظم الأحيان، لن تحتاج إلى استخدام هذه الواجهة، ويمكنك بدلاً من ذلك تمرير دالة تُستدعى عند حدوث الحدث. +## الاستماع إلى حدث `click` + الآن، لنلقِ نظرة على مثال لفهم كيفية عمل ذلك بشكل أفضل: في هذا المثال، لدينا عنصر `button` بمعرف `btn`: @@ -78,6 +86,8 @@ btn.addEventListener("click", () => alert("You clicked the button")); You clicked the button ``` +## الاستماع إلى حدث `input` + نوع آخر من الأحداث التي يمكنك الاستماع إليها هو حدث `"input"`. يُطلق هذا الحدث عندما يتغير قيمة عنصر الإدخال. إليك مثال: @@ -107,6 +117,8 @@ input.addEventListener("input", () => { ::: +## الاستماع إلى أحداث أخرى + هناك العديد من الأحداث الأخرى التي يمكنك الاستماع إليها باستخدام طريقة `addEventListener()`. بعض الأحداث الشائعة تشمل `mouseover`، `mouseout`، `keydown`، `keyup`، و`submit`. في الدروس القادمة، سنغطي المزيد من الأحداث وكيفية استخدام طريقة `addEventListener()` للاستماع إليها. diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/67336956340e8a34fbd5d9f3.md b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/67336956340e8a34fbd5d9f3.md index b1d98d55abd..ca7c78fdeac 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/67336956340e8a34fbd5d9f3.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-the-dom-click-events-and-web-apis/67336956340e8a34fbd5d9f3.md @@ -1,6 +1,6 @@ --- id: 67336956340e8a34fbd5d9f3 -title: ما هي واجهة برمجة التطبيقات requestAnimationFrame()، وكيف يمكن استخدامها لإعداد حلقة رسوم متحركة؟ +title: ما هي واجهة برمجة التطبيقات requestAnimationFrame()‎، وكيف يمكن استخدامها لإعداد حلقة رسوم متحركة؟ challengeType: 19 dashedName: what-is-the-requestanimationframe-api-and-how-can-it-be-used-to-set-up-an-animation-loop --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-types-and-objects/6732c68f4520d160584a6fd2.md b/curriculum/challenges/arabic/blocks/lecture-working-with-types-and-objects/6732c68f4520d160584a6fd2.md index b9998526acb..d72b4b67c08 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-types-and-objects/6732c68f4520d160584a6fd2.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-types-and-objects/6732c68f4520d160584a6fd2.md @@ -1,6 +1,6 @@ --- id: 6732c68f4520d160584a6fd2 -title: ما هي طريقة toString() وكيف تعمل؟ +title: ما هي طريقة toString()‎ وكيف تعمل؟ challengeType: 19 dashedName: what-is-the-tostring-method-and-how-does-it-work --- diff --git a/curriculum/challenges/arabic/blocks/lecture-working-with-types-and-objects/6732c69d82814160951b1aa7.md b/curriculum/challenges/arabic/blocks/lecture-working-with-types-and-objects/6732c69d82814160951b1aa7.md index d1163cfc376..14bbecf6f0d 100644 --- a/curriculum/challenges/arabic/blocks/lecture-working-with-types-and-objects/6732c69d82814160951b1aa7.md +++ b/curriculum/challenges/arabic/blocks/lecture-working-with-types-and-objects/6732c69d82814160951b1aa7.md @@ -1,6 +1,6 @@ --- id: 6732c69d82814160951b1aa7 -title: ما هو دالة البناء Number()، وكيف تعمل على إجبار النوع؟ +title: ما هو دالة البناء Number()‎، وكيف تعمل على إجبار النوع؟ challengeType: 19 dashedName: what-is-the-number-constructor-and-how-does-it-work-for-type-coercion --- diff --git a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0a.md b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0a.md index f0af96dd898..9d7c197a3fb 100644 --- a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0a.md +++ b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0a.md @@ -1,6 +1,6 @@ --- id: 587d7fb7367417b2b2512c0a -title: إنشاء سجلات متعددة باستخدام model.create() +title: إنشاء سجلات متعددة باستخدام model.create()‎ challengeType: 2 forumTopicId: 301537 dashedName: create-many-records-with-model-create diff --git a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0b.md b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0b.md index 84df3c57cb4..06f624cd1ed 100644 --- a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0b.md +++ b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0b.md @@ -1,6 +1,6 @@ --- id: 587d7fb7367417b2b2512c0b -title: استخدام model.find() للبحث في قاعدة بياناتك +title: استخدام model.find()‎ للبحث في قاعدة بياناتك challengeType: 2 forumTopicId: 301543 dashedName: use-model-find-to-search-your-database diff --git a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0c.md b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0c.md index ee27fba0f36..8fa38d4a9ce 100644 --- a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0c.md +++ b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0c.md @@ -1,6 +1,6 @@ --- id: 587d7fb7367417b2b2512c0c -title: استخدام model.findOne() لإرجاع مستند مطابق واحد من قاعدة بياناتك +title: استخدام model.findOne()‎ لإرجاع مستند مطابق واحد من قاعدة بياناتك challengeType: 2 forumTopicId: 301545 dashedName: use-model-findone-to-return-a-single-matching-document-from-your-database diff --git a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0d.md b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0d.md index 802b5ccacf0..ea772a5250a 100644 --- a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0d.md +++ b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb7367417b2b2512c0d.md @@ -1,6 +1,6 @@ --- id: 587d7fb7367417b2b2512c0d -title: استخدام model.findById() للبحث في قاعدة بياناتك بواسطة _id +title: استخدام model.findById()‎ للبحث في قاعدة بياناتك بواسطة _id challengeType: 2 forumTopicId: 301544 dashedName: use-model-findbyid-to-search-your-database-by-id diff --git a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb8367417b2b2512c0f.md b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb8367417b2b2512c0f.md index 7a4a731860b..64416dec1f1 100644 --- a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb8367417b2b2512c0f.md +++ b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb8367417b2b2512c0f.md @@ -1,6 +1,6 @@ --- id: 587d7fb8367417b2b2512c0f -title: إجراء تحديثات جديدة على وثيقة باستخدام model.findOneAndUpdate() +title: إجراء تحديثات جديدة على وثيقة باستخدام model.findOneAndUpdate()‎ challengeType: 2 forumTopicId: 301542 dashedName: perform-new-updates-on-a-document-using-model-findoneandupdate diff --git a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb8367417b2b2512c11.md b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb8367417b2b2512c11.md index 76f6d84d329..c7789c3d53e 100644 --- a/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb8367417b2b2512c11.md +++ b/curriculum/challenges/arabic/blocks/mongodb-and-mongoose/587d7fb8367417b2b2512c11.md @@ -1,6 +1,6 @@ --- id: 587d7fb8367417b2b2512c11 -title: حذف العديد من الوثائق باستخدام model.remove() +title: حذف العديد من الوثائق باستخدام model.remove()‎ challengeType: 2 forumTopicId: 301538 dashedName: delete-many-documents-with-model-remove diff --git a/curriculum/challenges/arabic/blocks/quiz-css-typography/66ed9010f45ce3ece4053eb8.md b/curriculum/challenges/arabic/blocks/quiz-css-typography/66ed9010f45ce3ece4053eb8.md index d19d547ab4d..93d5eb1d6bb 100644 --- a/curriculum/challenges/arabic/blocks/quiz-css-typography/66ed9010f45ce3ece4053eb8.md +++ b/curriculum/challenges/arabic/blocks/quiz-css-typography/66ed9010f45ce3ece4053eb8.md @@ -135,11 +135,11 @@ dashedName: quiz-css-typography --- -Papyrus +بابيروس --- -Impact +إمباكت #### --answer-- @@ -873,7 +873,7 @@ body { #### --text-- -أي مما يلي يمكن استخدامه للوصول إلى الخطوط الخارجية؟ +أي مما يلي يمكن استخدامه لاستيراد ورقة أنماط خارجية تحتوي على تعريفات الخطوط؟ #### --distractors-- diff --git a/curriculum/challenges/arabic/blocks/quiz-python-installation/69fd84e01123960e15bb8455.md b/curriculum/challenges/arabic/blocks/quiz-python-installation/69fd84e01123960e15bb8455.md index 2bbe500fe80..105ace1f61d 100644 --- a/curriculum/challenges/arabic/blocks/quiz-python-installation/69fd84e01123960e15bb8455.md +++ b/curriculum/challenges/arabic/blocks/quiz-python-installation/69fd84e01123960e15bb8455.md @@ -29,7 +29,7 @@ dashedName: quiz-python-installation --- -من مدير pip +من مدير الحزم pip #### --answer-- @@ -87,7 +87,7 @@ dashedName: quiz-python-installation #### --distractors-- -JetBrains وCLion وWindSurf +JetBrains وCLion وWindsurf --- @@ -95,7 +95,7 @@ JetBrains وCLion وWindSurf --- -Clang و Pip و Deno +Clang و pip و Deno #### --answer-- @@ -187,7 +187,7 @@ Python يثبت الحزم. #### --answer-- -Python ينتظر نص المُدخَل من المستخدم. +Python ينتظر منك إدخال أمر. ### --question-- @@ -219,11 +219,11 @@ Python ينتظر نص المُدخَل من المستخدم. #### --distractors-- -يطبع `"Hello, world!"` بشكل متكرر حتى يتوقف المستخدم. +يطبع `Hello, world!` في حلقة حتى يتوقف المستخدم. --- -ينشئ ملفًا ويطبع `"Hello, world!"` في الطرفية. +ينشئ ملفًا ويطبع `Hello, world!` في واجهة سطر الأوامر. --- @@ -231,4 +231,4 @@ Python ينتظر نص المُدخَل من المستخدم. #### --answer-- -يطبع `"Hello, world!"` في الطرفية. +يطبع `Hello, world!` في واجهة سطر الأوامر. diff --git a/curriculum/challenges/arabic/blocks/react/5a24c314108439a4d403618a.md b/curriculum/challenges/arabic/blocks/react/5a24c314108439a4d403618a.md index cfaf4507c0c..bb3f3190a2a 100644 --- a/curriculum/challenges/arabic/blocks/react/5a24c314108439a4d403618a.md +++ b/curriculum/challenges/arabic/blocks/react/5a24c314108439a4d403618a.md @@ -1,6 +1,6 @@ --- id: 5a24c314108439a4d403618a -title: استخدام Array.map() لعرض العناصر ديناميكيًا +title: استخدام Array.map()‎ لعرض العناصر ديناميكيًا challengeType: 6 forumTopicId: 301417 dashedName: use-array-map-to-dynamically-render-elements diff --git a/curriculum/challenges/arabic/blocks/react/5a24c314108439a4d403618c.md b/curriculum/challenges/arabic/blocks/react/5a24c314108439a4d403618c.md index 4bba6df000a..16f04ba99bd 100644 --- a/curriculum/challenges/arabic/blocks/react/5a24c314108439a4d403618c.md +++ b/curriculum/challenges/arabic/blocks/react/5a24c314108439a4d403618c.md @@ -1,6 +1,6 @@ --- id: 5a24c314108439a4d403618c -title: استخدام Array.filter() لتصفية مصفوفة بشكل ديناميكي +title: استخدام Array.filter()‎ لتصفية مصفوفة بشكل ديناميكي challengeType: 6 forumTopicId: 301416 dashedName: use-array-filter-to-dynamically-filter-an-array diff --git a/curriculum/challenges/arabic/blocks/review-back-end-development-and-apis/6a439658bfbe59fcf4b221c7.md b/curriculum/challenges/arabic/blocks/review-back-end-development-and-apis/6a439658bfbe59fcf4b221c7.md index 1d952429948..069e5e3b860 100644 --- a/curriculum/challenges/arabic/blocks/review-back-end-development-and-apis/6a439658bfbe59fcf4b221c7.md +++ b/curriculum/challenges/arabic/blocks/review-back-end-development-and-apis/6a439658bfbe59fcf4b221c7.md @@ -342,10 +342,10 @@ Content-Length: 105 - **HTML**: `text/html` - **CSS**: `text/css` -- **جافاسكريبت**: `application/javascript` +- **JavaScript**: `text/javascript` - **JSON**: `application/json` -- **PNG/JPEG/WebP**: `image/png` ،`image/jpeg` ،`image/webp` -- **MP4/MP3**: `video/mp4` ،`audio/mpeg` +- **PNG/JPEG/WebP**: `image/png`, `image/jpeg`, `image/webp` +- **MP4/MP3**: `video/mp4`, `audio/mpeg` - **PDF**: `application/pdf` - **WOFF2**: `font/woff2` diff --git a/curriculum/challenges/arabic/blocks/review-graphs-and-trees-js/698c302951ac746466349fd9.md b/curriculum/challenges/arabic/blocks/review-graphs-and-trees-js/698c302951ac746466349fd9.md index 4b4b5e20231..0ce5b768765 100644 --- a/curriculum/challenges/arabic/blocks/review-graphs-and-trees-js/698c302951ac746466349fd9.md +++ b/curriculum/challenges/arabic/blocks/review-graphs-and-trees-js/698c302951ac746466349fd9.md @@ -9,98 +9,147 @@ dashedName: review-graphs-and-trees-js ## نظرة عامة على الرسوم البيانية -الرسم البياني هو مجموعة من العقد (الرؤوس) متصلة بحواف (وصلات). يمكن لكل عقدة الاتصال بعدة عقد أخرى، مكونة شبكة. تشمل أنواع الرسوم البيانية المختلفة ما يلي: +الرسم البياني هو مجموعة من العقد (الرؤوس) متصلة بحواف (الاتصالات). يمكن لكل عقدة الاتصال بعدة عقد أخرى، مكونة شبكة. أنواع الرسوم البيانية المختلفة تشمل: -- موجه: الحواف لها اتجاه (من عقدة إلى أخرى)، وغالبًا ما تمثل بخطوط مستقيمة وأسهم. -- غير موجه: الحواف بلا اتجاه، وتمثل بخطوط بسيطة. -- ذات مسميات للرؤوس: كل عقدة مرتبطة بمسمى أو معرف. -- دوري: يحتوي على دورات (مسار يبدأ وينتهي عند نفس العقدة). -- غير دوري (DAG): لا يحتوي على دورات. -- ذات مسميات للحواف: كل حافة لها مسمى عادةً ما يُرسم بجانب الحافة المقابلة. -- موزون: الحواف لها أوزان (قيم) مرتبطة بها، يمكن استخدامها لأداء العمليات الحسابية. -- غير متصل: يحتوي على عقدتين أو أكثر غير متصلتين بأي حواف. +- **موجَّه**: الحواف لها اتجاه (من عقدة إلى أخرى)، وغالبًا ما تُمثَّل بخطوط مستقيمة وأسهم. +- **غير موجَّه**: الحواف بلا اتجاه، تُمثَّل بخطوط بسيطة. +- **عقدة معنونة**: كل عقدة مرتبطة بمسمى أو معرف. +- **دائري**: يحتوي على دورات (مسار يبدأ وينتهي عند نفس العقدة). +- **رسم بياني موجَّه لا دوري (DAG)**: رسم بياني موجَّه بلا دورات. +- **حافة معنونة**: كل حافة لها مسمى يُرسم عادةً بجانبها. +- **موزون**: الحواف لها أوزان (قيم) يمكن استخدامها في العمليات الحسابية. +- **منفصل**: يحتوي على مجموعتين أو أكثر من العقد (مكوِّنات) غير متصلة بأي حواف. يمكن أن تفتقر عقدتان إلى حافة مباشرة ومع ذلك يكون بينهما مسار. -تُستخدم الرسوم البيانية في تطبيقات متنوعة مثل الخرائط، الشبكات، أنظمة التوصية، وحل تبعيات. +تُستخدم الرسوم البيانية في تطبيقات متنوعة مثل الخرائط، الشبكات، أنظمة التوصية، وحل التبعيات. -## استعراض الرسوم البيانية +## استعراضات الرسوم البيانية -يتضمن ذلك زيارة جميع العقد في الرسم البياني. الخوارزميات الرئيسية هي: +تشمل زيارة جميع العقد في الرسم البياني. الخوارزميات الرئيسية هي: -- **البحث بالاتساع أولاً (BFS)** - - يستخدم طابور. - - يستكشف مستوى بمستوى. - - يجد أقصر مسار في الرسوم غير الموزونة. +- **البحث بالاتساع أولاً (BFS)**: يزور جميع العقد المجاورة قبل الانتقال إلى المستوى التالي في الرسم البياني. + - **طابور**: يستخدم طابور (FIFO). تُعلَم العقدة البداية بأنها مُزارة وتُضاف إلى الطابور. طالما الطابور غير فارغ، تُزال العقدة الحالية من الطابور، وتُعلَم كل جيرانها غير المزارة بأنها مُزارة وتُضاف إلى الطابور. + - **أقصر مسار**: يجد أقصر مسار في الرسوم البيانية غير الموزونة. + - **ذاكرة**: يتطلب تخزين الطابور في الذاكرة، لذا قد تكون متطلبات المساحة كبيرة، خاصةً للرسوم التي تحتوي على عدد كبير من العقد في نفس المستوى. + - **المكوِّنات المتصلة**: يمكن استخدامه أيضًا لإيجاد مكونات الرسم البياني المتصلة، ببدء بحث جديد من كل عقدة لم تُزر بعد. + - **بحث فضاء الحالة**: يستخدم طابورًا لتتبع الحالات المختلفة أثناء بناء تراكيب الأقواس. تمثل كل حالة كمصفوفة تحتوي على السلسلة النصية الحالية، وعدد الأقواس المفتوحة المستخدمة حتى الآن، وعدد الأقواس المغلقة المستخدمة حتى الآن. يمكن إضافة قوس مفتوح فقط إذا كان عدد الأقواس المفتوحة أقل من عدد الأزواج. يمكن إضافة قوس مغلق فقط إذا حافظ على التوازن، بمعنى أن عدد الأقواس المفتوحة يجب أن يكون أكبر من عدد الأقواس المغلقة. -- **البحث بالعمق أولاً (DFS)** - - يستخدم مكدس (أو استدعاء ذاتي). - - يستكشف فرعًا كاملاً قبل التراجع. - - مفيد لاكتشاف الدورات وإيجاد المسارات. +- **البحث بالعمق أولاً (DFS)**: يتبع كل فرع إلى أقصى عمق ممكن قبل التراجع. + - **مكدس**: يستخدم مكدس (LIFO) أو الاستدعاء الذاتي. تُعلَم العقدة البداية بأنها مُزارة وتُضاف إلى المكدس. طالما المكدس غير فارغ، تُزال العقدة الحالية من المكدس، وتُعلَم جيرانها غير المزارة بأنها مُزارة وتُضاف إلى المكدس. + - **ذاكرة**: يتطلب تخزين مكدس (أو مكدس استدعاءات الدالة عند استخدام الاستدعاء الذاتي) في الذاكرة، لذا قد تنمو متطلبات المساحة في الرسوم التي تحتوي على مسارات طويلة جدًا. + - **حالات الاستخدام**: مفيد لاكتشاف الدورات، إيجاد المسارات، وإيجاد المكونات المتصلة. + - **القيود**: لا يضمن دائمًا إيجاد أقصر مسار بين عقدتين في رسم بياني غير موزون. ## تمثيلات الرسوم البيانية يمكن تمثيل الرسوم البيانية بطريقتين رئيسيتين: -- **قائمة المجاورة** - - لكل عقدة قائمة بجيرانها. - - فعالة في استخدام المساحة للرسوم المتفرقة. - - سهلة التكرار على الجيران. - -- **المصفوفة المجاورة** - - مصفوفة ثنائية الأبعاد تمثل الصفوف والأعمدة العقد. - - تستهلك مساحة كبيرة للرسوم الكبيرة. - - سريعة في التحقق من وجود حافة بين عقدتين. +- **قائمة الجوار**: لكل عقدة قائمة بجيرانها. + - **التنفيذ**: كمصفوفة، حيث يمثل كل فهرس عقدة والمصفوفة المخزنة عند هذا الفهرس تحتوي على جيرانها. ككائن (أو `Map`)، حيث يمثل كل مفتاح عقدة والقيمة المرتبطة به (مصفوفة) تحتوي على جيرانها. + - **المساحة**: فعالة من حيث المساحة للرسوم المتفرقة، بتعقيد مساحة `O(V + E)`، حيث `V` عدد العقد و`E` عدد الحواف. + - **الجيران**: سهل التكرار على الجيران، إذ يتطلب فقط الوصول إلى القائمة المرتبطة بالعقدة. + - **البحث عن الحافة**: أقل كفاءة من المصفوفات المجاورة لتحديد وجود حافة بين عقدتين. عادةً ما يستغرق `O(deg(v))` وقتًا، حيث `deg(v)` عدد جيران العقدة التي تفحصها، وفي أسوأ الحالات يمكن أن يكون `O(V)`. + - **الأفضل لـ**: عادةً الخيار المفضل للسيناريوهات الواقعية، حيث الرسوم المتفرقة أكثر شيوعًا. + +- **المصفوفة المجاورة**: مصفوفة ثنائية الأبعاد تمثل الصفوف والأعمدة العقد. + - **القيم**: إذا كان الرسم غير موزون، تعني القيمة `1` وجود حافة تربط العقدتين، والقيمة `0` تعني عدم وجود حافة بينهما. إذا كان الرسم موزونًا، تمثل القيمة وزن الحافة التي تربط العقد. + - **الحلقات الذاتية**: تمثل القيم في القطر ما إذا كانت كل عقدة لها حلقة ذاتية، وهي حافة تربط العقدة بنفسها. + - **المساحة**: مكثفة المساحة للرسوم الكبيرة، مع متطلبات مساحة تربيعية كبيرة `O(V²)`، حيث `V` عدد العقد في الرسم. + - **البحث عن الحافة**: سريع للتحقق من وجود حافة بين عقدتين، لأنه يستغرق وقتًا ثابتًا `O(1)`. + - **الجيران**: غير فعال لإيجاد جيران العقدة، لأن البرنامج يجب أن يكرر على الصف أو العمود بأكمله. في أسوأ الحالات، يستغرق هذا `O(V)` وقتًا. + - **الأفضل لـ**: مفيد للرسوم الكثيفة التي تحتوي على العديد من الحواف. غير فعال للرسوم المتفرقة التي تحتوي على عدد قليل من الحواف. + +## خوارزمية أقصر مسار + +- **خوارزمية أقصر مسار**: تحسب أقصر مسار بين العقد في رسم موزون وتُرجع كلًا من المسافات والمسارات المتبعة. + - **المصفوفة المجاورة**: تمثل كل قيمة وزن (مسافة) الحافة بين عقدتين. + - **الحواف المفقودة**: تعني القيمة `INF` (`Infinity`) عدم وجود حافة مباشرة. + - **المسافات**: مصفوفة تتعقب أقصر مسافة معروفة من العقدة البداية إلى كل عقدة أخرى. في البداية، تُفترض كل العقد بعيدة إلى ما لا نهاية، والمسافة من العقدة البداية إلى نفسها دائمًا `0`. + - **المسارات**: قائمة حيث كل إدخال هو مصفوفة من فهارس العقد تمثل المسار المتبع للوصول إلى كل عقدة. + - **المزارة**: مصفوفة تتعقب العقد التي تمت معالجتها بالفعل حتى لا تُعاد زيارتها. + - **أقرب عقدة غير مزارة**: الحلقة الرئيسية تعمل مرة واحدة لكل عقدة في الرسم، مختارةً أقرب عقدة غير مزارة في كل مرة. + - **استرخاء الحافة**: لكل جار له حافة فعلية ولم يُزر بعد، تحقق إذا كان يمكن الوصول إليه بكفاءة أكبر عبر العقدة الحالية. إذا كانت المسافة الجديدة أفضل من المخزنة، حدّث المسافة والمسار. + - **العقد غير القابلة للوصول**: عندما لا يُعثر على عقدة صالحة، تصبح كل العقد المتبقية غير قابلة للوصول، فتتوقف الحلقة مبكرًا. + - **الهدف الاختياري**: معلمة `targetNode` اختيارية. عند عدم توفيرها، تحسب الدالة أقصر المسارات من `startNode` إلى كل العقد الأخرى في الرسم. ## الأشجار -الشجرة نوع خاص من الرسوم البيانية غير الدوري والمتصل. الخصائص الرئيسية تشمل: +الشجرة نوع خاص من الرسوم البيانية التي لا تحتوي على دورات ومتصلة. الخصائص الرئيسية تشمل: + +- **لا دورية**: الشجرة لا تحتوي على حلقات أو دورات (مسارات يبدأ وينتهي عند نفس العقدة). +- **متصلة**: يمكن الوصول إلى كل عقدة من كل عقدة أخرى. + +### مصطلحات الشجرة -- لا تحتوي على حلقات أو دورات (مسارات يبدأ وينتهي عند نفس العقدة). -- يجب أن تكون متصلة (يمكن الوصول إلى كل عقدة من أي عقدة أخرى). +- **عقدة الجذر**: أعلى نقطة في الشجرة. هي العقدة الوحيدة في الشجرة التي لا تملك عقدة أصل. +- **عقدة الأصل**: عقدة متصلة مباشرة بعقد أخرى تحتها. +- **عقدة فرعية**: عقدة متصلة مباشرة بعقدة فوقها. +- **ورقة**: عقدة لا تملك عقدًا فرعية. +- **العمق**: طول المسار من الجذر إلى تلك العقدة. +- **الارتفاع**: طول المسار من تلك العقدة نزولًا إلى ورقة. ارتفاع الشجرة هو ارتفاع عقدة الجذر. +- **الدرجة**: عدد العقد الفرعية لكل عقدة. +- **شجرة فرعية**: قسم من الشجرة هو شجرة بحد ذاته. +- **شجرة متوازنة**: شجرة يكون فيها ارتفاع الأشجار الفرعية اليسرى واليمنى لأي عقدة متقاربًا جدًا لضمان كفاءة العمليات. ### الأنواع الشائعة من الأشجار الأنواع الأكثر شيوعًا من الأشجار هي: -- الأشجار الثنائية - - لكل عقدة طفلان كحد أقصى، طفل أيسر وطفل أيمن. +- **الأشجار الثنائية**: كل عقدة لها طفلان كحد أقصى، طفل أيسر وطفل أيمن. -- أشجار البحث الثنائية (BST) - - شجرة ثنائية حيث كل طفل أيسر أقل من عقدة الأصل، وكل طفل أيمن أكبر من عقدة الأصل. +- **شجرة البحث الثنائي (BST)**: شجرة ثنائية حيث لكل عقدة، كل القيم في الشجرة الفرعية اليسرى أقل من قيمة العقدة، وكل القيم في الشجرة الفرعية اليمنى أكبر من قيمة العقدة. يجب أن تكون الأشجار الفرعية اليسرى واليمنى أيضًا أشجار بحث ثنائية. +- **الأشجار ذات التوازن الذاتي**: أشجار تحتوي على منطق داخلي إضافي يعيد توازن الشجرة عند الإدخالات أو الحذف التي تخلق حالة اختلال توازن. أمثلة شائعة تشمل أشجار AVL، أشجار الأحمر-الأسود، وأشجار B. -## شجرة Trie - -تُعرف أيضًا بأشجار البادئة، تُستخدم لتخزين مجموعات من السلاسل النصية، حيث تمثل كل عقدة حرفًا. +- **أشجار AVL**: نوع من أشجار البحث الثنائية ذات التوازن الذاتي حيث يختلف ارتفاع الأشجار الفرعية اليسرى واليمنى لأي عقدة بحد أقصى واحد. -يُخزن البادئات المشتركة مرة واحدة فقط، مما يجعلها فعالة لمهام مثل الإكمال التلقائي وتصحيح الإملاء. +- **أشجار الأحمر-الأسود**: نوع من أشجار البحث الثنائية ذات التوازن الذاتي حيث تُلوَّن كل عقدة باللون الأحمر أو الأسود. -عمليات البحث والإدخال لها تعقيد زمني O(L)، حيث L هو طول السلسلة النصية. +- **أشجار B**: نوع من الأشجار ذات التوازن الذاتي حيث يمكن لكل عقدة أن تحتوي على مفاتيح متعددة وأكثر من طفلين. -## طوابير الأولوية +## شجرة Trie -طابور الأولوية هو نوع بيانات مجرد حيث لكل عنصر أولوية. +- **شجرة Trie**: تُعرف أيضًا بأشجار البادئة، تُستخدم لتخزين مجموعات من السلاسل النصية، حيث تمثل كل عقدة حرفًا. +- **عقدة الجذر**: لا تمثل أي حرف معين، لذا يمكن اعتبارها تمثل سلسلة فارغة. +- **البادئات**: أثناء التنقل في الشجرة من الجذر، يحدد المسار إلى عقدة بادئة معينة. +- **علامات نهاية الكلمة**: تُعيَّن علامات نهاية الكلمة للعقد التي تمثل كلمات كاملة. +- **البادئات المشتركة**: عندما تشترك عدة سلاسل في نفس البادئة، تتداخل مساراتها، لذا تُخزن البادئة مرة واحدة فقط. هذا يجعل شجرة Trie فعالة لمهام مثل الإكمال التلقائي وتصحيح الإملاء. +- **الإدخال**: يتطلب فقط إنشاء عقد جديدة للأحرف التي لا توجد بعد في الشجرة. +- **تعقيد الوقت**: تستغرق عمليات البحث والإدخال وقتًا `O(L)`، حيث `L` طول السلسلة. +- **الذاكرة**: قد تكون شجرة Trie غير فعالة إذا كان مجموعة السلاسل تحتوي على العديد من الأحرف الفريدة، لأن ذلك يتطلب تخزين العديد من الأحرف الفريدة كعقد منفصلة. -تأخذ الطوابير والمكدسات في الاعتبار فقط ترتيب الإدخال، بينما تأخذ طوابير الأولوية في الاعتبار أولوية العناصر. +## طوابير الأولوية -تتبع الطوابير العادية مبدأ FIFO (الأول يدخل الأول يخرج) وتتبع المكدسات مبدأ LIFO (الأخير يدخل الأول يخرج). لكن في طابور الأولوية، تُخدم العناصر ذات الأولوية الأعلى قبل الأقل، بغض النظر عن ترتيب الإدخال. +- **طابور الأولوية**: نوع بيانات مجرد حيث لكل عنصر أولوية. +- **الطوابير والمكدسات**: الطوابير والمكدسات تأخذ بعين الاعتبار فقط ترتيب الإدخال، بينما طوابير الأولوية تأخذ بعين الاعتبار أولوية العناصر. الطوابير العادية تتبع FIFO (أول الداخلين أول الخارجين) والمكدسات تتبع LIFO (آخر الداخلين أول الخارجين). +- **ترتيب الإزالة**: عادةً يُزال العنصر ذو الأولوية الأعلى أولًا، لكن بعض التنفيذات قد تختار إزالة العنصر ذو الأولوية الأقل أولًا. +- **التعادل**: إذا كنت تحتاج إلى إزالة العناصر ذات الأولوية نفسها حسب ترتيب إدخالها، يمكنك تضمين عداد فريد لكسر التعادل. +- **التطبيقات**: إيجاد أقصر مسار بين موقعين، جدولة المهام في أنظمة التشغيل، محاكاة المرور، ضغط البيانات، وإدارة الشبكات. ## الحزم -هي هيكل بيانات شجري متخصص له خاصية محددة جدًا تسمى خاصية الحزمة. +الحزمة هي هيكل بيانات شجري متخصص له خاصية محددة جدًا تُسمى خاصية الحزمة. تحدد خاصية الحزمة العلاقة بين عقدة الأصل والعقد الفرعية. هناك نوعان من الحزم: -- الحزمة العظمى - - قيمة كل عقدة أصل أكبر من أو تساوي قيم عقدها الفرعية. - - أكبر عنصر يكون في الجذر. +- **الحزمة العظمى (Max-Heap)**: قيمة كل عقدة أصل أكبر من أو تساوي قيم أبنائها، وأكبر عنصر يكون في الجذر. -- الحزمة الصغرى - - قيمة كل عقدة أصل أقل من أو تساوي قيم عقدها الفرعية. - - أصغر عنصر يكون في الجذر. +- **الحزمة الصغرى (Min-Heap)**: قيمة كل عقدة أصل أقل من أو تساوي قيم أبنائها، وأصغر عنصر يكون في الجذر. لا يحتوي JavaScript على وحدة حزمة مدمجة، لكن يمكنك تنفيذ حزمة صغرى باستخدام مصفوفة. +- **تخزين كمصفوفة**: عادةً ما تُنفذ الحزم كمصفوفات للوصول بكفاءة إلى العقد الأصلية والفرعية. إذا حافظت الحزمة على هيكل شجرة ثنائية كاملة، فإن تنفيذ المصفوفة يتطلب عمليات حسابية بسيطة تعتمد على الفهارس لتحديد موقع العناصر. +- **الفهارس**: للعقدة عند الفهرس `i`، العقدة الأصل عند الفهرس `Math.floor((i - 1) / 2)`, الطفل الأيسر عند الفهرس `2 * i + 1`، والطفل الأيمن عند الفهرس `2 * i + 2`. +- **التفقد**: الحصول على القيمة الصغرى أو العظمى (حسب نوع الحزمة) دون إزالتها. +- **الإضافة**: يضيف عنصرًا في المكان المناسب للحفاظ على خاصية الحزمة. يُضاف العنصر الجديد في نهاية المصفوفة ثم يتحرك لأعلى، متبادلًا الأماكن مع أصله، حتى تُحفظ خاصية الحزمة (الانتفاخ لأعلى). +- **الإزالة**: يزيل العنصر ذو الأولوية الأعلى (في هذه الحالة، القيمة الأصغر). يحل العنصر الأخير في المصفوفة محل الجذر ثم يتحرك لأسفل، متبادلًا الأماكن مع أصغر طفل له، حتى تُحفظ خاصية الحزمة (الانتفاخ لأسفل). +- **الإضافة والإزالة معًا**: يجمع بين العمليتين في استدعاء واحد. هذا أكثر كفاءة من استدعائهما بشكل منفصل، خاصةً عندما تكون الحزمة كبيرة، لأنه ينفذ عملية إعادة ترتيب واحدة فقط. +- **التحويل إلى حزمة (Heapify)**: يحول مصفوفة موجودة إلى حزمة. +- **دالة المقارنة**: لا تُقارن المصفوفات تلقائيًا عنصرًا عنصرًا للترتيب في JavaScript، لذا تمرر دالة مقارنة إلى الحزمة تقارن الأولويات أولًا، مثل `new MinHeap((a, b) => a[0] - b[0])` للعناصر المخزنة كـ `[priority, element]`. القيم الأقل تمثل أولويات أعلى. +- **كسر التعادل المستقر**: تضمين عداد إدخال متزايد كالعنصر الثاني لكل عنصر، مثل: `[priority, counter, element]`. تقارن الأولويات أولًا ثم العدادات عند تساوي الأولويات: `new MinHeap((a, b) => (a[0] - b[0]) || (a[1] - b[1]))`. +- **تعقيد الوقت**: الإدخال والاستخراج للقيمة الصغرى أو العظمى هو `O(log n)`, التفقد هو `O(1)`, التحويل إلى حزمة هو `O(n)`, والبحث أو الحذف لعناصر عشوائية هو `O(n)`. +- **تعقيد المساحة**: `O(n)`, حيث `n` عدد العناصر التي تحتويها الحزمة. + # --assignment-- راجع موضوعات ومفاهيم الرسوم البيانية والأشجار. diff --git a/curriculum/challenges/arabic/blocks/review-graphs-and-trees/67f39e06b8a11b2de9ccd361.md b/curriculum/challenges/arabic/blocks/review-graphs-and-trees/67f39e06b8a11b2de9ccd361.md index 2b933fde5a4..596518056b7 100644 --- a/curriculum/challenges/arabic/blocks/review-graphs-and-trees/67f39e06b8a11b2de9ccd361.md +++ b/curriculum/challenges/arabic/blocks/review-graphs-and-trees/67f39e06b8a11b2de9ccd361.md @@ -9,22 +9,22 @@ dashedName: review-graph-and-trees ## نظرة عامة على الرسوم البيانية -الرسم البياني هو مجموعة من العقد (الرؤوس) متصلة بحواف (وصلات). يمكن لكل عقدة الاتصال بعدة عقد أخرى، مكونة شبكة. تشمل أنواع الرسوم البيانية المختلفة ما يلي: +الرسم البياني هو مجموعة من العقد (الرؤوس) متصلة بحواف (الاتصالات). يمكن لكل عقدة الاتصال بعدة عقد أخرى، مكونة شبكة. أنواع الرسوم البيانية المختلفة تشمل: -- موجه: الحواف لها اتجاه (من عقدة إلى أخرى)، وغالبًا ما تمثل بخطوط مستقيمة وأسهم. -- غير موجه: الحواف بلا اتجاه، وتمثل بخطوط بسيطة. +- موجه: الحواف لها اتجاه (من عقدة إلى أخرى)، غالبًا ما تمثل بخطوط مستقيمة وأسهم. +- غير موجه: الحواف ليس لها اتجاه، تمثل بخطوط بسيطة. - رأس: كل عقدة مرتبطة بمسمى أو معرف. - دوري: يحتوي على دورات (مسار يبدأ وينتهي عند نفس العقدة). - غير دوري (DAG): لا يحتوي على دورات. -- الحواف معنونة: كل حافة لها مسمى يُرسم عادةً بجانب الحافة المقابلة. -- موزون: الحواف لها أوزان (قيم) مرتبطة بها، يمكن استخدامها لأداء العمليات الحسابية. +- ملصق الحافة: كل حافة لها ملصق يُرسم عادة بجانب الحافة المقابلة. +- موزون: الحواف لها أوزان (قيم) مرتبطة بها، يمكن استخدامها لإجراء العمليات الحسابية. - غير متصل: يحتوي على عقدتين أو أكثر غير متصلتين بأي حواف. -تُستخدم الرسوم البيانية في تطبيقات متنوعة مثل الخرائط، الشبكات، أنظمة التوصية، وحل تبعيات. +تُستخدم الرسوم البيانية في تطبيقات مختلفة مثل الخرائط، الشبكات، أنظمة التوصية، وحل التبعيات. -## استعراض الرسوم البيانية +## استعراضات الرسوم البيانية -يتضمن ذلك زيارة جميع العقد في الرسم البياني. الخوارزميات الرئيسية هي: +تشمل زيارة جميع العقد في الرسم البياني. الخوارزميات الرئيسية هي: - **البحث بالاتساع أولاً (BFS)** - يستخدم طابور. @@ -32,37 +32,37 @@ dashedName: review-graph-and-trees - يجد أقصر مسار في الرسوم غير الموزونة. - **البحث بالعمق أولاً (DFS)** - - يستخدم مكدس (أو استدعاء ذاتي). - - يستكشف فرعًا كاملاً قبل التراجع. - - مفيد لاكتشاف الدورات وإيجاد المسارات. + - يستخدم مكدس (أو العودية). + - يستكشف فرعًا بالكامل قبل التراجع. + - مفيد لاكتشاف الدورات والعثور على المسارات. ## تمثيلات الرسوم البيانية يمكن تمثيل الرسوم البيانية بطريقتين رئيسيتين: -- **قائمة الجوار** - - لكل عقدة قائمة بجيرانها. - - فعالة في استخدام المساحة للرسوم المتفرقة. - - سهلة التكرار على الجيران. +- **قائمة المجاورة** + - تحتوي كل عقدة على قائمة بجيرانها. + - فعالة من حيث المساحة للرسوم البيانية المتفرقة. + - سهلة للتكرار على الجيران. - **المصفوفة المجاورة** - - مصفوفة ثنائية الأبعاد تمثل الصفوف والأعمدة العقد. - - تستهلك مساحة كبيرة للرسوم الكبيرة. - - سريعة في التحقق من وجود حافة بين عقدتين. + - مصفوفة ثنائية الأبعاد حيث تمثل الصفوف والأعمدة العقد. + - تستهلك مساحة كبيرة للرسوم البيانية الكبيرة. + - سريعة للتحقق مما إذا كان هناك حافة بين عقدتين. ## الأشجار -الشجرة نوع خاص من الرسوم البيانية يكون غير دوري ومتصل. الخصائص الرئيسية تشمل: +الشجرة نوع خاص من الرسوم البيانية التي لا تحتوي على دورات ومتصلة. الخصائص الرئيسية تشمل: - لا تحتوي على حلقات أو دورات (مسارات يبدأ وينتهي عند نفس العقدة). - يجب أن تكون متصلة (يمكن الوصول إلى كل عقدة من أي عقدة أخرى). -### أنواع الأشجار الشائعة +### الأنواع الشائعة من الأشجار -أنواع الأشجار الأكثر شيوعًا هي: +الأنواع الأكثر شيوعًا من الأشجار هي: - الأشجار الثنائية - - لكل عقدة طفلان كحد أقصى، طفل أيسر وطفل أيمن. + - تحتوي كل عقدة على طفلين كحد أقصى، طفل أيسر وطفل أيمن. - شجرة البحث الثنائي (BST) - شجرة ثنائية حيث كل طفل أيسر أقل من عقدة الأصل، وكل طفل أيمن أكبر من عقدة الأصل. @@ -72,21 +72,21 @@ dashedName: review-graph-and-trees تُعرف أيضًا بأشجار البادئة، تُستخدم لتخزين مجموعات من السلاسل النصية، حيث تمثل كل عقدة حرفًا. -يتم تخزين البادئات المشتركة مرة واحدة فقط، مما يجعلها فعالة في مهام مثل الإكمال التلقائي وتصحيح الإملاء. +يتم تخزين البادئات المشتركة مرة واحدة فقط، مما يجعلها فعالة لمهام مثل الإكمال التلقائي وفحص الإملاء. -عمليات البحث والإدخال لها تعقيد زمني O(L)، حيث L هو طول السلسلة النصية. +عمليات البحث والإدخال لها تعقيد زمني قدره O(L)، حيث L هو طول السلسلة النصية. ## طوابير الأولوية -طابور الأولوية هو نوع بيانات مجرد حيث لكل عنصر أولوية. +طابور الأولوية هو نوع مجرد من هياكل البيانات حيث لكل عنصر أولوية. -تأخذ الطوابير والمكدسات بعين الاعتبار فقط ترتيب الإدخال، بينما تأخذ طوابير الأولوية بعين الاعتبار أولوية العناصر. +تأخذ الطوابير والمكدسات في الاعتبار فقط ترتيب الإدخال، بينما تأخذ طوابير الأولوية في الاعتبار أولوية العناصر. -تتبع الطوابير العادية مبدأ FIFO (الأول يدخل هو الأول يخرج) وتتبع المكدسات مبدأ LIFO (الأخير يدخل هو الأول يخرج). لكن في طابور الأولوية، تُخدم العناصر ذات الأولوية الأعلى قبل ذات الأولوية الأقل، بغض النظر عن ترتيب الإدخال. +تتبع الطوابير القياسية مبدأ FIFO (الأول في الدخول، الأول في الخروج) وتتبع المكدسات مبدأ LIFO (الأخير في الدخول، الأول في الخروج). لكن في طابور الأولوية، تُخدم العناصر ذات الأولوية الأعلى قبل تلك ذات الأولوية الأقل، بغض النظر عن ترتيب إدخالها. ## الحزم -هي هيكل بيانات شجري متخصص له خاصية محددة جدًا تسمى خاصية الحزمة. +هيكل بيانات شجري متخصص له خاصية محددة جدًا تسمى خاصية الحزمة. تحدد خاصية الحزمة العلاقة بين عقدة الأصل والعقد الفرعية. هناك نوعان من الحزم: diff --git a/curriculum/challenges/arabic/blocks/review-http-and-the-web-standards-model/6a02da945706a3ddc2e44348.md b/curriculum/challenges/arabic/blocks/review-http-and-the-web-standards-model/6a02da945706a3ddc2e44348.md index 2f9a60415fa..0f3f0a4e628 100644 --- a/curriculum/challenges/arabic/blocks/review-http-and-the-web-standards-model/6a02da945706a3ddc2e44348.md +++ b/curriculum/challenges/arabic/blocks/review-http-and-the-web-standards-model/6a02da945706a3ddc2e44348.md @@ -40,7 +40,7 @@ dashedName: review-http-and-the-web-standards-model 4. يعيد خادم الأسماء المخول **سجل DNS** يحتوي على عنوان IP. 5. يسلم المُحلل التكراري عنوان IP إلى العميل ويُخزن السجل مؤقتًا لتسريع عمليات البحث المستقبلية. -## TCP/IP +## بروتوكول التحكم بالنقل/بروتوكول الإنترنت (TCP/IP) - **البروتوكول**: مجموعة قواعد ومعايير تسمح للأجهزة بالتواصل عبر الشبكة. - **TCP/IP**: مجموعة بروتوكولات تحدد كيفية تغليف البيانات وإرسالها وتوجيهها واستقبالها. @@ -154,7 +154,7 @@ Connection: keep-alive | --- | --- | | HTML | `text/html` | | CSS | `text/css` | -| JavaScript | `application/javascript` | +| JavaScript | `text/javascript` | | JSON | `application/json` | | XML | `application/xml` | | JPEG | `image/jpeg` | diff --git a/curriculum/challenges/arabic/blocks/review-python-basics/67f39b40deaec81a3e40e0c5.md b/curriculum/challenges/arabic/blocks/review-python-basics/67f39b40deaec81a3e40e0c5.md index 0afc6a6f245..5a3dc2a218f 100644 --- a/curriculum/challenges/arabic/blocks/review-python-basics/67f39b40deaec81a3e40e0c5.md +++ b/curriculum/challenges/arabic/blocks/review-python-basics/67f39b40deaec81a3e40e0c5.md @@ -7,10 +7,10 @@ dashedName: review-python-basics # --description-- -## ما هي بايثون؟ +## ما هو بايثون؟ -- **مقدمة**: بايثون هي لغة برمجة عامة الغرض معروفة ببساطتها وسهولة استخدامها. تُستخدم بايثون في مجالات عديدة مثل علم البيانات وتعلم الآلة، تطوير الويب، البرمجة النصية والأتمتة، الأنظمة المدمجة وإنترنت الأشياء، وأكثر من ذلك. -- **حالات الاستخدام الشائعة**: تُستخدم بايثون في علم البيانات، تعلم الآلة، تطوير الويب، الأمن السيبراني، الأتمتة، وأجهزة الحاسوب الصغيرة مثل Raspberry Pi واللوحات المتوافقة مع MicroPython. +- **مقدمة**: بايثون هي لغة برمجة عامة الغرض معروفة ببساطتها وسهولة استخدامها. +- **الاستخدامات الشائعة**: تُستخدم بايثون في علم البيانات، تعلم الآلة، تطوير الويب، الأمن السيبراني، الأنظمة المدمجة وإنترنت الأشياء، البرمجة النصية، الأتمتة، وأجهزة الحاسوب الصغيرة مثل Raspberry Pi واللوحات المتوافقة مع MicroPython. ## المتغيرات @@ -23,16 +23,18 @@ age = 25 - **اصطلاحات تسمية المتغيرات**: إليك الاصطلاحات التي يجب استخدامها لتسمية المتغيرات: - - أسماء المتغيرات يمكن أن تبدأ فقط بحرف أو بشرطة سفلية (_) وليس برقم. - - أسماء المتغيرات يمكن أن تحتوي فقط على أحرف أبجدية رقمية (a-z, A-Z, 0-9) والشرطة السفلية (_). - - أسماء المتغيرات حساسة لحالة الأحرف — `age`، `Age`، و`AGE` تعتبر أسماء مختلفة. - - لا يمكن أن تكون أسماء المتغيرات من الكلمات المفتاحية المحجوزة في Python مثل `if`، `class`، أو `def`. - - أسماء المتغيرات متعددة الكلمات تُفصل بالشرطة السفلية. مثال: `snake_case`. + - يجب أن تبدأ أسماء المتغيرات بحرف أو بشرطة سفلية (`_`) فقط، وليس برقم. + - يمكن أن تحتوي أسماء المتغيرات على أحرف أبجدية رقمية (`a-z`، `A-Z`، `0-9`) والشرطات السفلية (`_`) فقط. + - أسماء المتغيرات حساسة لحالة الأحرف: `age`، `Age`، و`AGE` تُعتبر أسماء مختلفة. + - لا يمكن أن تكون أسماء المتغيرات من الكلمات المفتاحية المحجوزة في بايثون مثل `if`، `class`، أو `def`. + - تستخدم أسماء المتغيرات متعددة الكلمات الشرطات السفلية، كما في `snake_case`. + - يجب أن تصف أسماء المتغيرات غرضها، كما في `user_age`. + - يُفضل تجنب أسماء المتغيرات ذات الحرف الواحد إذا لم تكن توصل معنى. ## التعليقات -- **تعليقات السطر الواحد**: يجب استخدام هذه الأنواع من التعليقات للملاحظات القصيرة التي ترغب في تركها داخل الكود. +- **التعليقات ذات السطر الواحد**: يُستخدم هذا النوع من التعليقات للملاحظات القصيرة في الكود الخاص بك. ```py # This is a single line comment @@ -184,7 +186,7 @@ developer = 'Jessica' print(len(developer)) # 7 ``` -## العمل مع معامل `in` +## العمل مع العامل `in` - **معامل `in`**: يُرجع قيمة منطقية تحدد ما إذا كان الحرف أو الأحرف موجودة في السلسلة النصية أم لا: @@ -327,7 +329,7 @@ result = 'abcabc'.translate(trans_table) print(result) # 123123 ``` -## العمليات الشائعة مع الأعداد الصحيحة والعشرية +## العمليات الشائعة المستخدمة مع الأعداد الصحيحة والأعداد العشرية - **العمليات الحسابية الأساسية**: في بايثون، يمكنك إجراء عمليات حسابية أساسية مع الأعداد الصحيحة والعشرية مثل الجمع، الطرح، الضرب، والقسمة: @@ -402,7 +404,7 @@ num = 4 print(float(num)) # 4.0 ``` -- **الدالة `int()`**: يمكنك استخدام هذه الدالة لتحويل عدد عشري إلى عدد صحيح. +- **دالة `int()`**: يمكنك استخدام هذه الدالة لتحويل عدد عشري إلى عدد صحيح. ```py num = 4.0 @@ -610,7 +612,7 @@ print(3 <= 4) # True ## العمل مع عبارات `if`، `elif` و`else` -- **عبارات `if`**: هذه شروط تُستخدم لتحديد ما إذا كان شيء ما صحيحًا أم لا. إذا قُيّم الشرط إلى `True`، فسيتم تنفيذ ذلك الجزء من الكود. +- **عبارات `if`**: هذه شروط تُستخدم لتحديد ما إذا كان شيء ما صحيحًا أم لا. إذا قُيّمت الشرط إلى `True`، فسيتم تنفيذ ذلك الجزء من الكود. ```py age = 18 @@ -684,10 +686,10 @@ print(bool(1)) # True print(bool('Hello')) # True ``` -## عوامل القيم المنطقية والقطع المبكر (Short-circuiting) +## العوامل المنطقية والاختصار في التقييم - **التعريف**: هذه عوامل خاصة تسمح لك بدمج عدة تعبيرات لإنشاء منطق اتخاذ قرار أكثر تعقيدًا في كودك. هناك ثلاثة عوامل منطقية في Python: `and`، و`or`، و`not`. -- **عامل `and`**: يأخذ هذا العامل معاملين ويُرجع المعامل الأول إذا كان قيمة منطقية خاطئة، وإلا فإنه يُرجع المعامل الثاني. يجب أن يكون كلا المعاملين قيمتين صحيحتين لكي ينتج التعبير قيمة صحيحة. +- **عامل `and`**: يأخذ هذا العامل معاملين ويُرجع المعامل الأول إذا كان قيمة منطقية خاطئة (falsy)، وإلا فإنه يُرجع المعامل الثاني. يجب أن يكون كلا المعاملين قيمتين صحيحتين (truthy) لكي تكون نتيجة التعبير قيمة صحيحة. ```py is_citizen = True diff --git a/curriculum/challenges/arabic/blocks/rosetta-code-challenges/598eea87e5cf4b116c3ff81a.md b/curriculum/challenges/arabic/blocks/rosetta-code-challenges/598eea87e5cf4b116c3ff81a.md index 514939eb63d..b0ae586884e 100644 --- a/curriculum/challenges/arabic/blocks/rosetta-code-challenges/598eea87e5cf4b116c3ff81a.md +++ b/curriculum/challenges/arabic/blocks/rosetta-code-challenges/598eea87e5cf4b116c3ff81a.md @@ -22,9 +22,9 @@ dashedName: factors-of-a-mersenne-number على سبيل المثال، لنحسب 223 mod 47. -حوّل الأس 23 إلى ثنائي، ستحصل على 10111. بدءًا من square = 1، قم بتربيعها مرارًا. +حوّل الأس 23 إلى النظام الثنائي، ستحصل على 10111. ابدأ بـ square = 1، وكرر تربيعه. -أزل أعلى بت من الأس، وإذا كان 1 اضرب `square` في أساس الأس (2)، ثم احسب square modulo 47. +احذف أعلى بت من الأس، وإذا كان 1 اضرب `square` في أساس الأس (2)، ثم احسب square باقي القسمة 47. استخدم نتيجة باقي القسمة من الخطوة السابقة كقيمة ابتدائية لـ `square` في الخطوة التالية: diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c675b599baa7b103192d.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c675b599baa7b103192d.md index e01f1e97c57..1f936fc9b33 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c675b599baa7b103192d.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c675b599baa7b103192d.md @@ -39,7 +39,7 @@ assert.isTrue(high?.value.matches("searchList.length - 1")); ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; --fcc-editable-region-- --fcc-editable-region-- diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c7363a4a437839f1f15d.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c7363a4a437839f1f15d.md index 55cd32541ba..e466e556581 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c7363a4a437839f1f15d.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c7363a4a437839f1f15d.md @@ -34,7 +34,7 @@ assert.match(codeWithoutComments, /while\s*\(\s*low\s*<=\s*high\s*\)/); ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c796385b6ea4e222d5e8.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c796385b6ea4e222d5e8.md index 4023f8c7e2b..d22b5c91d01 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c796385b6ea4e222d5e8.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c796385b6ea4e222d5e8.md @@ -30,7 +30,7 @@ assert.match( ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c8375f4301004459ee85.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c8375f4301004459ee85.md index cc9c22cf639..59445390412 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c8375f4301004459ee85.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c8375f4301004459ee85.md @@ -31,12 +31,12 @@ assert.match( ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); + const mid = Math.floor((low + high) / 2); --fcc-editable-region-- --fcc-editable-region-- diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c8f94fe6b250f11a2a1e.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c8f94fe6b250f11a2a1e.md index d9df8cbb14f..2fa3f5a5cb8 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c8f94fe6b250f11a2a1e.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c8f94fe6b250f11a2a1e.md @@ -29,13 +29,13 @@ assert.match( ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; --fcc-editable-region-- --fcc-editable-region-- diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c95e5bede03bdf2937a2.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c95e5bede03bdf2937a2.md index d22c8084390..39a76d98791 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c95e5bede03bdf2937a2.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996c95e5bede03bdf2937a2.md @@ -43,13 +43,13 @@ assert.match( ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; pathToTarget.push(valueAtMiddle); --fcc-editable-region-- diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996ca21a74104721f2c7e5d.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996ca21a74104721f2c7e5d.md index 92f991d0518..249e0a78fe5 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996ca21a74104721f2c7e5d.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996ca21a74104721f2c7e5d.md @@ -39,13 +39,13 @@ assert.deepEqual(binarySearch([], NaN), []); ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; pathToTarget.push(valueAtMiddle); if (value === valueAtMiddle) { diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cb5869acf58de751ae81.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cb5869acf58de751ae81.md index aba05a4474f..d146f3859b4 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cb5869acf58de751ae81.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cb5869acf58de751ae81.md @@ -35,13 +35,13 @@ assert.include(strippedCode, expectedStatement); ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; pathToTarget.push(valueAtMiddle); if (value === valueAtMiddle) { diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996ccadf9048c79b857bb15.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996ccadf9048c79b857bb15.md index 4b94cd9dff4..703283ef22a 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996ccadf9048c79b857bb15.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996ccadf9048c79b857bb15.md @@ -1,54 +1,54 @@ ---- -id: 6996ccadf9048c79b857bb15 +--- +id: 6996ccadf9048c79b857bb15 title: الخطوة 11 -challengeType: 1 -dashedName: step-11 ---- - -# --description-- - +challengeType: 1 +dashedName: step-11 +--- + +# --description-- + يمكنك أن ترى أن الاستدعاء الأول يُرجع `[3]`. ذلك لأن `3` هو القيمة الوسطى في `[1, 2, 3, 4, 5]`. - + من ناحية أخرى، الاستدعاء الثاني يُرجع مصفوفة فارغة. يحدث هذا لأن الحلقة بعد التحقق من القيمة الوسطى تفتقر حاليًا إلى المنطق الذي يضيق نطاق البحث بتحديث المتغيرين `low` أو `high`. هي فقط تقوم بفحص نقطة منتصف واحدة ثم تنتهي دون متابعة البحث. - + للسماح لخوارزمية البحث الثنائي بمواصلة تضييق نطاق البحث، أضف جملة `else if` تتحقق مما إذا كانت `value` أكبر من `valueAtMiddle`. - -# --hints-- - + +# --hints-- + يجب أن تضيف جملة `else if` بشرط `value > valueAtMiddle`. - -```js -assert.match( - __helpers.removeJSComments(String(binarySearch)), - /else\s+if\s*\(\s*value\s*>\s*valueAtMiddle\s*\)/ -); -``` - -# --seed-- - -## --seed-contents-- - -```js -function binarySearch(searchList, value) { - let pathToTarget = []; - let low = 0; - let high = searchList.length - 1; - - while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; - pathToTarget.push(valueAtMiddle); - - if (value === valueAtMiddle) { - return pathToTarget; ---fcc-editable-region-- - } ---fcc-editable-region-- - break; - } - return []; -} - -console.log(binarySearch([1, 2, 3, 4, 5], 3)); -console.log(binarySearch([1, 2, 3, 4, 5, 9], 4)); -``` + +```js +assert.match( + __helpers.removeJSComments(String(binarySearch)), + /else\s+if\s*\(\s*value\s*>\s*valueAtMiddle\s*\)/ +); +``` + +# --seed-- + +## --seed-contents-- + +```js +function binarySearch(searchList, value) { + const pathToTarget = []; + let low = 0; + let high = searchList.length - 1; + + while (low <= high) { + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; + pathToTarget.push(valueAtMiddle); + + if (value === valueAtMiddle) { + return pathToTarget; +--fcc-editable-region-- + } +--fcc-editable-region-- + break; + } + return []; +} + +console.log(binarySearch([1, 2, 3, 4, 5], 3)); +console.log(binarySearch([1, 2, 3, 4, 5, 9], 4)); +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cdf1f60cbc30eeeae1c9.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cdf1f60cbc30eeeae1c9.md index 8adab5fff16..d5c9dbd7011 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cdf1f60cbc30eeeae1c9.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cdf1f60cbc30eeeae1c9.md @@ -25,13 +25,13 @@ assert.match(__helpers.removeJSComments(String(binarySearch)), /low\s*=\s*mid\s* ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; pathToTarget.push(valueAtMiddle); if (value === valueAtMiddle) { diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cfb6c01e9a802add38be.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cfb6c01e9a802add38be.md index 4845aa4429d..0ea2b87cf9f 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cfb6c01e9a802add38be.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996cfb6c01e9a802add38be.md @@ -32,13 +32,13 @@ assert.notMatch(codeWithoutComments, /\bbreak\b/); ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; pathToTarget.push(valueAtMiddle); if (value === valueAtMiddle) { diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d0a2c2ac55041145a13f.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d0a2c2ac55041145a13f.md index 93a2babda32..02c6e69dff1 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d0a2c2ac55041145a13f.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d0a2c2ac55041145a13f.md @@ -29,13 +29,13 @@ assert.include(strippedCode, expectedStatement); ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; pathToTarget.push(valueAtMiddle); if (value === valueAtMiddle) { diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d1032feed88e2957dc8e.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d1032feed88e2957dc8e.md index 0f320379a6b..5aa621adb78 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d1032feed88e2957dc8e.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d1032feed88e2957dc8e.md @@ -30,13 +30,13 @@ assert.isTrue(validExpressions.some(expr => binarySearch?.hasReturn(expr) || bin ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; pathToTarget.push(valueAtMiddle); if (value === valueAtMiddle) { diff --git a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d18b31aab5cbbffbc731.md b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d18b31aab5cbbffbc731.md index 321904092b4..099bb9b4c21 100644 --- a/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d18b31aab5cbbffbc731.md +++ b/curriculum/challenges/arabic/blocks/workshop-binary-search-js/6996d18b31aab5cbbffbc731.md @@ -47,13 +47,13 @@ assert.deepEqual( ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; pathToTarget.push(valueAtMiddle); if (value === valueAtMiddle) { @@ -78,13 +78,13 @@ console.log(binarySearch([1, 3, 5, 9, 14, 22], 10)); ```js function binarySearch(searchList, value) { - let pathToTarget = []; + const pathToTarget = []; let low = 0; let high = searchList.length - 1; while (low <= high) { - let mid = Math.floor((low + high) / 2); - let valueAtMiddle = searchList[mid]; + const mid = Math.floor((low + high) / 2); + const valueAtMiddle = searchList[mid]; pathToTarget.push(valueAtMiddle); if (value === valueAtMiddle) { diff --git a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6810891bd6de8a87a833df42.md b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6810891bd6de8a87a833df42.md index 634582ade63..a2782b62635 100644 --- a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6810891bd6de8a87a833df42.md +++ b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6810891bd6de8a87a833df42.md @@ -7,7 +7,7 @@ dashedName: step-10 # --description-- -كما ترى من المخرجات، تم تشفير الرسالة. الخطوة التالية هي جعل كودك قابلًا لإعادة الاستخدام في حال أردت تشفير رسائل مختلفة. +كما ترى من المخرجات، تم تشفير الرسالة. بعد ذلك، ستجعل كودك قابلًا لإعادة الاستخدام ليتمكن من تشفير رسائل مختلفة. لهذا، ستحتاج إلى إنشاء دالة. كتذكير، إليك كيفية إنشاء دالة باسم `spam` تقوم بطباعة `Spam!` على الطرفية: @@ -26,7 +26,7 @@ def spam(): ({ test: () => assert(runPython(`_Node(_code).has_function("caesar")`)) }) ``` -يجب أن تنقل كل الكود الذي كتبته حتى الآن داخل جسم دالة `caesar`. تأكد من الحفاظ على نفس مستوى التراجع لكل الأسطر داخل جسم الدالة... +يجب أن تنقل كل الكود الذي كتبته حتى الآن داخل جسم الدالة `caesar`. تأكد من الحفاظ على نفس مستوى التراجع لكل الأسطر داخل جسم الدالة. ```js ({ test: () => assert(runPython(`_Node(_code).find_function("caesar").find_body().is_equivalent("alphabet = 'abcdefghijklmnopqrstuvwxyz'\\nshift = 5\\nshifted_alphabet = alphabet[shift:] + alphabet[:shift]\\ntranslation_table = str.maketrans(alphabet, shifted_alphabet)\\ntext = 'hello world'\\nencrypted_text = text.translate(translation_table)\\nprint(encrypted_text)")`)) }) diff --git a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6818ed1adc249bb91d373729.md b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6818ed1adc249bb91d373729.md index 06b7683bd39..6d7edaf9afd 100644 --- a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6818ed1adc249bb91d373729.md +++ b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6818ed1adc249bb91d373729.md @@ -14,7 +14,7 @@ def spam(): return 'Spam!' ``` -احذف استدعاء `print(encrypted_text)` من دالتك. ثم احذف إعلان المتغير `encrypted_text` وأرجع مباشرةً `text.translate(translation_table)` من دالتك. +احذف استدعاء `print(encrypted_text)` من دالتك. ثم احذف إعلان المتغير `encrypted_text` وأعد مباشرةً `text.translate(translation_table)` من دالتك. # --hints-- diff --git a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6818fcb250f34e62cab32c39.md b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6818fcb250f34e62cab32c39.md index ba1238573c6..bc16b54c7a1 100644 --- a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6818fcb250f34e62cab32c39.md +++ b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/6818fcb250f34e62cab32c39.md @@ -12,7 +12,7 @@ dashedName: step-15 لإصلاح ذلك، عليك تعديل السلاسل النصية الممررة إلى استدعاء `str.maketrans()` باستخدام الطريقة `upper()`: ```py -greet = "Hello" +greet = 'Hello' print(greet.upper()) # HELLO ``` @@ -23,7 +23,13 @@ print(greet.upper()) # HELLO يجب تعديل المعلمات في استدعاء `str.maketrans()` بضم النسخة الكبيرة من كل معلمة إلى المعلمة نفسها. ```js -({ test: () => assert(runPython(`caesar('This Is A TEST', 5) == 'Ymnx Nx F YJXY'`)) }) +({ test: () => runPython(` +_table = _Node(_code).find_function("caesar").find_variable("translation_table") +_first = _table.is_equivalent("translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())") +_second = _table.is_equivalent("translation_table = str.maketrans(alphabet.upper() + alphabet, shifted_alphabet.upper() + shifted_alphabet)") +assert _first or _second +assert caesar('This Is A TEST', 5) == 'Ymnx Nx F YJXY' +`) }) ``` # --seed-- diff --git a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/681a2a6cf95e82ca30866364.md b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/681a2a6cf95e82ca30866364.md index fc06972b80b..6371773a345 100644 --- a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/681a2a6cf95e82ca30866364.md +++ b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/681a2a6cf95e82ca30866364.md @@ -9,9 +9,9 @@ dashedName: step-23 أعلن دالتين باسم `encrypt` و `decrypt`، كلتاهما تحتويان على معلمتين `text` و `shift`. -استخدم `encrypt` لعملية التشفير، و `decrypt` لفك التشفير، مع تسمية كلتا العمليتين بمسمى وصفي. +ستستخدم `encrypt` للتشفير و`decrypt` لفك التشفير، مع إعطاء كل إجراء اسمًا وصفيًا. -أرجع استدعاء `caesar` مع تمرير `text` و `shift` من كلا الدالتين الجديدتين، لكن تأكد من تمرير `False` كالمعلمة الثالثة في دالة `decrypt`. +من الدالتين الجديدتين، أرجع استدعاء `caesar` الذي يمرر `text` و`shift`. في `decrypt`، مرر أيضًا `False` كالمعلمة الثالثة. # --hints-- diff --git a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/681a44f4c3235f7d8f428545.md b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/681a44f4c3235f7d8f428545.md index 5282e8b6f68..4370daea830 100644 --- a/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/681a44f4c3235f7d8f428545.md +++ b/curriculum/challenges/arabic/blocks/workshop-caesar-cipher/681a44f4c3235f7d8f428545.md @@ -9,7 +9,7 @@ dashedName: step-25 الآن ستختبر الدالة `decrypt`. استبدل القيمة المُعيَّنة إلى `encrypted_text` بالسلسلة النصية التالية، التي تمثل رسالة لفك تشفيرها: `Pbhentr vf sbhaq va hayvxryl cynprf.` -بعد ذلك، أعلن عن متغير باسم `decrypted_text` وعيّن له استدعاء الدالة `decrypt` مع `encrypted_text` كمعامل أول وتحويل بمقدار `13` كمعامل ثاني. +بعد ذلك، أعلن متغيرًا باسم `decrypted_text` وعيّن له استدعاءً للدالة `decrypt` مع `encrypted_text` كمعلمتها الأولى وتحويل بمقدار `13` كمعلمتها الثانية. أخيرًا، اطبع `decrypted_text` على الطرفية. بذلك، يكتمل تشفير قيصر. diff --git a/curriculum/challenges/arabic/blocks/workshop-email-simulator/6853f4584f508e95cc7a9f4d.md b/curriculum/challenges/arabic/blocks/workshop-email-simulator/6853f4584f508e95cc7a9f4d.md index 3fca1d12f88..3283db8a68d 100644 --- a/curriculum/challenges/arabic/blocks/workshop-email-simulator/6853f4584f508e95cc7a9f4d.md +++ b/curriculum/challenges/arabic/blocks/workshop-email-simulator/6853f4584f508e95cc7a9f4d.md @@ -24,13 +24,21 @@ dashedName: step-30 }) ``` -يجب أن تتحقق مما إذا كانت `self.emails` فارغة باستخدام `if not self.emails`. +يجب التحقق مما إذا كانت `self.emails` فارغة. ```js ({ test: () => { - assert(runPython(`_Node(_code).find_class("Inbox").find_function("list_emails").find_ifs()[0].find_conditions()[0].is_equivalent("not self.emails")`)) + runPython(` + condition = _Node(_code).find_class("Inbox").find_function("list_emails").find_ifs()[0].find_conditions()[0] + + assert( + condition.is_equivalent("not self.emails") or + condition.is_equivalent("len(self.emails) == 0") or + condition.is_equivalent("self.emails == []") + ) + `) } }) ``` diff --git a/curriculum/challenges/arabic/blocks/workshop-email-simulator/685cdfd1932d8ac6ad986813.md b/curriculum/challenges/arabic/blocks/workshop-email-simulator/685cdfd1932d8ac6ad986813.md index 7bf19b36f77..fd1ebbf7f84 100644 --- a/curriculum/challenges/arabic/blocks/workshop-email-simulator/685cdfd1932d8ac6ad986813.md +++ b/curriculum/challenges/arabic/blocks/workshop-email-simulator/685cdfd1932d8ac6ad986813.md @@ -11,14 +11,14 @@ dashedName: step-28 تسمح التعبيرات الشرطية بتعيين قيمة بناءً على شرط في سطر واحد. -إليك مثالاً: +إليك مثال: ```py x = 10 y = 'Even' if x % 2 == 0 else 'Odd' # y will be Even ``` -داخل الطريقة، استخدم التعبير الشرطي لتعيين السلسلة النصية `Read` إلى المتغير `status` إذا كان البريد الإلكتروني مقروءًا و`Unread` إذا لم يكن كذلك. +داخل الطريقة، استخدم تعبيرًا شرطيًا لتعيين السلسلة النصية `Read` إلى متغير اسمه `status` إذا كان البريد الإلكتروني مقروءًا و`Unread` إذا لم يكن كذلك. # --hints-- diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md new file mode 100644 index 00000000000..754b118e6e1 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69de4308e652aaeb5ccdb03e.md @@ -0,0 +1,40 @@ +--- +id: 69de4308e652aaeb5ccdb03e +title: الخطوة 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +في هذه الورشة، ستتمرن على العمل مع طرق السلاسل النصية في Python. + +ابدأ بإنشاء متغير باسم `email` وقم بتعيين السلسلة النصية `alice.johnson@company.com` له. + +# --hints-- + +يجب إنشاء متغير باسم `email`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('email') +`) }) +``` + +يجب تعيين السلسلة النصية `alice.johnson@company.com` إلى `email`. تذكر أن تحيط النص إما بعلامات اقتباس مفردة أو علامات اقتباس مزدوجة. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('email').is_equivalent("email = 'alice.johnson@company.com'") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md new file mode 100644 index 00000000000..21cfbb700a2 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e20876baed33de636b989a.md @@ -0,0 +1,66 @@ +--- +id: 69e20876baed33de636b989a +title: الخطوة 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +أحيانًا، قد تريد إيجاد موقع حرف معين داخل سلسلة نصية. يوفر Python الطريقة المدمجة `.find()` لهذا الغرض. تُرجع عددًا صحيحًا يمثل الفهرس (الموقع) لأول ظهور للسلسلة الفرعية المعطاة. + +إليك مثالاً: + +```py +text = 'hello' +print(text.find('e')) # 1 +``` + +الآن، استدعِ الطريقة `.find()` على `email` ومرر لها `'@'` لإيجاد موقع علامة @ في سلسلة `email`. عيّن النتيجة في متغير اسمه `at_position`. + +ثم اطبع `at_position` بحيث يكون الناتج: `Position of @: 13`. + +# --hints-- + +يجب إنشاء متغير اسمه `at_position`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('at_position') +`) }) +``` + +يجب تعيين `at_position` القيمة `email.find('@')`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('at_position').is_equivalent("at_position = email.find('@')") +`) }) +``` + +يجب طباعة `at_position` بحيث يكون الناتج `Position of @: 13`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Position of @: {at_position}')", + "print('Position of @: ' + str(at_position))", + "print('Position of @:', at_position)", + "print('Position of @:', str(at_position))", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md new file mode 100644 index 00000000000..a527c7f69b3 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e20a0451c7a3ef189514d3.md @@ -0,0 +1,70 @@ +--- +id: 69e20a0451c7a3ef189514d3 +title: الخطوة 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +بما أنك تعرف موقع `@` في البريد الإلكتروني، يمكنك استخراج اسم المستخدم الموضوع قبل علامة `@`. + +في ورشة العمل السابقة، استخرجت جزءًا من سلسلة نصية باستخدام التقطيع. للتذكير، الصيغة النحوية هي: + +```python +text = 'hello world' +print(text[:5]) # hello +``` + +استخدم التقطيع على `email` لاستخراج كل شيء قبل `at_position`، وخزن النتيجة في متغير اسمه `username`. + +ثم اطبع `username` بحيث يظهر الإخراج كالتالي: `Username: alice.johnson`. + +# --hints-- + +يجب إنشاء متغير اسمه `username`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('username') +`) }) +``` + +يجب استخدام التقطيع مع `at_position` على `email` لتعيين قيمة لـ `username`. + +```js +({ test: () => runPython(` +node = _Node(_code).find_variable('username') +assert node.is_equivalent("username = email[:at_position]") or node.is_equivalent("username = email[0:at_position]") +`) }) +``` + +يجب طباعة `username` بحيث يظهر الإخراج كالتالي: `Username: alice.johnson`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Username: {username}')", + "print('Username: ' + username)", + "print('Username:', username)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md new file mode 100644 index 00000000000..3101afa3fee --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e6284f3b7659c5a05c2a79.md @@ -0,0 +1,72 @@ +--- +id: 69e6284f3b7659c5a05c2a79 +title: الخطوة 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +يمكنك التحقق مما إذا كانت سلسلة نصية فرعية موجودة داخل سلسلة نصية باستخدام الكلمة المفتاحية `in`. تُرجع `True` إذا كانت السلسلة الفرعية موجودة و`False` إذا لم تكن كذلك. إليك مثالًا: + +```py +sentence = 'I love Python' +print('Python' in sentence) # True +print('Java' in sentence) # False +``` + +أنشئ متغيرًا باسم `has_at` يتحقق مما إذا كان الحرف `@` موجودًا في `email`. + +ثم اطبع `has_at` بحيث تكون النتيجة: `Has @ symbol: True`. + +# --hints-- + +يجب أن تنشئ متغيرًا باسم `has_at`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('has_at') +`) }) +``` + +يجب أن يحتوي متغير `has_at` على القيمة `'@' in email`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('has_at').is_equivalent("has_at = '@' in email") +`) }) +``` + +يجب أن تطبع `has_at` بحيث تكون النتيجة `Has @ symbol: True`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Has @ symbol: {has_at}')", + "print('Has @ symbol: ' + str(has_at))", + "print('Has @ symbol:', has_at)", + "print('Has @ symbol:', str(has_at))", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md new file mode 100644 index 00000000000..409eb23b1bc --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e6299710319e7cb8ebdc37.md @@ -0,0 +1,75 @@ +--- +id: 69e6299710319e7cb8ebdc37 +title: الخطوة 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +غالبًا ما تكون البيانات الواقعية غير مرتبة مع مسافات إضافية وأحرف بحالة غير متناسقة. + +أنشئ متغيرًا باسم `messy_name` وقم بتعيين السلسلة النصية `sARaH dAVis` له مع مسافتين في البداية ومسافتين في النهاية. ثم اطبع المتغير بحيث يكون الناتج: + +```md +Original name: ' sARaH dAVis ' +``` + +ستقوم بتنظيف هذا في الخطوات القادمة. + +# --hints-- + +يجب أن تنشئ متغيرًا باسم `messy_name`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('messy_name') +`) }) +``` + +يجب أن تعيّن '  sARaH dAVis  ' إلى `messy_name`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('messy_name').is_equivalent("messy_name = ' sARaH dAVis '") +`) }) +``` + +يجب أن تطبع `messy_name` بحيث يكون الناتج `Original name: ' sARaH dAVis '`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f\\"Original name: '{messy_name}'\\")", + "print(\\"Original name: '\\" + messy_name + \\"'\\")", + "print(\\"Original name: '\\", messy_name, \\"'\\", sep='')", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md new file mode 100644 index 00000000000..825c380705c --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e62ce96df237884da25282.md @@ -0,0 +1,128 @@ +--- +id: 69e62ce96df237884da25282 +title: الخطوة 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +تُحوّل الطريقة `.lower()` كل الأحرف في سلسلة نصية إلى أحرف صغيرة. هذا مفيد لتوحيد عناوين البريد الإلكتروني: + +```python +upperGreet = 'HELLO WORLD' +lowerGreet = upperGreet.lower() +print(lowerGreet) # Output: hello world +``` + +يمكنك استدعاء كل من `.strip()` و `.lower()` على سلسلة نصية بهذه الطريقة: + +```python +messy = ' HELLO WORLD ' +clean = messy.strip().lower() +print(clean) # Output: hello world +``` + +أنشئ متغيرًا باسم `messy_email` وعيّن له السلسلة النصية `SARAH.DAVIS@COMPANY.COM` مع وجود مسافتين في البداية ومسافتين في النهاية. + +أيضًا، استدعِ `.strip().lower()` على `messy_email` وعيّن النتيجة إلى متغير `clean_email`. + +ثم اطبع كلا المتغيرين بحيث يكون الإخراج كما يلي: + +```md +Original email: ' SARAH.DAVIS@COMPANY.COM ' +Cleaned email: 'sarah.davis@company.com' +``` + +# --hints-- + +يجب أن تنشئ متغيرًا باسم `messy_email`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('messy_email') +`) }) +``` + +يجب أن تعيّن ' SARAH.DAVIS@COMPANY.COM ' إلى `messy_email`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('messy_email').is_equivalent("messy_email = ' SARAH.DAVIS@COMPANY.COM '") +`) }) +``` + +يجب أن تنشئ متغيرًا باسم `clean_email`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('clean_email') +`) }) +``` + +يجب أن تستدعي `.strip().lower()` على `messy_email` وتعيّن النتيجة إلى متغير `clean_email`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('clean_email').is_equivalent("clean_email = messy_email.strip().lower()") +`) }) +``` + +يجب أن تطبع `messy_email` بحيث يكون الإخراج: `Original email: ' SARAH.DAVIS@COMPANY.COM '`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f\\"Original email: '{messy_email}'\\")", + "print(\\"Original email: '\\" + messy_email + \\"'\\")", + "print(\\"Original email: '\\", messy_email, \\"'\\", sep='')", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +يجب أن تطبع `clean_email` بحيث يكون الإخراج: `Cleaned email: 'sarah.davis@company.com'`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f\\"Cleaned email: '{clean_email}'\\")", + "print(\\"Cleaned email: '\\" + clean_email + \\"'\\")", + "print(\\"Cleaned email: '\\", clean_email, \\"'\\", sep='')", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md new file mode 100644 index 00000000000..2a2ca82d909 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e736c39dfa403496e8071e.md @@ -0,0 +1,88 @@ +--- +id: 69e736c39dfa403496e8071e +title: الخطوة 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +تحول الطريقة `.upper()` جميع الأحرف إلى أحرف كبيرة. هذا مفيد لشارات الأسماء أو العناوين: + +```py +name = 'sarah davis' +badge = name.upper() +print(badge) # Output: SARAH DAVIS +``` + +أنشئ متغيرًا باسم `name_badge` وقم بتعيين نتيجة استدعاء الطريقة `.upper()` على `clean_name` إليه. + +ثم اطبع `name_badge` بحيث يكون الناتج: `Name badge: SARAH DAVIS`. + +# --hints-- + +يجب أن تنشئ متغيرًا باسم `name_badge`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('name_badge') +`) }) +``` + +يجب أن تستدعي `.upper()` على `clean_name` وتعيّن النتيجة إلى المتغير `name_badge`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('name_badge').is_equivalent("name_badge = clean_name.upper()") +`) }) +``` + +يجب أن تطبع `name_badge` بحيث يكون الناتج `Name badge: SARAH DAVIS`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Name badge: {name_badge}')", + "print('Name badge: ' + name_badge)", + "print('Name badge:', name_badge)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md new file mode 100644 index 00000000000..7a7eea29fb1 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e73a141addc6f442924b0d.md @@ -0,0 +1,121 @@ +--- +id: 69e73a141addc6f442924b0d +title: الخطوة 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +لقد استخدمت بالفعل `.find()` والتقطيع على المتغير `email`. الآن ستستخدم نفس التقنية على `clean_email`. + +ابحث عن موقع الحرف `@` في `clean_email` وقم بتخزينه في `at_pos`. ثم استخدم التقطيع لاستخراج كل شيء قبل `@` وخزنه في `email_user`. + +ثم اطبع `clean_email` و `email_user` بحيث يكون الناتج كما يلي: + +```md +Email: sarah.davis@company.com +Username: sarah.davis +``` + +# --hints-- + +يجب إنشاء متغير باسم `at_pos`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('at_pos') +`) }) +``` + +يجب استدعاء `.find('@')` على `clean_email` وتعيين النتيجة إلى المتغير `at_pos`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('at_pos').is_equivalent("at_pos = clean_email.find('@')") +`) }) +``` + +يجب إنشاء متغير باسم `email_user`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('email_user') +`) }) +``` + +يجب استخدام التقطيع مع `at_pos` على `clean_email` وتعيين النتيجة إلى المتغير `email_user`. + +```js +({ test: () => runPython(` +node = _Node(_code).find_variable('email_user') +assert node.is_equivalent("email_user = clean_email[:at_pos]") or node.is_equivalent("email_user = clean_email[0:at_pos]") +`) }) +``` + +يجب طباعة `clean_email` بحيث يكون الناتج `Email: sarah.davis@company.com`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Email: {clean_email}')", + "print('Email: ' + clean_email)", + "print('Email:', clean_email)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +يجب طباعة `email_user` بحيث يكون الناتج `Username: sarah.davis`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Username: {email_user}')", + "print('Username: ' + email_user)", + "print('Username:', email_user)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md new file mode 100644 index 00000000000..95f9686b883 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e73f4f5f986657647bbd63.md @@ -0,0 +1,97 @@ +--- +id: 69e73f4f5f986657647bbd63 +title: الخطوة 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +طريقة `.replace(old, new)` تستبدل كل ظهور للسلسلة الفرعية `old` بأخرى، وهي `new`. يمكنك أيضًا ربطها مع طرق أخرى. على سبيل المثال: + +```py +text = 'john.doe' +name = text.replace('.', ' ').title() +print(name) # Output: John Doe +``` + +استبدل `.` بمسافة واحدة في `email_user`، ثم استدعِ `.title()` على النتيجة. عيّن النتيجة في متغير اسمه `display_name`. + +ثم اطبع `display_name` بحيث يكون الإخراج: `Display name: Sarah Davis`. + +# --hints-- + +يجب إنشاء متغير اسمه `display_name`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('display_name') +`) }) +``` + +يجب استخدام `.replace('.', ' ')` و`.title()` على `email_user` وتعيين النتيجة في المتغير `display_name`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('display_name').is_equivalent("display_name = email_user.replace('.', ' ').title()") +`) }) +``` + +يجب طباعة `display_name` بحيث يكون الإخراج `Display name: Sarah Davis`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Display name: {display_name}')", + "print('Display name: ' + display_name)", + "print('Display name:', display_name)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md new file mode 100644 index 00000000000..28a14cbedb0 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e75dc335b6ec9903a87d3e.md @@ -0,0 +1,135 @@ +--- +id: 69e75dc335b6ec9903a87d3e +title: الخطوة 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +يمكنك أيضًا استخدام `.replace()` لإزالة الأحرف غير المرغوب فيها. على سبيل المثال، إزالة الشرطات من رقم الهاتف: + +```py +phone = '456-147' +clean = phone.replace('-', '') +print(clean) # Output: 456147 +``` + +أنشئ متغيرًا باسم `phone` وقم بتعيين السلسلة النصية `123-456-7890` له. ثم استبدل `-` بسلسلة فارغة وعيّن النتيجة إلى متغير باسم `phone_clean`. + +ثم اطبع كلا المتغيرين بحيث يكون الناتج: + +```md +Phone with dashes: 123-456-7890 +Phone without dashes: 1234567890 +``` + +# --hints-- + +يجب أن تنشئ متغيرًا باسم `phone`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('phone') +`) }) +``` + +يجب أن تعيّن السلسلة النصية `123-456-7890` إلى `phone`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('phone').is_equivalent("phone = '123-456-7890'") +`) }) +``` + +يجب أن تنشئ متغيرًا باسم `phone_clean`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('phone_clean') +`) }) +``` + +يجب أن تستخدم `.replace('-', '')` على `phone` وتعيّن النتيجة إلى المتغير `phone_clean`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('phone_clean').is_equivalent("phone_clean = phone.replace('-', '')") +`) }) +``` + +يجب أن تطبع `phone` بحيث يكون الناتج `Phone with dashes: 123-456-7890`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Phone with dashes: {phone}')", + "print('Phone with dashes: ' + phone)", + "print('Phone with dashes:', phone)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +يجب أن تطبع `phone_clean` بحيث يكون الناتج `Phone without dashes: 1234567890`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Phone without dashes: {phone_clean}')", + "print('Phone without dashes: ' + phone_clean)", + "print('Phone without dashes:', phone_clean)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +display_name = email_user.replace('.', ' ').title() +print(f'Display name: {display_name}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md new file mode 100644 index 00000000000..f913003b322 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e76d1997661be7f0040e2d.md @@ -0,0 +1,122 @@ +--- +id: 69e76d1997661be7f0040e2d +title: الخطوة 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +طريقة `.split(separator)` تقسم سلسلة نصية إلى قائمة من السلاسل الفرعية عند كل ظهور لـ `separator`. على سبيل المثال: + +```py +fruits = 'apple, banana, cherry' +parts = fruits.split(', ') +print(parts) # Output: ['apple', 'banana', 'cherry'] +``` + +أنشئ متغيرًا باسم `full_address` وعيّن له السلسلة النصية `123 Main Street, Springfield, IL`. ثم أنشئ `address_parts` بتقسيم السلسلة عند الفاصلة متبوعة بمسافة واحدة. + +ثم اطبع `address_parts` بحيث يكون الناتج: `Address parts: ['123 Main Street', 'Springfield', 'IL']`. + +# --hints-- + +يجب أن تنشئ متغيرًا باسم `full_address`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('full_address') +`) }) +``` + +يجب أن تعيّن السلسلة النصية `123 Main Street, Springfield, IL` إلى `full_address`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('full_address').is_equivalent("full_address = '123 Main Street, Springfield, IL'") +`) }) +``` + +يجب أن تنشئ متغيرًا باسم `address_parts`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('address_parts') +`) }) +``` + +يجب أن تستخدم `.split(', ')` على `full_address` وتعيّن النتيجة إلى المتغير `address_parts`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('address_parts').is_equivalent("address_parts = full_address.split(', ')") +`) }) +``` + +يجب أن تطبع `address_parts` بحيث يكون الناتج: `Address parts: ['123 Main Street', 'Springfield', 'IL']`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Address parts: {address_parts}')", + "print('Address parts: ' + str(address_parts))", + "print('Address parts:', address_parts)", + "print('Address parts:', str(address_parts))", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +display_name = email_user.replace('.', ' ').title() +print(f'Display name: {display_name}') + +phone = '123-456-7890' +phone_clean = phone.replace('-', '') +print(f'Phone with dashes: {phone}') +print(f'Phone without dashes: {phone_clean}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md new file mode 100644 index 00000000000..90e409d382a --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e76e91402d7850510a5f18.md @@ -0,0 +1,109 @@ +--- +id: 69e76e91402d7850510a5f18 +title: الخطوة 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +طريقة `.join(list)` هي عكس `.split()`. تُدمج قائمة من السلاسل النصية في سلسلة نصية واحدة باستخدام فاصل. على سبيل المثال: + +```py +parts = ['apple', 'banana', 'cherry'] +joined = ' - '.join(parts) +print(joined) # Output: apple - banana - cherry +``` + +ادمج العناصر من `address_parts` باستخدام الحرف `|` محاطًا بمسافات وعيّن النتيجة إلى متغير اسمه `rejoined`. + +ثم اطبع `rejoined` بحيث يكون الإخراج: `Rejoined: 123 Main Street | Springfield | IL`. + +# --hints-- + +يجب إنشاء متغير اسمه `rejoined`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('rejoined') +`) }) +``` + +يجب تعيين `rejoined` القيمة `' | '.join(address_parts)`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('rejoined').is_equivalent("rejoined = ' | '.join(address_parts)") +`) }) +``` + +يجب طباعة `rejoined` بحيث يكون الإخراج `Rejoined: 123 Main Street | Springfield | IL`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Rejoined: {rejoined}')", + "print('Rejoined: ' + rejoined)", + "print('Rejoined:', rejoined)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +display_name = email_user.replace('.', ' ').title() +print(f'Display name: {display_name}') + +phone = '123-456-7890' +phone_clean = phone.replace('-', '') +print(f'Phone with dashes: {phone}') +print(f'Phone without dashes: {phone_clean}') + +full_address = '123 Main Street, Springfield, IL' +address_parts = full_address.split(', ') +print(f'Address parts: {address_parts}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md new file mode 100644 index 00000000000..cf0c8bd40e1 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e774b82fe0bfdb684f95b4.md @@ -0,0 +1,114 @@ +--- +id: 69e774b82fe0bfdb684f95b4 +title: الخطوة 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +أحيانًا تحتاج إلى التحقق من كيفية بدء سلسلة نصية. يوفر Python طريقة `.startswith()` لهذا الغرض. تُرجع `True` إذا بدأت السلسلة النصية بـبادئة معينة؛ وإلا تُرجع `False`. + +إليك مثالاً: + +```python +code = 'EMP-001' +print(code.startswith('EMP')) # True +print(code.startswith('001')) # False +``` + +أنشئ متغيرًا باسم `employee_code` وعيّن له السلسلة النصية `EMP-2024-SD`. ثم أنشئ متغيرًا `starts_with_emp` يتحقق مما إذا كانت `employee_code` تبدأ بـ `EMP`. + +# --hints-- + +يجب إنشاء متغير باسم `employee_code`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('employee_code') +`) }) +``` + +يجب تعيين `EMP-2024-SD` إلى `employee_code`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('employee_code').is_equivalent("employee_code = 'EMP-2024-SD'") +`) }) +``` + +يجب إنشاء متغير باسم `starts_with_emp`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('starts_with_emp') +`) }) +``` + +يجب استخدام `.startswith('EMP')` على `employee_code` وتعيين النتيجة إلى المتغير `starts_with_emp`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('starts_with_emp').is_equivalent("starts_with_emp = employee_code.startswith('EMP')") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +display_name = email_user.replace('.', ' ').title() +print(f'Display name: {display_name}') + +phone = '123-456-7890' +phone_clean = phone.replace('-', '') +print(f'Phone with dashes: {phone}') +print(f'Phone without dashes: {phone_clean}') + +full_address = '123 Main Street, Springfield, IL' +address_parts = full_address.split(', ') +print(f'Address parts: {address_parts}') + +rejoined = ' | '.join(address_parts) +print(f'Rejoined: {rejoined}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md new file mode 100644 index 00000000000..e8151b0f52b --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69e7766b93d27261775d1cf1.md @@ -0,0 +1,141 @@ +--- +id: 69e7766b93d27261775d1cf1 +title: الخطوة 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +اطبع الآن `employee_code`، و`starts_with_emp`، و`clean_email`، و`ends_with_com` بحيث تكون النتيجة: + +```md +Code: EMP-2024-SD +Starts with EMP: True +Clean email: sarah.davis@company.com +Ends with .com: True +``` + +# --hints-- + +اطبع `employee_code` بحيث تكون النتيجة `Code: EMP-2024-SD`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Code: {employee_code}')", + "print('Code: ' + employee_code)", + "print('Code:', employee_code)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +اطبع `starts_with_emp` بحيث تكون النتيجة `Starts with EMP: True`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Starts with EMP: {starts_with_emp}')", + "print('Starts with EMP: ' + str(starts_with_emp))", + "print('Starts with EMP:', starts_with_emp)", + "print('Starts with EMP:', str(starts_with_emp))", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +اطبع `clean_email` بحيث تكون النتيجة `Clean email: sarah.davis@company.com`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Clean email: {clean_email}')", + "print('Clean email: ' + clean_email)", + "print('Clean email:', clean_email)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +اطبع `ends_with_com` بحيث تكون النتيجة `Ends with .com: True`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Ends with .com: {ends_with_com}')", + "print('Ends with .com: ' + str(ends_with_com))", + "print('Ends with .com:', ends_with_com)", + "print('Ends with .com:', str(ends_with_com))", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +display_name = email_user.replace('.', ' ').title() +print(f'Display name: {display_name}') + +phone = '123-456-7890' +phone_clean = phone.replace('-', '') +print(f'Phone with dashes: {phone}') +print(f'Phone without dashes: {phone_clean}') + +full_address = '123 Main Street, Springfield, IL' +address_parts = full_address.split(', ') +print(f'Address parts: {address_parts}') + +rejoined = ' | '.join(address_parts) +print(f'Rejoined: {rejoined}') + +employee_code = 'EMP-2024-SD' +starts_with_emp = employee_code.startswith('EMP') +ends_with_com = clean_email.endswith('.com') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md new file mode 100644 index 00000000000..62259b75890 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/69eb3158c33d9a229a79951c.md @@ -0,0 +1,120 @@ +--- +id: 69eb3158c33d9a229a79951c +title: الخطوة 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +تُرجع الطريقة `.count(substring)` عدد المرات التي تظهر فيها سلسلة نصية فرعية داخل سلسلة نصية. على سبيل المثال: + +```py +text = 'banana' +print(text.count('a')) # Output: 3 +``` + +أنشئ متغيرين باسم `dot_count` و `dash_count`. يجب أن يحصي `dot_count` عدد أحرف `.` التي تظهر في `clean_email`، ويجب أن يحصي `dash_count` عدد أحرف `-` التي تظهر في `employee_code`. + +# --hints-- + +يجب أن تنشئ متغيرًا باسم `dot_count`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('dot_count') +`) }) +``` + +يجب أن تستخدم `.count('.')` على `clean_email` لتعيين قيمة لـ `dot_count`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('dot_count').is_equivalent("dot_count = clean_email.count('.')") +`) }) +``` + +يجب أن تنشئ متغيرًا باسم `dash_count`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('dash_count') +`) }) +``` + +يجب أن تستخدم `.count('-')` على `employee_code` لتعيين قيمة لـ `dash_count`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('dash_count').is_equivalent("dash_count = employee_code.count('-')") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +display_name = email_user.replace('.', ' ').title() +print(f'Display name: {display_name}') + +phone = '123-456-7890' +phone_clean = phone.replace('-', '') +print(f'Phone with dashes: {phone}') +print(f'Phone without dashes: {phone_clean}') + +full_address = '123 Main Street, Springfield, IL' +address_parts = full_address.split(', ') +print(f'Address parts: {address_parts}') + +rejoined = ' | '.join(address_parts) +print(f'Rejoined: {rejoined}') + +employee_code = 'EMP-2024-SD' +starts_with_emp = employee_code.startswith('EMP') +ends_with_com = clean_email.endswith('.com') + +print(f'Code: {employee_code}') +print(f'Starts with EMP: {starts_with_emp}') +print(f'Clean email: {clean_email}') +print(f'Ends with .com: {ends_with_com}') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md new file mode 100644 index 00000000000..f7f95d36b11 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a71a8df10e823e77358d896.md @@ -0,0 +1,66 @@ +--- +id: 6a71a8df10e823e77358d896 +title: الخطوة 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +أنشئ متغيرًا آخر اسمه `has_com` يتحقق مما إذا كانت `.com` موجودة في `email`. + +ثم اطبع `has_com` بحيث تكون النتيجة: `Has .com: True`. + +# --hints-- + +يجب أن تنشئ متغيرًا اسمه `has_com`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('has_com') +`) }) +``` + +يجب أن يحتوي متغير `has_com` على القيمة `'.com' in email`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('has_com').is_equivalent("has_com = '.com' in email") +`) }) +``` + +يجب أن تطبع `has_com` بحيث تكون النتيجة `Has .com: True`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Has .com: {has_com}')", + "print('Has .com: ' + str(has_com))", + "print('Has .com:', has_com)", + "print('Has .com:', str(has_com))", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md new file mode 100644 index 00000000000..55ac9867936 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a71b3e49668c3be461257b5.md @@ -0,0 +1,64 @@ +--- +id: 6a71b3e49668c3be461257b5 +title: الخطوة 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +تُحوّل الطريقة `.title()` الحرف الأول من كل كلمة إلى حرف كبير. إليك مثالاً: + +```py +lowercase = 'hello world' +title_case = lowercase.title() +print(title_case) # Output: Hello World +``` + +أنشئ متغيرًا باسم `clean_name` وقم بتعيين نتيجة استدعاء `.title()` على `messy_name` له. + +# --hints-- + +يجب أن تنشئ متغيرًا باسم `clean_name`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('clean_name') +`) }) +``` + +يجب أن تستخدم `.title()` على `messy_name` لتعيين قيمة لـ `clean_name`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('clean_name').is_equivalent("clean_name = messy_name.title()") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md new file mode 100644 index 00000000000..8c3c3cd67c6 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a73427af41619a909fb21b4.md @@ -0,0 +1,190 @@ +--- +id: 6a73427af41619a909fb21b4 +title: الخطوة 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +اطبع الآن `dot_count` و `dash_count` بحيث يكون الناتج: + +```md +Dots in email: 2 +Dashes in code: 2 +``` + +بهذا، تكتمل ورشة عمل مدقق ملف الموظف الخاص بك! + +# --hints-- + +يجب أن تطبع `dot_count` بحيث يكون الناتج `Dots in email: 2`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Dots in email: {dot_count}')", + "print('Dots in email: ' + str(dot_count))", + "print('Dots in email:', dot_count)", + "print('Dots in email:', str(dot_count))", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +يجب أن تطبع `dash_count` بحيث يكون الناتج `Dashes in code: 2`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Dashes in code: {dash_count}')", + "print('Dashes in code: ' + str(dash_count))", + "print('Dashes in code:', dash_count)", + "print('Dashes in code:', str(dash_count))", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +display_name = email_user.replace('.', ' ').title() +print(f'Display name: {display_name}') + +phone = '123-456-7890' +phone_clean = phone.replace('-', '') +print(f'Phone with dashes: {phone}') +print(f'Phone without dashes: {phone_clean}') + +full_address = '123 Main Street, Springfield, IL' +address_parts = full_address.split(', ') +print(f'Address parts: {address_parts}') + +rejoined = ' | '.join(address_parts) +print(f'Rejoined: {rejoined}') + +employee_code = 'EMP-2024-SD' +starts_with_emp = employee_code.startswith('EMP') +ends_with_com = clean_email.endswith('.com') + +print(f'Code: {employee_code}') +print(f'Starts with EMP: {starts_with_emp}') +print(f'Clean email: {clean_email}') +print(f'Ends with .com: {ends_with_com}') + +dot_count = clean_email.count('.') +dash_count = employee_code.count('-') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` + +# --solutions-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +display_name = email_user.replace('.', ' ').title() +print(f'Display name: {display_name}') + +phone = '123-456-7890' +phone_clean = phone.replace('-', '') +print(f'Phone with dashes: {phone}') +print(f'Phone without dashes: {phone_clean}') + +full_address = '123 Main Street, Springfield, IL' +address_parts = full_address.split(', ') +print(f'Address parts: {address_parts}') + +rejoined = ' | '.join(address_parts) +print(f'Rejoined: {rejoined}') + +employee_code = 'EMP-2024-SD' +starts_with_emp = employee_code.startswith('EMP') +ends_with_com = clean_email.endswith('.com') + +print(f'Code: {employee_code}') +print(f'Starts with EMP: {starts_with_emp}') +print(f'Clean email: {clean_email}') +print(f'Ends with .com: {ends_with_com}') + +dot_count = clean_email.count('.') +dash_count = employee_code.count('-') + +print(f'Dots in email: {dot_count}') +print(f'Dashes in code: {dash_count}') +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md new file mode 100644 index 00000000000..9b08d4bbff5 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a86b9e64da746838e67fb13.md @@ -0,0 +1,80 @@ +--- +id: 6a86b9e64da746838e67fb13 +title: الخطوة 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +تُزيل الطريقة `.strip()` الفراغات من كلا طرفي السلسلة النصية. + +```python +messy = ' hello world ' +clean = messy.strip() +print(clean) # Output: hello world +``` + +يمكنك ربط الطريقتين `.strip()` و `.title()` لإزالة الفراغات من كلا طرفي السلسلة النصية وتكبير الحرف الأول من كل كلمة: + +```python +messy = ' hello world ' +clean = messy.strip().title() +print(clean) # Output: Hello World +``` + +حدّث قيمة `clean_name` لاستدعاء `.strip()` على `messy_name` قبل `.title()`. + +بعد ذلك، اطبع `clean_name` بحيث تكون النتيجة `Cleaned name: 'Sarah Davis'`. + +# --hints-- + +يجب تحديث `clean_name` لاستدعاء `.strip()` على `messy_name` قبل `.title()`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('clean_name').is_equivalent("clean_name = messy_name.strip().title()") +`) }) +``` + +يجب طباعة `clean_name` بحيث تكون النتيجة `Cleaned name: 'Sarah Davis'`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f\\"Cleaned name: '{clean_name}'\\")", + "print(\\"Cleaned name: '\\" + clean_name + \\"'\\")", + "print(\\"Cleaned name: '\\", clean_name, \\"'\\", sep='')", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +--fcc-editable-region-- +clean_name = messy_name.title() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md new file mode 100644 index 00000000000..df084425b9b --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a86be3e8cc29e9ae239e70a.md @@ -0,0 +1,101 @@ +--- +id: 6a86be3e8cc29e9ae239e70a +title: الخطوة 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +قد تحتاج أيضًا إلى التحقق من كيفية انتهاء سلسلة نصية. يوفر Python الطريقة `.endswith()` لهذا الغرض. تُرجع `True` إذا انتهت السلسلة النصية باللاحقة المعطاة و`False` إذا لم تنتهِ بها. + +إليك مثالاً: + +```python +code = 'EMP-001' +print(code.endswith('EMP')) # False +print(code.endswith('001')) # True +``` + +أنشئ متغيرًا باسم `ends_with_com` يتحقق مما إذا كانت `clean_email` تنتهي بـ `.com`. + +# --hints-- + +يجب أن تنشئ متغيرًا باسم `ends_with_com`. + +```js +({ test: () => runPython(` +assert _Node(_code).has_variable('ends_with_com') +`) }) +``` + +يجب أن تستخدم `.endswith('.com')` على `clean_email` وتعيّن النتيجة إلى المتغير `ends_with_com`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_variable('ends_with_com').is_equivalent("ends_with_com = clean_email.endswith('.com')") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +print(f'Email: {email}') + +at_position = email.find('@') +print(f'Position of @: {at_position}') + +username = email[:at_position] +print(f'Username: {username}') + +has_at = '@' in email +print(f'Has @ symbol: {has_at}') + +has_com = '.com' in email +print(f'Has .com: {has_com}') + +messy_name = ' sARaH dAVis ' +print(f"Original name: '{messy_name}'") + +clean_name = messy_name.strip().title() +print(f"Cleaned name: '{clean_name}'") + +messy_email = ' SARAH.DAVIS@COMPANY.COM ' +clean_email = messy_email.strip().lower() +print(f"Original email: '{messy_email}'") +print(f"Cleaned email: '{clean_email}'") + +name_badge = clean_name.upper() +print(f'Name badge: {name_badge}') + +at_pos = clean_email.find('@') +email_user = clean_email[:at_pos] + +print(f'Email: {clean_email}') +print(f'Username: {email_user}') + +display_name = email_user.replace('.', ' ').title() +print(f'Display name: {display_name}') + +phone = '123-456-7890' +phone_clean = phone.replace('-', '') +print(f'Phone with dashes: {phone}') +print(f'Phone without dashes: {phone_clean}') + +full_address = '123 Main Street, Springfield, IL' +address_parts = full_address.split(', ') +print(f'Address parts: {address_parts}') + +rejoined = ' | '.join(address_parts) +print(f'Rejoined: {rejoined}') + +employee_code = 'EMP-2024-SD' +starts_with_emp = employee_code.startswith('EMP') + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md new file mode 100644 index 00000000000..b9070c58f63 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-employee-profile-validator/6a870cc60c23f0332a2fe788.md @@ -0,0 +1,46 @@ +--- +id: 6a870cc60c23f0332a2fe788 +title: الخطوة 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +تذكر من ورشة العمل السابقة أنه يمكنك استخدام f-string لتضمين متغير داخل سلسلة نصية، بكتابة `f` قبل علامة الاقتباس الافتتاحية وتغليف المتغير بـ `{}`. + +إليك تذكير بكيفية عملها: + +```python +name = 'Alice' +print(f'Hello, {name}') # Hello, Alice +``` + +الآن، اطبع `email` بحيث تكون النتيجة: `Email: alice.johnson@company.com`. + +# --hints-- + +يجب أن تطبع `email` بحيث تكون النتيجة `Email: alice.johnson@company.com`. + +```js +({ test: () => runPython(` +node = _Node(_code) +valid_calls = [ + "print(f'Email: {email}')", + "print('Email: ' + email)", + "print('Email:', email)", +] +assert any(node.has_call(call) for call in valid_calls) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +email = 'alice.johnson@company.com' +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md new file mode 100644 index 00000000000..3c3c4ad7199 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac09f8420b4b67e075d2cd2.md @@ -0,0 +1,45 @@ +--- +id: 6ac09f8420b4b67e075d2cd2 +title: الخطوة 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +في هذه الورشة، ستنشئ أول برنامج Python خاص بك. + +هذا هو محرر الكود الخاص بك، حيث ستكتب كود Python. السطر 1 مميز. اذهب إليه واكتب: + +```py +'Hello' +``` + +تأكد من البدء في بداية السطر ولا تنسَ علامات الاقتباس. + +عندما تنتهي، انقر على زر "التحقق من الكود" لترى ما إذا كان صحيحًا. + +# --hints-- + +يجب أن تكتب `'Hello'`. تأكد من البدء في بداية السطر ولا تنسَ علامات الاقتباس. + +```js +({ test: () => runPython(` +import re +stmts = _Node(_code) +pattern = r"""(['"])\\s*hello\\s*\\1""" +assert any( + re.fullmatch(pattern, str(stmt).strip(), flags=re.IGNORECASE) + for stmt in stmts +)`) }); +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md new file mode 100644 index 00000000000..4fe0ac7633f --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0a4463662d9738c393e21.md @@ -0,0 +1,45 @@ +--- +id: 6ac0a4463662d9738c393e21 +title: الخطوة 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +في الخطوة السابقة، أنشأت **سلسلة نصية**: متتالية من الأحرف محاطة إما بعلامات اقتباس مفردة أو علامات اقتباس مزدوجة. في البرمجة، تُستخدم السلاسل النصية لتمثيل النص. + +**الطرفية** هي المكان الذي يمكنك فيه رؤية ناتج الكود الخاص بك. + +لكي تتمكن من رؤية الناتج، حوّل السطر الحالي من الكود إلى: + +```py +print('Hello') +``` + +تأكد من البدء من بداية السطر. + +# --hints-- + +يجب أن يحتوي كودك على `print('Hello')`. تأكد من البدء من بداية السطر. + +```js +({ test: () => runPython(` +import re +stmts = _Node(_code) +pattern = r"""print\\s*\\((['"])\\s*hello\\s*\\1\\s*\\)""" +assert any( + re.fullmatch(pattern, str(stmt).strip(), flags=re.IGNORECASE) + for stmt in stmts +)`) }); +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +'Hello' +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md new file mode 100644 index 00000000000..eff32e5bbc3 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0aaba914d81b32567c076.md @@ -0,0 +1,44 @@ +--- +id: 6ac0aaba914d81b32567c076 +title: الخطوة 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +`print` دالة مدمجة يمكنك استخدامها لإرسال الإخراج إلى الطرفية. كما ترى، النص `Hello` أصبح ظاهرًا الآن على الطرفية. + +الآن، اطبع النص `freeCodeCamp` على الطرفية بالذهاب إلى السطر المميز وكتابة: + +```py +print('freeCodeCamp') +``` + +تأكد من البدء في بداية السطر. + +# --hints-- + +يجب أن يحتوي كودك على `print('freeCodeCamp')`. تأكد من البدء في بداية السطر. + +```js +({ test: () => runPython(` +import re +stmts = _Node(_code) +pattern = r"""print\\s*\\((['"])\\s*freecodecamp\\s*\\1\\s*\\)""" +assert any( + re.fullmatch(pattern, str(stmt).strip(), flags=re.IGNORECASE) + for stmt in stmts +)`) }); +``` + +# --seed-- + +## --seed-contents-- + +```py +print('Hello') +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md new file mode 100644 index 00000000000..b382629b4a4 --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0ae563f6de70930f47ef7.md @@ -0,0 +1,42 @@ +--- +id: 6ac0ae563f6de70930f47ef7 +title: الخطوة 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +عند كتابة الكود، غالبًا ما تريد إعادة استخدام أو الإشارة إلى قيم موجودة في كودك. المتغيرات تتيح لك ذلك. + +لتعيين قيمة إلى متغير، اكتب اسم المتغير متبوعًا بمعامل التعيين (`=`) والقيمة التي تريد تعيينها لذلك المتغير: + +```py +sentence = 'I am learning Python' +``` + +انتقل إلى السطر المميز، أنشئ متغيرًا باسم `sentence` وعيّن له السلسلة النصية `I am learning Python`. + +# --hints-- + +يجب أن يحتوي كودك على `sentence = 'I am learning Python'`. تأكد من البدء في بداية السطر. + +```js +({ test: () => runPython(` +import re +target_var = _Node(_code).find_variable("sentence") +pattern = r"""sentence\\s*=\\s*(['"])\\s*i\\s+am\\s+learning\\s+python\\s*\\1\\s*""" +assert re.fullmatch(pattern, str(target_var).strip(), flags=re.IGNORECASE)`) }); +``` + +# --seed-- + +## --seed-contents-- + +```py +print('Hello') +print('freeCodeCamp') +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md new file mode 100644 index 00000000000..50e8d22826f --- /dev/null +++ b/curriculum/challenges/arabic/blocks/workshop-first-python-program/6ac0b35f3b29a27f7e207295.md @@ -0,0 +1,44 @@ +--- +id: 6ac0b35f3b29a27f7e207295 +title: الخطوة 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +في الخطوة السابقة، أنشأت المتغير `sentence`. الآن اطبع قيمته على الطرفية بكتابة `print(sentence)` في السطر المميز. + +بهذا تكون قد أكملت برنامج Python الأول الخاص بك. + +# --hints-- + +يجب أن يحتوي كودك على `print(sentence)`. تأكد من البدء في بداية السطر. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("print(sentence)")`)) }); +``` + +# --seed-- + +## --seed-contents-- + +```py +print('Hello') +print('freeCodeCamp') + +sentence = 'I am learning Python' +--fcc-editable-region-- + +--fcc-editable-region-- +``` + +# --solutions-- + +```py +print('Hello') +print('freeCodeCamp') + +sentence = 'I am learning Python' +print(sentence) +``` diff --git a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e4ae26f2b7e4b5b026cf8.md b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e4ae26f2b7e4b5b026cf8.md index 1f2197b1f29..baf3980806c 100644 --- a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e4ae26f2b7e4b5b026cf8.md +++ b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e4ae26f2b7e4b5b026cf8.md @@ -16,7 +16,7 @@ def my_function(): pass ``` -عرّف دالة فارغة باسم `check_kitchen_stock()`. استخدم الكلمة المفتاحية `pass` داخل جسم الدالة الآن حتى لا ترمي Python خطأ نحويًا. +عرّف دالة فارغة باسم `check_kitchen_stock`. استخدم الكلمة المفتاحية `pass` داخل جسم الدالة الآن حتى لا تُرجع Python خطأ `SyntaxError`. تذكر أن Python تعتمد على المسافة البادئة لتعريف كتل الكود. لذا تأكد من إضافة المسافة البادئة لجسم الدالة. diff --git a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e5475c35dbc138d77c6f4.md b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e5475c35dbc138d77c6f4.md index 0b3851cda90..b255161cb26 100644 --- a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e5475c35dbc138d77c6f4.md +++ b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e5475c35dbc138d77c6f4.md @@ -7,14 +7,7 @@ dashedName: step-4 # --description-- -الآن بعد أن حسبت المجموع الكلي، يجب أن تعرض المخزون. في Python، يمكنك استخدام الدالة `print()` مع **f-strings** (سلاسل نصية منسقة) لطباعة النص والمتغيرات معًا بسهولة. - -على سبيل المثال: - -```py -name = 'Alice' -print(f'Hello, {name}!') # Output: Hello, Alice! -``` +الآن بعد أن حسبت المجموع الكلي، يجب أن تعرض المخزون. تذكر من الدروس السابقة أنه يمكنك استخدام الدالة `print()` مع **f-strings** لتضمين المتغيرات في الإخراج. داخل دالتك `check_kitchen_stock`، أسفل متغير `total_items`، أضف هذه العبارات الأربع للطباعة بالضبط: diff --git a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e67fc5ef4045201c28219.md b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e67fc5ef4045201c28219.md index f1d44e52ea4..87ef8faff32 100644 --- a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e67fc5ef4045201c28219.md +++ b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e67fc5ef4045201c28219.md @@ -9,8 +9,6 @@ dashedName: step-7 داخل دالة `use_eggs`، عليك التحقق مما إذا كان لديك بيض كافٍ للطهي. يمكنك فعل ذلك باستخدام جملة `if`. -جملة `if` تُقيّم شرطًا. إذا كان الشرط صحيحًا، يُنفذ الكود داخل كتلة الـ `if`. - استبدل الكلمة المفتاحية `pass` بجملة `if` تتحقق مما إذا كانت قيمة `eggs_to_use` أكبر من (`>`) قيمة `available_eggs`. داخل كتلة الـ `if`، اطبع السلسلة النصية `The kitchen does not have enough eggs.`. # --hints-- diff --git a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e6fd08125dfa615cb431b.md b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e6fd08125dfa615cb431b.md index 68c23bf84dc..936e977c234 100644 --- a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e6fd08125dfa615cb431b.md +++ b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e6fd08125dfa615cb431b.md @@ -17,6 +17,8 @@ def calculate_sum(a, b): calculate_sum(3, 1) # Output: 4 ``` +في هذا المثال، السطران الأولان هما تعريف الدالة، حيث `a` و `b` هما المعلمتان. السطر الأخير، `calculate_sum(3, 1)`، هو استدعاء الدالة. القيم `3` و `1` هما المعلمتان. يتم مطابقتها مع المعلمات حسب الموضع، لذا تُعيَّن القيمة `3` إلى `a` والقيمة `1` تُعيَّن إلى `b`. + في أسفل الكود الخاص بك، استدعِ دالة `use_eggs` ومرر لها معلمتين: المتغير العام `available_eggs` والرقم `1` (الذي يمثل عدد البيض الذي تريد استخدامه). # --hints-- diff --git a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e7284e89ce3367e709331.md b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e7284e89ce3367e709331.md index 5de23848838..546dc6d727a 100644 --- a/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e7284e89ce3367e709331.md +++ b/curriculum/challenges/arabic/blocks/workshop-kitchen-inventory-tracker/6a3e7284e89ce3367e709331.md @@ -9,7 +9,7 @@ dashedName: step-13 قبل صنع بيضة مقلية، يجب أولاً التحقق من وجود المكونات المطلوبة. يمكنك فعل ذلك بمقارنة كمية البيض المتوفرة مع الكمية اللازمة للوصفة. -داخل دالة `make_fried_egg`، استبدل الكلمة المفتاحية `pass` بإنشاء متغير اسمه `has_enough_eggs` وتعيين نتيجة التحقق مما إذا كان `available_eggs` أكبر من أو يساوي `1`. +داخل دالة `make_fried_egg`، استبدل الكلمة المفتاحية `pass` بمتغير اسمه `has_enough_eggs`. عيّن له نتيجة التحقق مما إذا كان `available_eggs` أكبر من أو يساوي `1`. # --hints-- diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fdb4386b473631d8e27ca.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fdb4386b473631d8e27ca.md index 6d40dedafd1..0a367a9651c 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fdb4386b473631d8e27ca.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fdb4386b473631d8e27ca.md @@ -9,23 +9,40 @@ dashedName: step-27 يمكن أن تحتوي التعبيرات النمطية على متتاليات خاصة تتكون من شرطة مائلة عكسية (`\`) تليها حرف. لهذه المتتاليات معنى خاص. على سبيل المثال، `\d` تطابق رقمًا عشريًا. +في بايثون، وضع بادئة `r` أو `R` قبل سلسلة نصية ينشئ *سلسلة نصية خام*. السلاسل النصية الخام تعامل الشرطة المائلة العكسية كحروف حرفية بدلًا من تخطى التسلسل، مما يجعلها مثالية للتعبيرات النمطية. + ```py import re book = "Fahrenheit 451" -print(re.search('\d', book)) +print(re.search(r'\d', book)) # ``` -بعد الحرف `p`، يجب أن يحتوي `patient_id` على متتالية من الأرقام. لذا، عدل نمط التعبير النمطي ليشمل الحرف `p` متبوعًا بالمتتالية الخاصة `\d`. +بعد الحرف `p`، يجب أن يحتوي `patient_id` على متتالية من الأرقام. لذا، عدل تعبيرك النمطي ليكون السلسلة النصية الخام `r'p\d'`. # --hints-- -يجب تعديل نمط التعبير النمطي ليكون `p\d`. +يجب تعديل تعبيرك النمطي ليكون `r'p\d'`. + +```js +({ test: () => runPython(` +assert _Node(_code).find_function("find_invalid_records").find_variable("constraints").is_equivalent(r"constraints = {'patient_id': isinstance(patient_id, str) and re.search(r'p\\d', patient_id, re.IGNORECASE)}") +`) }) +``` + +يجب استخدام سلسلة نصية خام لتعبيرك النمطي. ```js ({ test: () => runPython(` -assert _Node(_code).find_function("find_invalid_records").find_variable("constraints").is_equivalent("constraints = {'patient_id': isinstance(patient_id, str) and re.search('p\\d', patient_id, re.IGNORECASE)}") +import ast + +_target = _Node(_code).find_function("find_invalid_records").find_variable("constraints").tree.value +_keys = [k.value for k in _target.keys] +_index = _keys.index('patient_id') +_val = _target.values[_index] +_pattern = _val.values[1].args[0] +assert ast.get_source_segment(_code, _pattern).lower().startswith('r') `) }) ``` diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fde383e4b1298310927b9.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fde383e4b1298310927b9.md index 86b4ec5ebad..5b40b0b52c1 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fde383e4b1298310927b9.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fde383e4b1298310927b9.md @@ -13,10 +13,10 @@ dashedName: step-28 import re book = "Fahrenheit 451" -print(re.search('\d', book)) +print(re.search(r'\d', book)) # -print(re.search('\d+', book)) +print(re.search(r'\d+', book)) # ``` @@ -24,11 +24,11 @@ print(re.search('\d+', book)) # --hints-- -يجب أن تضيف المحدد الكمي `+` إلى نمط التعبير النمطي الحالي `p\d`. +يجب إضافة المحدد الكمي `+` إلى تعبيرك النمطي الحالي `r'p\d'`. ```js ({ test: () => runPython(` -assert _Node(_code).find_function("find_invalid_records").find_variable("constraints").is_equivalent("constraints = {'patient_id': isinstance(patient_id, str) and re.search('p\\d+', patient_id, re.IGNORECASE)}") +assert _Node(_code).find_function("find_invalid_records").find_variable("constraints").is_equivalent(r"constraints = {'patient_id': isinstance(patient_id, str) and re.search(r'p\\d+', patient_id, re.IGNORECASE)}") `) }) ``` @@ -79,7 +79,7 @@ def find_invalid_records( ): constraints = { --fcc-editable-region-- - 'patient_id': isinstance(patient_id, str) and re.search('p\d', patient_id, re.IGNORECASE) + 'patient_id': isinstance(patient_id, str) and re.search(r'p\d', patient_id, re.IGNORECASE) --fcc-editable-region-- } return constraints diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fe1be09b05ad785832546.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fe1be09b05ad785832546.md index df518358490..0d9d95518ea 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fe1be09b05ad785832546.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/684fe1be09b05ad785832546.md @@ -1,6 +1,6 @@ --- id: 684fe1be09b05ad785832546 -title: الخطوة 29 +title: خطوة 29 challengeType: 20 dashedName: step-29 --- @@ -15,9 +15,9 @@ dashedName: step-29 import re book = "Fahrenheit 451" -print(re.fullmatch('\d+', book)) #None +print(re.fullmatch(r'\d+', book)) #None -print(re.fullmatch('Fahrenheit \d+', book)) +print(re.fullmatch(r'Fahrenheit \d+', book)) # ``` @@ -25,11 +25,11 @@ print(re.fullmatch('Fahrenheit \d+', book)) # --hints-- -يجب أن تستبدل `re.search('p\d+', patient_id, re.IGNORECASE)` بـ `re.fullmatch('p\d+', patient_id, re.IGNORECASE)`. +يجب استبدال `re.search(r'p\d+', patient_id, re.IGNORECASE)` بـ `re.fullmatch(r'p\d+', patient_id, re.IGNORECASE)`. ```js ({ test: () => runPython(` -assert _Node(_code).find_function("find_invalid_records").find_variable("constraints").is_equivalent("constraints = {'patient_id': isinstance(patient_id, str) and re.fullmatch('p\\d+', patient_id, re.IGNORECASE)}") +assert _Node(_code).find_function("find_invalid_records").find_variable("constraints").is_equivalent(r"constraints = {'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\\d+', patient_id, re.IGNORECASE)}") `) }) ``` @@ -80,7 +80,7 @@ def find_invalid_records( ): constraints = { --fcc-editable-region-- - 'patient_id': isinstance(patient_id, str) and re.search('p\d+', patient_id, re.IGNORECASE) + 'patient_id': isinstance(patient_id, str) and re.search(r'p\d+', patient_id, re.IGNORECASE) --fcc-editable-region-- } return constraints diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685081f42afaba3a60bdf94f.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685081f42afaba3a60bdf94f.md index f48ea4fc9c6..d5d632da066 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685081f42afaba3a60bdf94f.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685081f42afaba3a60bdf94f.md @@ -80,7 +80,7 @@ def find_invalid_records( ): constraints = { --fcc-editable-region-- - 'patient_id': isinstance(patient_id, str) and re.fullmatch('p\d+', patient_id, re.IGNORECASE) + 'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE) --fcc-editable-region-- } diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6851051b0da0e34840f3919f.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6851051b0da0e34840f3919f.md index b6562fce802..80e2f9a00fc 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6851051b0da0e34840f3919f.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6851051b0da0e34840f3919f.md @@ -71,7 +71,7 @@ def find_invalid_records( patient_id, age, gender, diagnosis, medications, last_visit_id ): constraints = { - 'patient_id': isinstance(patient_id, str) and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + 'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), --fcc-editable-region-- 'age': isinstance(age, int) --fcc-editable-region-- diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685106fab1f801691d8f58a0.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685106fab1f801691d8f58a0.md index 8c4bf3478a6..e4ddc5d70bb 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685106fab1f801691d8f58a0.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685106fab1f801691d8f58a0.md @@ -79,7 +79,7 @@ def find_invalid_records( patient_id, age, gender, diagnosis, medications, last_visit_id ): constraints = { - 'patient_id': isinstance(patient_id, str) and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + 'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), --fcc-editable-region-- 'age': isinstance(age, int) and age >= 18 diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685118ddcad14fa5d62faaef.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685118ddcad14fa5d62faaef.md index b30c53aac2e..9db26dbf080 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685118ddcad14fa5d62faaef.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685118ddcad14fa5d62faaef.md @@ -81,7 +81,7 @@ def find_invalid_records( patient_id, age, gender, diagnosis, medications, last_visit_id ): constraints = { - 'patient_id': isinstance(patient_id, str) and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + 'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, --fcc-editable-region-- 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female') diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68511abf14415dc7c27fbea7.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68511abf14415dc7c27fbea7.md index 88c50f8beb6..e8a40fa1fa2 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68511abf14415dc7c27fbea7.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68511abf14415dc7c27fbea7.md @@ -1,6 +1,6 @@ --- id: 68511abf14415dc7c27fbea7 -title: خطوة 34 +title: الخطوة 34 challengeType: 20 dashedName: step-34 --- @@ -79,7 +79,7 @@ def find_invalid_records( patient_id, age, gender, diagnosis, medications, last_visit_id ): constraints = { - 'patient_id': isinstance(patient_id, str) and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + 'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), --fcc-editable-region-- diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68511bdce9282edbef75ca48.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68511bdce9282edbef75ca48.md index 0138725d995..7c97561b6a1 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68511bdce9282edbef75ca48.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68511bdce9282edbef75ca48.md @@ -80,7 +80,7 @@ def find_invalid_records( patient_id, age, gender, diagnosis, medications, last_visit_id ): constraints = { - 'patient_id': isinstance(patient_id, str) and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + 'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516ab0ba81759b1ff864e3.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516ab0ba81759b1ff864e3.md index ca82b050394..98faee67c29 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516ab0ba81759b1ff864e3.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516ab0ba81759b1ff864e3.md @@ -79,7 +79,7 @@ def find_invalid_records( patient_id, age, gender, diagnosis, medications, last_visit_id ): constraints = { - 'patient_id': isinstance(patient_id, str) and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + 'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516d0c0cb162c7578616ad.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516d0c0cb162c7578616ad.md index 60b743a225a..26b5bbd99f7 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516d0c0cb162c7578616ad.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516d0c0cb162c7578616ad.md @@ -1,6 +1,6 @@ --- id: 68516d0c0cb162c7578616ad -title: خطوة 37 +title: الخطوة 37 challengeType: 20 dashedName: step-37 --- @@ -79,7 +79,7 @@ def find_invalid_records( patient_id, age, gender, diagnosis, medications, last_visit_id ): constraints = { - 'patient_id': isinstance(patient_id, str) and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + 'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516e3c627b43de8c138ea9.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516e3c627b43de8c138ea9.md index deb2cadd143..b98d0a08ebe 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516e3c627b43de8c138ea9.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68516e3c627b43de8c138ea9.md @@ -9,11 +9,11 @@ dashedName: step-38 حان الوقت لاستخدام تعبير نمطي آخر. بالمثل لما فعلته سابقًا، استخدم العامل `and` لإضافة تعبير إلى القيمة الحالية لـ `constraints['last_visit_id']`. -على الجانب الأيمن من العامل `and`، استخدم الدالة `fullmatch` من وحدة `re` للتأكد من أن `last_visit_id` يبدأ بالحرف `v` (سواء أحرف صغيرة أو كبيرة) متبوعًا برقم واحد أو أكثر. +على الجانب الأيمن من عامل `and`، استخدم الدالة `fullmatch` من وحدة `re` للتأكد من أن `last_visit_id` يبدأ بالحرف `v` (سواء أحرف صغيرة أو كبيرة) متبوعًا برقم واحد أو أكثر. استخدم السلسلة النصية الخام `r'v\d+'` للنمط. # --hints-- -يجب أن تكون قيمة المفتاح `last_visit_id` في قاموس `constraints` هي `isinstance(last_visit_id, str) and re.fullmatch('v\d+', last_visit_id, re.IGNORECASE)`. +يجب أن تكون قيمة المفتاح `last_visit_id` في قاموس `constraints` هي `isinstance(last_visit_id, str) and re.fullmatch(r'v\d+', last_visit_id, re.IGNORECASE)`. ```js ({ test: () => assert(runPython(` @@ -21,10 +21,25 @@ _target = _Node(_code).find_function("find_invalid_records").find_variable("cons _keys = [k.value for k in _target.keys] _index = _keys.index('last_visit_id') _val = _target.values[_index] -_Node(_val).is_equivalent("isinstance(last_visit_id, str) and re.fullmatch('v\\d+', last_visit_id, re.IGNORECASE)") +_Node(_val).is_equivalent(r"isinstance(last_visit_id, str) and re.fullmatch(r'v\\d+', last_visit_id, re.IGNORECASE)") `)) }) ``` +يجب استخدام سلسلة نصية خام لنمط التعبير النمطي الخاص بك. + +```js +({ test: () => runPython(` +import ast + +_target = _Node(_code).find_function("find_invalid_records").find_variable("constraints").tree.value +_keys = [k.value for k in _target.keys] +_index = _keys.index('last_visit_id') +_val = _target.values[_index] +_pattern = _val.values[1].args[0] +assert ast.get_source_segment(_code, _pattern).lower().startswith('r') +`) }) +``` + # --seed-- ## --seed-contents-- @@ -71,7 +86,7 @@ def find_invalid_records( patient_id, age, gender, diagnosis, medications, last_visit_id ): constraints = { - 'patient_id': isinstance(patient_id, str) and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + 'patient_id': isinstance(patient_id, str) and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6851719eee78621daa093a00.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6851719eee78621daa093a00.md index 9fd6d652d20..09a22f71c77 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6851719eee78621daa093a00.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6851719eee78621daa093a00.md @@ -13,7 +13,7 @@ dashedName: step-39 # --hints-- -يجب أن تُعيد دالة `find_invalid_records` فهم قائمة يقوم بالتكرار على `constraints.items()`. +يجب أن تُرجع دالة `find_invalid_records` تركيب قائمة يتكرر على `constraints.items()`. ```js ({ test: () => assert(runPython(` @@ -22,7 +22,7 @@ _iter.is_equivalent("constraints.items()") `)) }) ``` -يجب أن تُعيد دالة `find_invalid_records` فهم قائمة يستخدم `key, value` للتكرار على `constraints.items()`. +يجب أن تُرجع دالة `find_invalid_records` تركيب قائمة يستخدم `key, value` للتكرار على `constraints.items()`. ```js ({ test: () => assert(runPython(` @@ -31,7 +31,7 @@ _target.is_equivalent("key, value") `)) }) ``` -يجب أن تُعيد دالة `find_invalid_records` فهم قائمة يُقيّم `key` لكل `key, value` في `constraints.items()`. +يجب أن تُرجع دالة `find_invalid_records` تركيب قائمة يقيم `key` لكل `key, value` في `constraints.items()`. ```js ({ test: () => assert(runPython(` @@ -87,14 +87,14 @@ def find_invalid_records( ): constraints = { 'patient_id': isinstance(patient_id, str) - and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, 'medications': isinstance(medications, list) and all([isinstance(i, str) for i in medications]), 'last_visit_id': isinstance(last_visit_id, str) - and re.fullmatch('v\d+', last_visit_id, re.IGNORECASE) + and re.fullmatch(r'v\d+', last_visit_id, re.IGNORECASE) } --fcc-editable-region-- return constraints diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68517af94b02d6cc2bc08280.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68517af94b02d6cc2bc08280.md index 6ee726bded8..d912a3f8001 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68517af94b02d6cc2bc08280.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68517af94b02d6cc2bc08280.md @@ -102,14 +102,14 @@ def find_invalid_records( ): constraints = { 'patient_id': isinstance(patient_id, str) - and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, 'medications': isinstance(medications, list) and all([isinstance(i, str) for i in medications]), 'last_visit_id': isinstance(last_visit_id, str) - and re.fullmatch('v\d+', last_visit_id, re.IGNORECASE) + and re.fullmatch(r'v\d+', last_visit_id, re.IGNORECASE) } --fcc-editable-region-- return [key for key, value in constraints.items()] diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68529393dcd6a5c80de570fc.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68529393dcd6a5c80de570fc.md index bf991fc20cf..890d3a2c051 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68529393dcd6a5c80de570fc.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68529393dcd6a5c80de570fc.md @@ -66,14 +66,14 @@ def find_invalid_records( ): constraints = { 'patient_id': isinstance(patient_id, str) - and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, 'medications': isinstance(medications, list) and all([isinstance(i, str) for i in medications]), 'last_visit_id': isinstance(last_visit_id, str) - and re.fullmatch('v\d+', last_visit_id, re.IGNORECASE) + and re.fullmatch(r'v\d+', last_visit_id, re.IGNORECASE) } return [key for key, value in constraints.items() if not value] diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685294b4a1ccb3de0e40410c.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685294b4a1ccb3de0e40410c.md index e0d4fc7fc6a..df3d7ac7568 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685294b4a1ccb3de0e40410c.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/685294b4a1ccb3de0e40410c.md @@ -76,14 +76,14 @@ def find_invalid_records( ): constraints = { 'patient_id': isinstance(patient_id, str) - and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, 'medications': isinstance(medications, list) and all([isinstance(i, str) for i in medications]), 'last_visit_id': isinstance(last_visit_id, str) - and re.fullmatch('v\d+', last_visit_id, re.IGNORECASE) + and re.fullmatch(r'v\d+', last_visit_id, re.IGNORECASE) } return [key for key, value in constraints.items() if not value] diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68529fb26c581f13e901de3a.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68529fb26c581f13e901de3a.md index d322de1243f..af74b7b89fd 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68529fb26c581f13e901de3a.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/68529fb26c581f13e901de3a.md @@ -137,14 +137,14 @@ def find_invalid_records( ): constraints = { 'patient_id': isinstance(patient_id, str) - and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, 'medications': isinstance(medications, list) and all([isinstance(i, str) for i in medications]), 'last_visit_id': isinstance(last_visit_id, str) - and re.fullmatch('v\d+', last_visit_id, re.IGNORECASE) + and re.fullmatch(r'v\d+', last_visit_id, re.IGNORECASE) } return [key for key, value in constraints.items() if not value] @@ -231,14 +231,14 @@ def find_invalid_records( ): constraints = { 'patient_id': isinstance(patient_id, str) - and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, 'medications': isinstance(medications, list) and all([isinstance(i, str) for i in medications]), 'last_visit_id': isinstance(last_visit_id, str) - and re.fullmatch('v\d+', last_visit_id, re.IGNORECASE) + and re.fullmatch(r'v\d+', last_visit_id, re.IGNORECASE) } return [key for key, value in constraints.items() if not value] diff --git a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6852c7f62711efe79f8a4219.md b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6852c7f62711efe79f8a4219.md index e340fa74b4e..edd344ae2fb 100644 --- a/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6852c7f62711efe79f8a4219.md +++ b/curriculum/challenges/arabic/blocks/workshop-medical-data-validator/6852c7f62711efe79f8a4219.md @@ -70,14 +70,14 @@ def find_invalid_records( ): constraints = { 'patient_id': isinstance(patient_id, str) - and re.fullmatch('p\d+', patient_id, re.IGNORECASE), + and re.fullmatch(r'p\d+', patient_id, re.IGNORECASE), 'age': isinstance(age, int) and age >= 18, 'gender': isinstance(gender, str) and gender.lower() in ('male', 'female'), 'diagnosis': isinstance(diagnosis, str) or diagnosis is None, 'medications': isinstance(medications, list) and all([isinstance(i, str) for i in medications]), 'last_visit_id': isinstance(last_visit_id, str) - and re.fullmatch('v\d+', last_visit_id, re.IGNORECASE) + and re.fullmatch(r'v\d+', last_visit_id, re.IGNORECASE) } return [key for key, value in constraints.items() if not value] diff --git a/curriculum/challenges/arabic/blocks/workshop-movie-ticket-booking-calculator/6958de0d773289a89515a6b8.md b/curriculum/challenges/arabic/blocks/workshop-movie-ticket-booking-calculator/6958de0d773289a89515a6b8.md index 0be7ea9ac28..e6123621c20 100644 --- a/curriculum/challenges/arabic/blocks/workshop-movie-ticket-booking-calculator/6958de0d773289a89515a6b8.md +++ b/curriculum/challenges/arabic/blocks/workshop-movie-ticket-booking-calculator/6958de0d773289a89515a6b8.md @@ -7,6 +7,14 @@ dashedName: step-4 # --description-- +معامل أكبر من أو يساوي (`>=`) يتحقق مما إذا كانت القيمة على يساره أكبر من أو تساوي القيمة على يمينه. على عكس معامل أكبر من (`>`)، فإن `>=` تُقيّم أيضًا إلى `True` عندما تكون القيمتان متساويتين: + +```py +score = 50 +print(score > 50) # False +print(score >= 50) # True +``` + الآن ستتحقق مما إذا كان يُسمح للمستخدم بحجز عرض مسائي بناءً على عمره. أنشئ جملة `if` للتحقق مما إذا كانت قيمة `age` أكبر من أو تساوي `21`. داخل جسم جملة الـ `if`، اطبع `User is eligible for Evening shows`. diff --git a/curriculum/challenges/arabic/blocks/workshop-pin-extractor/6852db755c9c1274d75aae9a.md b/curriculum/challenges/arabic/blocks/workshop-pin-extractor/6852db755c9c1274d75aae9a.md index bcbffb6d88b..fa7076eacdf 100644 --- a/curriculum/challenges/arabic/blocks/workshop-pin-extractor/6852db755c9c1274d75aae9a.md +++ b/curriculum/challenges/arabic/blocks/workshop-pin-extractor/6852db755c9c1274d75aae9a.md @@ -7,9 +7,9 @@ dashedName: step-1 # --description-- -في هذه الورشة ستنشئ مستخرج رمز PIN، حيث تكون أرقام الرمز مخفية في كل سطر من قصيدة. +في هذه الورشة، ستنشئ مستخرج رمز PIN. أرقام الـ PIN مخفية في كل سطر من قصيدة. -ابدأ بإنشاء دالة تسمى `pin_extractor` مع معلمة `poem`. الدالة الفارغة تُعطي خطأ، لذا أضف `pass` داخل الدالة مؤقتًا لجعلها صالحة. +ابدأ بإنشاء دالة تسمى `pin_extractor` مع معلمة `poem`. الدالة التي لا تحتوي على جسم ترجع خطأ، لذا أضف `pass` داخل الدالة كعنصر نائب مؤقت لجعلها صالحة. # --hints-- diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6740495ba48aa94e5667b436.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6740495ba48aa94e5667b436.md index 1fd4d11da3f..7b8971e562a 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6740495ba48aa94e5667b436.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6740495ba48aa94e5667b436.md @@ -33,7 +33,9 @@ export function multiply(a, b) { ```js const explorer = await __helpers.Explorer(code); const { Navbar } = explorer.allFunctions; -assert.isTrue(Navbar?.toString().startsWith("export")); +assert.exists(Navbar); +const stripped = __helpers.removeJSComments(code).replace(/(["'`])(?:\\.|(?!\1).)*\1/gs, '""'); +assert.match(stripped, /export\s+(?:(?:const|let|var|function)\s+Navbar\b|\{(?:[^}]*,)?\s*(?:\w+\s+as\s+)?Navbar\s*(?:,[^}]*)?\})/); ``` # --seed-- @@ -55,7 +57,7 @@ assert.isTrue(Navbar?.toString().startsWith("export")); type="text/babel" src="index.jsx" > - +
@@ -65,8 +67,8 @@ assert.isTrue(Navbar?.toString().startsWith("export")); data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -119,7 +121,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -156,8 +158,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/67457ff2dc531fbed928a0f0.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/67457ff2dc531fbed928a0f0.md index 3a826ece7c9..cfec03d4ae2 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/67457ff2dc531fbed928a0f0.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/67457ff2dc531fbed928a0f0.md @@ -61,7 +61,7 @@ assert.equal(document.querySelector('nav')?.getAttribute('class'), 'navbar'); type="text/babel" src="index.jsx" > - +
@@ -71,8 +71,8 @@ assert.equal(document.querySelector('nav')?.getAttribute('class'), 'navbar'); data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -125,7 +125,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -162,8 +162,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c732dbeb7c04f346e6f7.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c732dbeb7c04f346e6f7.md index b7b220a5bed..c32290cefb2 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c732dbeb7c04f346e6f7.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c732dbeb7c04f346e6f7.md @@ -42,7 +42,7 @@ assert.lengthOf(document.querySelectorAll('ul li'), 3); type="text/babel" src="index.jsx" > - +
@@ -52,8 +52,8 @@ assert.lengthOf(document.querySelectorAll('ul li'), 3); data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -106,7 +106,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -143,8 +143,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c7b06a0b530602cb63fa.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c7b06a0b530602cb63fa.md index 8f4fed83873..9782e9378ca 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c7b06a0b530602cb63fa.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c7b06a0b530602cb63fa.md @@ -38,7 +38,7 @@ assert.isTrue(document.querySelectorAll('ul li')[2]?.classList.contains('nav-ite type="text/babel" src="index.jsx" > - +
@@ -48,8 +48,8 @@ assert.isTrue(document.querySelectorAll('ul li')[2]?.classList.contains('nav-ite data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -102,7 +102,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -139,8 +139,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c89fba004707ded84453.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c89fba004707ded84453.md index 9b07a35f320..d3308f3f967 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c89fba004707ded84453.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745c89fba004707ded84453.md @@ -14,19 +14,19 @@ dashedName: step-5 يجب أن تنشئ عنصر `a` داخل أول عنصر `li` لديك. ```js -assert.exists(document.querySelector('li a')); +assert.exists(document.querySelector('li:nth-of-type(1) a')); ``` -يجب أن يحتوي عنصر `a` الخاص بك على خاصية `href` بقيمة `#`. +يجب أن يحتوي عنصر `a` على خاصية `href` بقيمة `#`. ```js -assert.equal(document.querySelector('a')?.getAttribute('href'), '#'); +assert.equal(document.querySelector('li:nth-of-type(1) a')?.getAttribute('href'), '#'); ``` يجب أن يحتوي عنصر `a` على النص `Dashboard`. ```js -assert.equal(document.querySelector('a')?.textContent, 'Dashboard'); +assert.equal(document.querySelector('li:nth-of-type(1) a')?.textContent, 'Dashboard'); ``` # --seed-- @@ -48,7 +48,7 @@ assert.equal(document.querySelector('a')?.textContent, 'Dashboard'); type="text/babel" src="index.jsx" > - +
@@ -58,8 +58,8 @@ assert.equal(document.querySelector('a')?.textContent, 'Dashboard'); data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -112,7 +112,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -149,8 +149,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745cebbf97ef2129f3b9bab.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745cebbf97ef2129f3b9bab.md index 89e599a7370..078b9efb154 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745cebbf97ef2129f3b9bab.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745cebbf97ef2129f3b9bab.md @@ -14,19 +14,19 @@ dashedName: step-6 يجب أن تنشئ عنصر `a` داخل العنصر الثاني `li`. ```js -assert.lengthOf(document.querySelectorAll('li a'), 2); +assert.exists(document.querySelector('li:nth-of-type(2) a')); ``` يجب أن يحتوي عنصر `a` على خاصية `href` بقيمة `#`. ```js -assert.equal(document.querySelectorAll('a')[1]?.getAttribute('href'), '#'); +assert.equal(document.querySelector('li:nth-of-type(2) a')?.getAttribute('href'), '#'); ``` يجب أن يحتوي عنصر `a` على النص `Widgets`. ```js -assert.equal(document.querySelectorAll('a')[1]?.textContent, 'Widgets'); +assert.equal(document.querySelector('li:nth-of-type(2) a')?.textContent, 'Widgets'); ``` # --seed-- @@ -48,7 +48,7 @@ assert.equal(document.querySelectorAll('a')[1]?.textContent, 'Widgets'); type="text/babel" src="index.jsx" > - +
@@ -58,8 +58,8 @@ assert.equal(document.querySelectorAll('a')[1]?.textContent, 'Widgets'); data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -112,7 +112,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -149,8 +149,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745d799beeb822076a4da9d.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745d799beeb822076a4da9d.md index 98d9000359d..82024f4fdd8 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745d799beeb822076a4da9d.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745d799beeb822076a4da9d.md @@ -56,7 +56,7 @@ assert.equal( type="text/babel" src="index.jsx" > - +
@@ -66,8 +66,8 @@ assert.equal( data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -120,7 +120,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -157,8 +157,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745d9df333efe2543a1f457.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745d9df333efe2543a1f457.md index 7015355f3ab..5c0a3146765 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745d9df333efe2543a1f457.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745d9df333efe2543a1f457.md @@ -14,19 +14,19 @@ dashedName: step-8 يجب أن تنشئ عنصر `ul` داخل العنصر الثالث `li` الخاص بك. ```js -assert.exists(document.querySelector('li ul')); +assert.exists(document.querySelector('li:nth-of-type(3) ul')); ``` يجب أن يحتوي عنصر `ul` على `className` بقيمة `sub-menu`. ```js -assert.equal(document.querySelector('li ul')?.getAttribute('class'), 'sub-menu'); +assert.equal(document.querySelector('li:nth-of-type(3) ul')?.getAttribute('class'), 'sub-menu'); ``` يجب أن يحتوي عنصر `ul` على `aria-label` بقيمة `Apps`. ```js -assert.equal(document.querySelector('li ul')?.getAttribute('aria-label'), 'Apps'); +assert.equal(document.querySelector('li:nth-of-type(3) ul')?.getAttribute('aria-label'), 'Apps'); ``` # --seed-- @@ -48,7 +48,7 @@ assert.equal(document.querySelector('li ul')?.getAttribute('aria-label'), 'Apps' type="text/babel" src="index.jsx" > - +
@@ -58,8 +58,8 @@ assert.equal(document.querySelector('li ul')?.getAttribute('aria-label'), 'Apps' data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -112,7 +112,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -149,8 +149,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745dce846995b2a466594be.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745dce846995b2a466594be.md index 96272da07bb..2924bc2eb55 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745dce846995b2a466594be.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745dce846995b2a466594be.md @@ -36,7 +36,7 @@ assert.lengthOf(document.querySelectorAll('.sub-menu li'), 3); type="text/babel" src="index.jsx" > - +
@@ -46,8 +46,8 @@ assert.lengthOf(document.querySelectorAll('.sub-menu li'), 3); data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -100,7 +100,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -137,8 +137,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745de9ce925b92d72df713a.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745de9ce925b92d72df713a.md index f8e245ef58e..60050b10d2c 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745de9ce925b92d72df713a.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745de9ce925b92d72df713a.md @@ -14,9 +14,11 @@ dashedName: step-10 يجب أن تنشئ عنصر `a` جديد مع خاصية `href` بقيمة `#` داخل كل من عناصر `li` الثلاثة الجديدة. ```js -assert.equal(document.querySelectorAll('li a')[2]?.getAttribute('href'), '#'); -assert.equal(document.querySelectorAll('li a')[3]?.getAttribute('href'), '#'); -assert.equal(document.querySelectorAll('li a')[4]?.getAttribute('href'), '#'); +const items = document.querySelectorAll('.sub-menu li'); +assert.lengthOf(items, 3); +items.forEach(item => { + assert.equal(item.querySelector('a')?.getAttribute('href'), '#'); +}); ``` # --seed-- @@ -38,7 +40,7 @@ assert.equal(document.querySelectorAll('li a')[4]?.getAttribute('href'), '#'); type="text/babel" src="index.jsx" > - +
@@ -48,8 +50,8 @@ assert.equal(document.querySelectorAll('li a')[4]?.getAttribute('href'), '#'); data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -102,7 +104,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -139,8 +141,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } diff --git a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745e2aca895c935168e7d91.md b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745e2aca895c935168e7d91.md index 81d4a8e273f..665026b6d54 100644 --- a/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745e2aca895c935168e7d91.md +++ b/curriculum/challenges/arabic/blocks/workshop-reusable-mega-navbar/6745e2aca895c935168e7d91.md @@ -7,28 +7,49 @@ dashedName: step-11 # --description-- -لإنهاء الأمور، عيّن نص العنصر الأول `a` إلى `Calendar`، والثاني إلى `Chat`، والثالث إلى `Email`. +لإنهاء الأمور، عيّن نص العنصر الأول `a` **في `sub-menu`** إلى `Calendar`، والثاني إلى `Chat`، والثالث إلى `Email`. + +أخيرًا، اجعل زر `Apps` وقائمة `sub-menu` يتغيران ديناميكيًا. استخدم `React.useState` لإضافة حالة تتبع ما إذا كانت القائمة الفرعية مفتوحة، وأضف معالِج `onClick` إلى عنصر `button` لتبديلها. عيّن خاصية `aria-expanded` في عنصر `button` إلى `"true"` أو `"false"` (كسلسلة نصية) حسب الحالة. بالنسبة إلى عنصر `ul`، أضف الصنف `sub-menu--open` عندما تكون الحالة true (مع الإبقاء على صنف `sub-menu`). بهذا، يصبح مكوِّن `Navbar` الخاص بك مكتملًا! # --hints-- -يجب أن تعيّن نص العنصر الأول `a` إلى `Calendar`. +يجب أن تعيّن نص العنصر الأول `a` **في `sub-menu`** إلى `Calendar`. + +```js +assert.equal(document.querySelectorAll('.sub-menu a')[0]?.textContent, 'Calendar'); +``` + +يجب أن تعيّن نص العنصر الثاني `a` **في `sub-menu`** إلى `Chat`. ```js -assert.equal(document.querySelectorAll('li a')[2]?.textContent, 'Calendar'); +assert.equal(document.querySelectorAll('.sub-menu a')[1]?.textContent, 'Chat'); ``` -يجب أن تعيّن نص العنصر الثاني `a` إلى `Chat`. +يجب أن تعيّن نص العنصر الثالث `a` **في `sub-menu`** إلى `Email`. ```js -assert.equal(document.querySelectorAll('li a')[3]?.textContent, 'Chat'); +assert.equal(document.querySelectorAll('.sub-menu a')[2]?.textContent, 'Email'); ``` -يجب أن تعيّن نص العنصر الثالث `a` إلى `Email`. +يجب أن تدمج حالة React لتبديل الخاصية `aria-expanded` والصنف `sub-menu--open`. ```js -assert.equal(document.querySelectorAll('li a')[4]?.textContent, 'Email'); +const button = document.querySelector('button'); +const subMenu = document.querySelector('.sub-menu'); +assert.equal(button?.getAttribute('aria-expanded'), 'false'); +assert.isFalse(subMenu?.classList.contains('sub-menu--open')); + +button.click(); +await new Promise(resolve => setTimeout(resolve, 0)); +assert.equal(button?.getAttribute('aria-expanded'), 'true'); +assert.isTrue(subMenu?.classList.contains('sub-menu--open')); + +button.click(); +await new Promise(resolve => setTimeout(resolve, 0)); +assert.equal(button?.getAttribute('aria-expanded'), 'false'); +assert.isFalse(subMenu?.classList.contains('sub-menu--open')); ``` # --seed-- @@ -50,7 +71,7 @@ assert.equal(document.querySelectorAll('li a')[4]?.textContent, 'Email'); type="text/babel" src="index.jsx" > - +
@@ -60,8 +81,8 @@ assert.equal(document.querySelectorAll('li a')[4]?.textContent, 'Email'); data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -114,7 +135,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -151,14 +172,14 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } ``` ```jsx +--fcc-editable-region-- export const Navbar = () => { return ( ); }; +--fcc-editable-region-- ``` # --solutions-- @@ -202,7 +222,7 @@ export const Navbar = () => { type="text/babel" src="index.jsx" > - +
@@ -212,8 +232,8 @@ export const Navbar = () => { data-presets="react" data-type="module" > - import { Navbar } from './index.jsx'; - ReactDOM.createRoot(document.getElementById('root')).render( + import { Navbar } from "./index.jsx"; + ReactDOM.createRoot(document.getElementById("root")).render( ); @@ -266,7 +286,7 @@ body { button { background: transparent; border: none; - font-family: 'Times New Roman', Times, serif; + font-family: "Times New Roman", Times, serif; padding: 10px; font-size: 1rem; } @@ -303,8 +323,7 @@ button:hover { } } -.navbar ul .nav-item:hover .sub-menu, -.navbar ul .nav-item:focus-within .sub-menu { +.navbar ul .nav-item .sub-menu.sub-menu--open { visibility: visible; opacity: 1; } @@ -312,6 +331,8 @@ button:hover { ```jsx export const Navbar = () => { + const [isOpen, setIsOpen] = React.useState(false); + return ( - ) -} + ); +}; ``` diff --git a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md b/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e21ba8acb466c97ccbee6.md similarity index 62% rename from curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md rename to curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e21ba8acb466c97ccbee6.md index 30b504aec32..d9713d9fb36 100644 --- a/curriculum/challenges/arabic/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md +++ b/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e21ba8acb466c97ccbee6.md @@ -1,6 +1,6 @@ --- id: 647e21ba8acb466c97ccbee6 -title: أضف منطق القرار إلى كودك باستخدام جمل if و else و else if في C# +title: أضف منطق القرار إلى كودك في C# challengeType: 19 dashedName: add-decision-logic-to-your-code-using-if-else-and-else-if-statements-in-c-sharp --- @@ -9,12 +9,12 @@ dashedName: add-decision-logic-to-your-code-using-if-else-and-else-if-statements سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: -1. اذهب إلى https://learn.microsoft.com/training/modules/csharp-if-elseif-else/ وأكمل جميع المهام في وحدة "أضف منطق القرار إلى كودك باستخدام جمل if و else و else if في C#". هذا **مطلوب** للحصول على جائزة "إنشاء وتشغيل تطبيقات وحدة التحكم البسيطة بلغة C#" على Microsoft Learn، وللتأهل لاختبار الشهادة. +1. اذهب إلى https://learn.microsoft.com/training/modules/csharp-if-elseif-else/ وأكمل جميع المهام في وحدة "أضف منطق القرار إلى كودك في C#". هذا **مطلوب** للحصول على جائزة "اكتب كودك الأول باستخدام C#" على Microsoft Learn، وللتأهل لاختبار الشهادة. 1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. # --assignment-- -أكمل وحدة أضف منطق القرار إلى كودك باستخدام جمل `if` و `else` و `else if` في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. +أكمل وحدة أضف منطق القرار إلى كودك في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. # --questions-- diff --git a/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md b/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md deleted file mode 100644 index b9bf95096b2..00000000000 --- a/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e235a8acb466c97ccbf00.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -id: 647e235a8acb466c97ccbf00 -title: مشروع موجه - حساب وطباعة درجات الطلاب -challengeType: 19 -dashedName: guided-project-calculate-and-print-student-grades ---- - -# --description-- - -سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: - -1. اذهب إلى https://learn.microsoft.com/training/modules/guided-project-calculate-print-student-grades/ وأكمل جميع المهام في وحدة "المشروع الموجه - حساب وطباعة درجات الطلاب". هذا **مطلوب** للحصول على جائزة "اكتب كودك الأول باستخدام C#" على Microsoft Learn، وللتأهل لاختبار الشهادة. -1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. - -# --assignment-- - -أكمل مشروع حساب وطباعة درجات الطلاب الموجه على Microsoft Learn. ثم أجب عن السؤال أدناه. - -# --questions-- - -## --text-- - -ما الخطأ في الكود التالي؟ - -```csharp -int sophiaSum; -Console.WriteLine("Sophia: " + sophiaSum); -``` - -## --answers-- - -`sophiaSum` لم يُهيأ قبل الاستخدام - ---- - -`sophiaSum` لم يُحدد نوعه ضمنيًا كسلسلة نصية - ---- - -يجب أن يستخدم `sophiaSum` الكلمة المفتاحية var - -## --video-solution-- - -1 diff --git a/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md b/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md deleted file mode 100644 index 51e3703bead..00000000000 --- a/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e236d8acb466c97ccbf01.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -id: 647e236d8acb466c97ccbf01 -title: مشروع موجه - حساب المعدل التراكمي النهائي -challengeType: 19 -dashedName: guided-project-calculate-final-gpa ---- - -# --description-- - -سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: - -1. انتقل إلى https://learn.microsoft.com/training/modules/guided-project-calculate-final-gpa/ وأكمل جميع المهام في وحدة "المشروع الموجه - حساب المعدل التراكمي النهائي". هذا **مطلوب** للحصول على جائزة "اكتب كودك الأول باستخدام C#" على Microsoft Learn، وللتأهل لاختبار الشهادة. -1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. - -# --assignment-- - -أكمل مشروع حساب المعدل التراكمي النهائي الموجه على Microsoft Learn. ثم أجب عن السؤال أدناه. - -# --questions-- - -## --text-- - -افترض أن `decimal gradePointAverage = 3.99872831m;`. - -ما قيمة `(int) gradePointAverage`؟ - -## --answers-- - -3.99 - ---- - -4 - ---- - -3 - -## --video-solution-- - -3 diff --git a/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md b/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md deleted file mode 100644 index c50f680d034..00000000000 --- a/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e23828acb466c97ccbf03.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e23828acb466c97ccbf03 -title: تنفيذ تنسيق سلسلة نصية أساسي في C# -challengeType: 19 -dashedName: perform-basic-string-formatting-in-c-sharp ---- - -# --description-- - -سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: - -1. اذهب إلى https://learn.microsoft.com/training/modules/csharp-basic-formatting/ وأكمل جميع المهام في وحدة "أداء تنسيق سلسلة نصية أساسي في C#". هذا **مطلوب** للحصول على جائزة "اكتب كودك الأول باستخدام C#" على Microsoft Learn، وللتأهل لاختبار الشهادة. -1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. - -# --assignment-- - -أكمل وحدة تنفيذ تنسيق سلسلة نصية أساسي في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. - -# --questions-- - -## --text-- - -أي من أسطر الكود التالية يستخدم استيفاء السلسلة النصية بشكل صحيح بافتراض أن المتغير `value` هو سلسلة نصية؟ - -## --answers-- - -`Console.WriteLine(@"My value: {value}");` - ---- - -`Console.WriteLine($"My value: {value}");` - ---- - -`Console.WriteLine(@"My value: [value]");` - -## --video-solution-- - -2 diff --git a/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e238f8acb466c97ccbf04.md b/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e238f8acb466c97ccbf04.md index 485d7f90e96..f7195fd8fec 100644 --- a/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e238f8acb466c97ccbf04.md +++ b/curriculum/challenges/arabic/blocks/write-your-first-code-using-c-sharp/647e238f8acb466c97ccbf04.md @@ -1,6 +1,6 @@ --- id: 647e238f8acb466c97ccbf04 -title: تخزين واسترجاع البيانات باستخدام القيم الحرفية والمتغيرة في C# +title: تخزين البيانات باستخدام المتغيرات في C# challengeType: 19 dashedName: store-and-retrieve-data-using-literal-and-variable-values-in-c-sharp --- @@ -9,12 +9,12 @@ dashedName: store-and-retrieve-data-using-literal-and-variable-values-in-c-sharp سيُنجز هذا التحدي جزئيًا على منصة Microsoft Learn. اتبع هذه التعليمات لإكمال التحدي: -1. انتقل إلى https://learn.microsoft.com/training/modules/csharp-literals-variables/ وأكمل جميع المهام في وحدة "تخزين واسترجاع البيانات باستخدام القيم الحرفية والمتغيرة في C#". هذا مطلوب للحصول على جائزة "اكتب كودك الأول باستخدام C#" على Microsoft Learn، وللتأهل لاختبار الشهادة. +1. انتقل إلى https://learn.microsoft.com/training/modules/csharp-literals-variables/ وأكمل جميع المهام في وحدة "تخزين البيانات باستخدام المتغيرات في C#". هذا مطلوب للحصول على جائزة "اكتب كودك الأول باستخدام C#" على Microsoft Learn، وللتأهل لاختبار الشهادة. 1. عند الانتهاء، عد وأجب عن السؤال أدناه بشكل صحيح. # --assignment-- -أكمل وحدة تخزين واسترجاع البيانات باستخدام القيم الحرفية والمتغيرة في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. +أكمل وحدة تخزين البيانات باستخدام المتغيرات في C# على Microsoft Learn. ثم أجب عن السؤال أدناه. # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/bootstrap/bad87fee1348bd9aedf08845.md b/curriculum/challenges/chinese-traditional/blocks/bootstrap/bad87fee1348bd9aedf08845.md index e79569fa2a0..e7c1373cad1 100644 --- a/curriculum/challenges/chinese-traditional/blocks/bootstrap/bad87fee1348bd9aedf08845.md +++ b/curriculum/challenges/chinese-traditional/blocks/bootstrap/bad87fee1348bd9aedf08845.md @@ -11,9 +11,9 @@ dashedName: use-a-span-to-target-inline-elements 你可以使用 span 來創建行內元素。還記得我們使用 `btn-block` 類別讓按鈕填滿整個列嗎? ```html - + - + ``` 這說明了「行內」元素和「區塊」元素之間的差異。 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md deleted file mode 100644 index 10e234e0d54..00000000000 --- a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21ba8acb466c97ccbee6.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e21ba8acb466c97ccbee6 -title: 使用 C# 中的 if、else 和 else if 述語為你的程式碼添加決策邏輯 -challengeType: 19 -dashedName: add-decision-logic-to-your-code-using-if-else-and-else-if-statements-in-c-sharp ---- - -# --description-- - -此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: - -1. 前往 https://learn.microsoft.com/training/modules/csharp-if-elseif-else/ 並完成「為你的程式碼添加決策邏輯,使用 if、else 和 else if 述語在 C# 中」模組的所有任務。這是獲得 Microsoft Learn 上「創建並執行簡單 C# 主控台應用程式」獎盃並符合認證考試資格的**必要**條件。 -1. 完成後,回來正確回答以下問題。 - -# --assignment-- - -完成 Microsoft Learn 上的 使用 C# 中的 `if`、`else` 和 `else if` 述語為你的程式碼添加決策邏輯 模組。然後,回答以下問題。 - -# --questions-- - -## --text-- - -以下選項中哪一個不是 C# 中有效的運算子? - -## --answers-- - -`%%` - ---- - -`&&` - ---- - -`||` - -## --video-solution-- - -1 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md deleted file mode 100644 index 99871df544f..00000000000 --- a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21c48acb466c97ccbee7.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e21c48acb466c97ccbee7 -title: 使用 C# 從 .NET 類別程式庫呼叫方法 -challengeType: 19 -dashedName: call-methods-from-the-dot-net-class-library-using-c-sharp ---- - -# --description-- - -此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: - -1. 前往 https://learn.microsoft.com/training/modules/csharp-call-methods/ 並完成「使用 C# 從 .NET 類別程式庫呼叫方法」模組的所有任務。這是獲得 Microsoft Learn 上「創建並執行簡單 C# 主控台應用程式」獎盃並符合認證考試資格的**必要**條件。 -1. 完成後,回來正確回答以下問題。 - -# --assignment-- - -完成 Microsoft Learn 上的 使用 C# 從 .NET 類別程式庫呼叫方法 模組。然後,回答以下問題。 - -# --questions-- - -## --text-- - -什麼是物件? - -## --answers-- - -一個記憶體位址。 - ---- - -一個無狀態類別。 - ---- - -一個類別的實體。 - -## --video-solution-- - -3 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md deleted file mode 100644 index 60a9c87a835..00000000000 --- a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21d08acb466c97ccbee8.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e21d08acb466c97ccbee8 -title: 挑戰專案-開發 foreach 和 if-elseif-else 結構來處理陣列資料於 C# -challengeType: 19 -dashedName: challenge-project-develop-foreach-and-if-elseif-else-structures-to-process-array-data-in-c-sharp ---- - -# --description-- - -此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: - -1. 前往 https://learn.microsoft.com/training/modules/challenge-project-arrays-iteration-selection/ 並完成「Challenge Project - Develop foreach and if-elseif-else Structures to Process Array Data in C#」模組的所有任務。這是獲得 Microsoft Learn 上「Create and Run Simple C# Console Applications」獎盃並符合認證考試資格的**必要**條件。 -1. 完成後,回來正確回答以下問題。 - -# --assignment-- - -完成 Microsoft Learn 上的 Develop `foreach` and `if`-`elseif`-`else` Structures to Process Array Data in C# 挑戰專案。然後,回答以下問題。 - -# --questions-- - -## --text-- - -一位開發者正在與另外兩位開發者合作更新一個應用程式群集。開發者們將在更新過程中使用程式碼註解。以下哪一項描述了程式碼註解的適當使用方式? - -## --answers-- - -當進行更新時,開發人員會使用行註解和區塊註解來標示每個單獨的程式碼更新。 - ---- - -當進行更新時,開發人員會保留所有現有的程式碼註解。當舊註解不再適用時,會新增註解來顯示。 - ---- - -當進行更新時,開發者會使用區塊註解來總結變更。 - -## --video-solution-- - -3 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md deleted file mode 100644 index b1e7c627e98..00000000000 --- a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21df8acb466c97ccbee9.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e21df8acb466c97ccbee9 -title: 使用約定、空白和註解在 C# 中創建可讀的程式碼 -challengeType: 19 -dashedName: create-readable-code-with-conventions-whitespace-and-comments-in-c-sharp ---- - -# --description-- - -此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: - -1. 前往 https://learn.microsoft.com/training/modules/csharp-readable-code/ 並完成「Create Readable Code with Conventions, Whitespace, and Comments in C#」模組的所有任務。這是獲得 Microsoft Learn 上「Create and Run Simple C# Console Applications」獎盃並符合認證考試資格的**必要**條件。 -1. 完成後,回來正確回答以下問題。 - -# --assignment-- - -完成 Microsoft Learn 上的 使用慣例、空白和註解在 C# 中創建可讀程式碼 模組。然後,回答以下問題。 - -# --questions-- - -## --text-- - -以下哪一項是使用程式碼註解的錯誤理由? - -## --answers-- - -描述程式碼的高層次意圖。 - ---- - -在以不同方式評估一個特性時,暫時註解掉一行程式碼。 - ---- - -說明新的 C# 關鍵字如何運作。 - -## --video-solution-- - -3 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md deleted file mode 100644 index 1c7eb2eb5aa..00000000000 --- a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e21eb8acb466c97ccbeea.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -id: 647e21eb8acb466c97ccbeea -title: "引導式專案-開發 foreach 和 if-elseif-else 結構以處理 C# 中的陣列資料" -challengeType: 19 -dashedName: guided-project-develop-foreach-and-if-elseif-else-structures-to-process-array-data-in-c-sharp ---- - -# --description-- - -此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: - -1. 前往 https://learn.microsoft.com/training/modules/guided-project-arrays-iteration-selection/ 並完成「Guided Project - Develop foreach and if-elseif-else Structures to Process Array Data in C#」模組的所有任務。這是獲得 Microsoft Learn 上「Create and Run Simple C# Console Applications」獎盃並取得認證考試資格的**必要**條件。 -1. 完成後,回來正確回答以下問題。 - -# --assignment-- - -完成 Microsoft Learn 上的 在 C# 中開發 `foreach` 和 `if`-`elseif`-`else` 結構以處理陣列資料 指導專案。然後,回答以下問題。 - -# --questions-- - -## --text-- - -開發人員撰寫一個應用程式,使用 `foreach` 迴圈來迭代包含 20 個元素的陣列。應用程式完成後,開發人員得知該陣列必須更新為包含 40 個元素。應用程式需要檢查所有 40 個陣列元素。以下哪一項描述所需的程式碼更新? - -## --answers-- - -創建第二個 `foreach` 迴圈,迭代額外的項目。 - ---- - -`foreach` 迴圈不需要任何更改。 - ---- - -將原本的 `foreach` 迴圈放入第二個 `foreach` 迴圈的程式碼區塊中,該迴圈會迭代兩次。 - -## --video-solution-- - -2 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md deleted file mode 100644 index ec4f5f0a75a..00000000000 --- a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/647e22058acb466c97ccbeec.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -id: 647e22058acb466c97ccbeec -title: "使用陣列和 foreach 述語在 C# 中儲存並迭代資料序列" -challengeType: 19 -dashedName: store-and-iterate-through-sequences-of-data-using-arrays-and-the-foreach-statement-in-c-sharp ---- - -# --description-- - -此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: - -1. 前往 https://learn.microsoft.com/training/modules/csharp-arrays/ 並完成「使用陣列和 foreach 述語儲存及迭代資料序列」模組中的所有任務。這是獲得 Microsoft Learn 上「創建並執行簡單 C# 主控台應用程式」獎盃並符合認證考試資格的**必要**條件。 -1. 完成後,回來正確回答以下問題。 - -# --assignment-- - -完成 Microsoft Learn 上的 使用陣列和 `foreach` 述語在 C# 中儲存及迭代資料序列 模組。然後,回答以下問題。 - -# --questions-- - -## --text-- - -以下哪一個 foreach 述語在語法上是正確的? - -## --answers-- - -`foreach (int value of values)` - ---- - -`foreach (int value with values)` - ---- - -`foreach (int value in values)` - - -## --video-solution-- - -3 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md new file mode 100644 index 00000000000..0297b71daa7 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7679fd5ceb2af42aa67.md @@ -0,0 +1,39 @@ +--- +id: 6ac3f7679fd5ceb2af42aa67 +title: 使用迴圈在 C# 中重複動作 +challengeType: 19 +dashedName: repeat-actions-with-loops-in-c-sharp +--- + +# --description-- + +此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: + +1. 前往 https://learn.microsoft.com/en-us/training/modules/csharp-repeat-actions-loops/ 並完成「使用迴圈在 C# 中重複動作」模組的所有任務。這是取得 Microsoft Learn 上「創建和執行簡單 C# 主控台應用程式」獎盃並符合認證考試資格的**必要條件**。 +1. 完成後,回來正確回答以下問題。 + +# --assignment-- + +在 Microsoft Learn 完成使用迴圈在 C# 中重複動作模組。然後,回答以下問題。 + +# --questions-- + +## --text-- + +當你事先知道要重複動作的次數時,哪種迴圈最適合使用? + +## --answers-- + +`while` 迴圈。 + +--- + +`for` 迴圈。 + +--- + +`if` 述語。 + +## --video-solution-- + +2 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md new file mode 100644 index 00000000000..d06bea228e3 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f76d9fd5ceb2af42aa68.md @@ -0,0 +1,39 @@ +--- +id: 6ac3f76d9fd5ceb2af42aa68 +title: 使用 C# 的陣列和列表組織資料 +challengeType: 19 +dashedName: organize-data-with-arrays-and-lists-in-c-sharp +--- + +# --description-- + +此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: + +1. 前往 https://learn.microsoft.com/en-us/training/modules/csharp-arrays-lists/ 並完成「使用 C# 的陣列和列表組織資料」模組的所有任務。這是取得 Microsoft Learn 上「創建和執行簡單 C# 主控台應用程式」獎盃並符合認證考試資格的**必要條件**。 +1. 完成後,回來正確回答以下問題。 + +# --assignment-- + +完成 Microsoft Learn 上的 使用 C# 的陣列和列表組織資料 模組。然後回答以下問題。 + +# --questions-- + +## --text-- + +哪個方法會將新的條款新增到 `List` 的結尾? + +## --answers-- + +`.Append()` + +--- + +`.Insert()` + +--- + +`.Add()` + +## --video-solution-- + +3 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md new file mode 100644 index 00000000000..795a97aeec8 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f7739fd5ceb2af42aa69.md @@ -0,0 +1,39 @@ +--- +id: 6ac3f7739fd5ceb2af42aa69 +title: 在 C# 中撰寫可重複使用的程式碼 +challengeType: 19 +dashedName: write-reusable-code-in-c-sharp +--- + +# --description-- + +此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: + +1. 前往 https://learn.microsoft.com/en-us/training/modules/csharp-reusable-code/ 並完成「在 C# 中撰寫可重複使用的程式碼」模組的所有任務。這是獲得 Microsoft Learn 上「創建與執行簡單 C# 主控台應用程式」獎盃並符合認證考試資格的**必要條件**。 +1. 完成後,回來正確回答以下問題。 + +# --assignment-- + +完成 Microsoft Learn 上的 在 C# 中撰寫可重複使用的程式碼 模組。然後回答以下問題。 + +# --questions-- + +## --text-- + +如果你嘗試將對一個 void 方法的呼叫結果存到變數中,會發生什麼事? + +## --answers-- + +程式碼無法編譯。 + +--- + +變數被設為 null。 + +--- + +變數被設為其型別的預設值。 + +## --video-solution-- + +1 diff --git a/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md new file mode 100644 index 00000000000..1448a50f78f --- /dev/null +++ b/curriculum/challenges/chinese-traditional/blocks/create-and-run-simple-c-sharp-console-applications/6ac3f77a9fd5ceb2af42aa6a.md @@ -0,0 +1,39 @@ +--- +id: 6ac3f77a9fd5ceb2af42aa6a +title: 在 C# 中讀取與寫入檔案 +challengeType: 19 +dashedName: read-and-write-files-in-c-sharp +--- + +# --description-- + +此挑戰將在 Microsoft Learn 平台上部分完成。請遵循這些指示以完成挑戰: + +1. 前往 https://learn.microsoft.com/en-us/training/modules/csharp-read-write-files/ 並完成「在 C# 中讀取與寫入檔案」模組的所有任務。這是取得 Microsoft Learn 上「創建與執行簡單 C# 主控台應用程式」獎盃並符合認證考試資格的**必要條件**。 +1. 完成後,回來正確回答以下問題。 + +# --assignment-- + +完成 Microsoft Learn 上的 在 C# 中讀取與寫入檔案 模組。然後回答以下問題。 + +# --questions-- + +## --text-- + +`File.ReadAllLines()` 傳回什麼? + +## --answers-- + +包含整個檔案的單一字串。 + +--- + +一個字串陣列,每個字串對應檔案中的一行。 + +--- + +檔案中的行數。 + +## --video-solution-- + +2 diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/681cb05adab50c87ddb2e513.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/681cb05adab50c87ddb2e513.md index 2792621f3f1..421d27cc50e 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/681cb05adab50c87ddb2e513.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/681cb05adab50c87ddb2e513.md @@ -9,16 +9,15 @@ dashedName: challenge-2 給定一個表述數字的字串,以及一個介於 2 到 36 的整數進位,判斷該數字在該進位中是否有效。 -- 該字串可能包含整數,以及大寫或小寫字元。 -- 該檢查應該不區分大小寫。 -- 基數可以是 2 到 36 之間的任何數字。 -- 如果每個字元都是給定進位制中有效的數字,則該數字是有效的。 -- 有效進位制的數字範例: - - 基數 2:0-1 - - 八進位:0-7 - - 十進位:0-9 - - 基數 16:0-9 和 A-F - - 進位 36:0-9 和 A-Z +- 這個字串可能包含數字和大寫或小寫字母。 +- 檢查時不區分大小寫。 +- 如果每個字元都是該進位制中有效的數字,則該數字有效。 +- 不同進位制中有效數字的範例: + - 2 進位制:0-1 + - 8 進位制:0-7 + - 10 進位制:0-9 + - 16 進位制:0-9 和 A-F + - 36 進位制:0-9 和 A-Z # --hints-- @@ -118,6 +117,12 @@ assert.isTrue(isValidNumber("AbC", 16)) assert.isTrue(isValidNumber("z", 36)) ``` +`isValidNumber("", 10)` 應該傳回 `false`。 + +```js +assert.isFalse(isValidNumber("", 10)) +``` + # --seed-- ## --seed-contents-- diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/681cb1afdab50c87ddb2e515.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/681cb1afdab50c87ddb2e515.md index 1b5812b43c8..682dca64ad9 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/681cb1afdab50c87ddb2e515.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/681cb1afdab50c87ddb2e515.md @@ -37,7 +37,7 @@ assert.equal(spaceJam("Hello World?!"), "H E L L O W O R L D ? !"); assert.equal(spaceJam("C@t$ & D0g$"), "C @ T $ & D 0 G $"); ``` -`spaceJam("allyourbase")` 應該傳回 `"A L L Y O U R B A S E"`。 +`spaceJam("all your base")` 應該傳回 `"A L L Y O U R B A S E"`。 ```js assert.equal(spaceJam("all your base"), "A L L Y O U R B A S E"); diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a902958.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a902958.md index 3ee4907869d..d2a16c65087 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a902958.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a902958.md @@ -27,6 +27,18 @@ assert.isTrue(isValidIPv4("192.168.1.1")); assert.isTrue(isValidIPv4("0.0.0.0")); ``` +`isValidIPv4("255.255.255.255")` 應該傳回 `true`。 + +```js +assert.isTrue(isValidIPv4("255.255.255.255")); +``` + +`isValidIPv4("208.67.222.222")` 應該傳回 `true`。 + +```js +assert.isTrue(isValidIPv4("208.67.222.222")); +``` + `isValidIPv4("255.01.50.111")` 應該傳回 `false`。 ```js @@ -57,6 +69,24 @@ assert.isFalse(isValidIPv4("192.168.101.")); assert.isFalse(isValidIPv4("192168145213")); ``` +`isValidIPv4("192.168.1.a")` 應該傳回 `false`。 + +```js +assert.isFalse(isValidIPv4("192.168.1.a")); +``` + +`isValidIPv4("192.168.o.1")` 應該傳回 `false`。 + +```js +assert.isFalse(isValidIPv4("192.168.o.1")); +``` + +`isValidIPv4("192.168.1.1a")` 應該傳回 `false`。 + +```js +assert.isFalse(isValidIPv4("192.168.1.1a")); +``` + # --seed-- ## --seed-contents-- diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a90295e.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a90295e.md index 189622b03a4..342b68f063c 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a90295e.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68adce01c0e1144d0a90295e.md @@ -43,7 +43,7 @@ assert.equal(buildAcronym("Federal Bureau of Investigation"), "FBI"); `buildAcronym("For your information")` 應該傳回 `"FYI"`。 ```js -assert.equal(buildAcronym("Light Amplification by Stimulated Emission of Radiation"), "LASER"); +assert.equal(buildAcronym("For your information"), "FYI"); ``` `buildAcronym("By the way")` 應該傳回 `"BTW"`。 diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68af0687ef34c76c28ffa54b.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68af0687ef34c76c28ffa54b.md index d02b9d6f788..f9266f12f4f 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68af0687ef34c76c28ffa54b.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68af0687ef34c76c28ffa54b.md @@ -26,7 +26,7 @@ assert.equal(reverseSentence("world hello"), "hello world"); assert.equal(reverseSentence("push commit git"), "git commit push"); ``` -`reverseSentence("npm install sudo")` 應該傳回 `"sudo install npm"`。 +`reverseSentence("npm install apt sudo")` 應該傳回 `"sudo apt install npm"`。 ```js assert.equal(reverseSentence("npm install apt sudo"), "sudo apt install npm"); diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68b06e589bf2273243814777.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68b06e589bf2273243814777.md index c80763101c7..898517e5d9f 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68b06e589bf2273243814777.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/68b06e589bf2273243814777.md @@ -9,10 +9,10 @@ dashedName: challenge-39 給定油箱的大小、目前的燃料層次和每加侖的價格,傳回將油箱加滿的費用。 -- `tankSize` 是油箱的總容量,單位為加侖。 -- `fuelLevel` 是油箱中目前的燃料量,單位為加侖。 -- `pricePerGallon` 是一加侖燃料的成本。 -- 傳回的值應該以 `"$d.dd"` 格式四捨五入到小數點後兩位。 +- 第一個引數是油箱的總容量(以加侖為單位)。 +- 第二個引數是油箱中目前的燃料量(以加侖為單位)。 +- 第三個引數是一加侖燃料的價格。 +- 傳回的值應四捨五入到小數點後兩位,格式為:`"$d.dd"`。 # --hints-- diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/6939b873185d8e00d453563c.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/6939b873185d8e00d453563c.md index 0c0c7defecc..ce7f893d696 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/6939b873185d8e00d453563c.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/6939b873185d8e00d453563c.md @@ -9,7 +9,7 @@ dashedName: challenge-157 給定 Markdown 中的聯結字串,傳回等價的 HTML 字串。 -Markdown 影像、圖片具有以下格式:`"[link_text](link_url)"`。傳回 HTML `a` 頁籤的字串,其 `href` 設為 `link_url`,並以 `link_text` 作為頁籤內容。 +Markdown 聯結的格式如下:`"[link_text](link_url)"`。傳回 HTML `a` 標記的字串,並將 `href` 設為 `link_url`,`link_text` 作為標記內容。 例如,給定 `"[freeCodeCamp](https://freecodecamp.org/)"` 傳回 `'freeCodeCamp'`; diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/69d03e549613fbdbe21d11e0.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/69d03e549613fbdbe21d11e0.md index 4447b1b9c00..a820cd535bb 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/69d03e549613fbdbe21d11e0.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-javascript/69d03e549613fbdbe21d11e0.md @@ -7,10 +7,10 @@ dashedName: challenge-271 # --description-- -給定一個用藥陣列和一個表示當前時間的字串,傳回你下一次需要服用的藥物以及距離服用時間還有多久。 +給定一個藥物陣列和一個表示當前時間的字串,傳回你下一個需要服用的藥物以及距離服用時間還有多久。 -- 每個藥物的格式為 `[name, lastTaken]`,其中 `name` 是藥物名稱,`lastTaken` 是上次服用時間。 -- 所有給定時間皆為 `"HH:MM"`(24 小時制)格式。 +- 每種藥物包含兩個元素:藥物名稱,接著是最後一次服用的時間。 +- 所有給定的時間皆為 `"HH:MM"`(24 小時制)格式。 使用以下用藥排程: diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb05adab50c87ddb2e513.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb05adab50c87ddb2e513.md index ac5d6c4b644..d0b3da96712 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb05adab50c87ddb2e513.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb05adab50c87ddb2e513.md @@ -9,16 +9,15 @@ dashedName: challenge-2 給定一個表述數字的字串,以及一個介於 2 到 36 的整數進位,判斷該數字在該進位中是否有效。 -- 該字串可能包含整數,以及大寫或小寫字元。 -- 該檢查應該不區分大小寫。 -- 基數可以是 2 到 36 之間的任何數字。 -- 如果每個字元都是給定進位制中有效的數字,則該數字是有效的。 -- 有效進位制的數字範例: - - 基數 2:0-1 - - 八進位:0-7 - - 十進位:0-9 - - 基數 16:0-9 和 A-F - - 進位 36:0-9 和 A-Z +- 字串可能包含數字和大寫或小寫字母。 +- 檢查應該不區分大小寫。 +- 如果每個字元都是該進位制中有效的數字,則該數字有效。 +- 不同進位制中有效數字的範例: + - 進位制 2:0-1 + - 進位制 8:0-7 + - 進位制 10:0-9 + - 進位制 16:0-9 和 A-F + - 進位制 36:0-9 和 A-Z # --hints-- @@ -166,6 +165,15 @@ TestCase().assertIs(is_valid_number("z", 36), True)`) }}) ``` +`is_valid_number("", 10)` 應該傳回 `False`。 + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_number("", 10), False)`) +}}) +``` + # --seed-- ## --seed-contents-- @@ -185,6 +193,9 @@ def is_valid_number(n, base): availableChars = allChars[0:base] + if not newN: + return False + for char in newN: if char not in availableChars: return False diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e515.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e515.md index b6647c9cf3c..d3de1290a56 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e515.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e515.md @@ -49,7 +49,7 @@ TestCase().assertEqual(space_jam("C@t$ & D0g$"), "C @ T $ & D 0 G $")`) }}) ``` -`space_jam("allyourbase")` 應該傳回 `"A L L Y O U R B A S E"`。 +`space_jam("all your base")` 應該傳回 `"A L L Y O U R B A S E"`。 ```js ({test: () => { runPython(` diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e517.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e517.md index f8360227d33..67a02989df6 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e517.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/681cb1afdab50c87ddb2e517.md @@ -13,7 +13,7 @@ dashedName: challenge-6 # --hints-- -`are_anagrams("listen", "silent")` 應該傳回 `true`。 +`are_anagrams("listen", "silent")` 應該傳回 `True`。 ```js ({test: () => { runPython(` @@ -22,7 +22,7 @@ TestCase().assertIs(are_anagrams("listen", "silent"), True)`) }}) ``` -`are_anagrams("School master", "The classroom")` 應該傳回 `true`。 +`are_anagrams("School master", "The classroom")` 應該傳回 `True`。 ```js ({test: () => { runPython(` @@ -31,7 +31,7 @@ TestCase().assertIs(are_anagrams("School master", "The classroom"), True)`) }}) ``` -`are_anagrams("A gentleman", "Elegant man")` 應該傳回 `true`。 +`are_anagrams("A gentleman", "Elegant man")` 應該傳回 `True`。 ```js ({test: () => { runPython(` @@ -40,7 +40,7 @@ TestCase().assertIs(are_anagrams("A gentleman", "Elegant man"), True)`) }}) ``` -`are_anagrams("Hello", "World")` 應該傳回 `false`。 +`are_anagrams("Hello", "World")` 應該傳回 `False`。 ```js ({test: () => { runPython(` @@ -49,7 +49,7 @@ TestCase().assertIs(are_anagrams("Hello", "World"), False)`) }}) ``` -`are_anagrams("apple", "banana")` 應該傳回 `false`。 +`are_anagrams("apple", "banana")` 應該傳回 `False`。 ```js ({test: () => { runPython(` @@ -58,7 +58,7 @@ TestCase().assertIs(are_anagrams("apple", "banana"), False)`) }}) ``` -`are_anagrams("cat", "dog")` 應該傳回 `false`。 +`are_anagrams("cat", "dog")` 應該傳回 `False`。 ```js ({test: () => { runPython(` diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68adce01c0e1144d0a902958.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68adce01c0e1144d0a902958.md index 3fb0986d937..ad2f12acbf6 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68adce01c0e1144d0a902958.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68adce01c0e1144d0a902958.md @@ -33,6 +33,24 @@ TestCase().assertIs(is_valid_ipv4("0.0.0.0"), True)`) }}) ``` +`is_valid_ipv4("255.255.255.255")` 應該傳回 `True`。 + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("255.255.255.255"), True)`) +}}) +``` + +`is_valid_ipv4("208.67.222.222")` 應該傳回 `True`。 + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("208.67.222.222"), True)`) +}}) +``` + `is_valid_ipv4("255.01.50.111")` 應該傳回 `False`。 ```js @@ -78,6 +96,33 @@ TestCase().assertIs(is_valid_ipv4("192168145213"), False)`) }}) ``` +`is_valid_ipv4("192.168.1.a")` 應該傳回 `False`。 + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("192.168.1.a"), False)`) +}}) +``` + +`is_valid_ipv4("192.168.o.1")` 應該傳回 `False`。 + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("192.168.o.1"), False)`) +}}) +``` + +`is_valid_ipv4("192.168.1.1a")` 應該傳回 `False`。 + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(is_valid_ipv4("192.168.1.1a"), False)`) +}}) +``` + # --seed-- ## --seed-contents-- diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68b06e589bf2273243814777.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68b06e589bf2273243814777.md index 4577fe255b8..533899b82fe 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68b06e589bf2273243814777.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68b06e589bf2273243814777.md @@ -9,10 +9,10 @@ dashedName: challenge-39 給定油箱的大小、目前的燃料層次和每加侖的價格,傳回將油箱加滿的費用。 -- `tankSize` 是油箱的總容量,單位為加侖。 -- `fuelLevel` 是油箱中目前的燃料量,單位為加侖。 -- `pricePerGallon` 是一加侖燃料的成本。 -- 傳回的值應該以 `"$d.dd"` 格式四捨五入到小數點後兩位。 +- 第一個引數是油箱的總容量(以加侖為單位)。 +- 第二個引數是油箱中目前的燃料量(以加侖為單位)。 +- 第三個引數是一加侖燃料的價格。 +- 傳回的值應該四捨五入到小數點後兩位,格式為:`"$d.dd"`。 # --hints-- diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68f6587287ad1f4ad39b0c7f.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68f6587287ad1f4ad39b0c7f.md index 97434f0b80e..292b2b6cc76 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68f6587287ad1f4ad39b0c7f.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/68f6587287ad1f4ad39b0c7f.md @@ -58,7 +58,7 @@ TestCase().assertEqual(count("freeCodeCamp"), [5, 7])`) ```js ({test: () => { runPython(` from unittest import TestCase -TestCase().assertEqual(count("Hello World"), [3, 7])`) +TestCase().assertEqual(count("Hello, World!"), [3, 7])`) }}) ``` @@ -67,7 +67,7 @@ TestCase().assertEqual(count("Hello World"), [3, 7])`) ```js ({test: () => { runPython(` from unittest import TestCase -TestCase().assertEqual(count("Hello World"), [3, 7])`) +TestCase().assertEqual(count("The quick brown fox jumps over the lazy dog."), [11, 24])`) }}) ``` diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/6939b873185d8e00d453563c.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/6939b873185d8e00d453563c.md index 76f8beb41ab..2bfd64624d4 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/6939b873185d8e00d453563c.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/6939b873185d8e00d453563c.md @@ -9,7 +9,7 @@ dashedName: challenge-157 給定 Markdown 中的聯結字串,傳回等價的 HTML 字串。 -Markdown 影像、圖片具有以下格式:`"[link_text](link_url)"`。傳回 HTML `a` 頁籤的字串,其 `href` 設為 `link_url`,並以 `link_text` 作為頁籤內容。 +Markdown 聯結的格式如下:`"[link_text](link_url)"`。傳回 HTML `a` 標記的字串,並將 `href` 設為 `link_url`,`link_text` 作為標記內容。 例如,給定 `"[freeCodeCamp](https://freecodecamp.org/)"` 傳回 `'freeCodeCamp'`; diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/697a49e9860d24853adef680.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/697a49e9860d24853adef680.md index 970d1a8bcd0..4e76b02f93a 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/697a49e9860d24853adef680.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/697a49e9860d24853adef680.md @@ -50,7 +50,7 @@ dashedName: challenge-195 # --hints-- -`score_curling([[".", ".", "R", ".", "."], [".", "R", ".", ".", "."], ["Y", ".", ".", ".", "."], [".", "R", ".", ".", "."], [".", ".", ".", ".", "."]])` 應該傳回 `"R:2"`。 +`score_curling([[".", ".", "R", ".", "."], [".", "R", ".", ".", "."], ["Y", ".", ".", ".", "."], [".", "R", ".", ".", "."], [".", ".", ".", ".", "."]])` 應該傳回 `"R: 2"`。 ```js ({test: () => { runPython(` diff --git a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/69d03e549613fbdbe21d11e0.md b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/69d03e549613fbdbe21d11e0.md index 248a7598373..8ae9155c97b 100644 --- a/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/69d03e549613fbdbe21d11e0.md +++ b/curriculum/challenges/chinese-traditional/blocks/daily-coding-challenges-python/69d03e549613fbdbe21d11e0.md @@ -9,8 +9,8 @@ dashedName: challenge-271 給定一個藥物陣列和一個表示當前時間的字串,傳回你下一個需要服用的藥物以及距離服用時間還有多久。 -- 每個藥物的格式為 `[name, lastTaken]`,其中 `name` 是藥物名稱,`lastTaken` 是上次服用時間。 -- 所有給定的時間都將是 `"HH:MM"`(24 小時)格式。 +- 每種藥物包含兩個元素:藥物名稱,接著是最後服用的時間。 +- 所有給定的時間皆為 `"HH:MM"`(24 小時制)格式。 使用以下用藥排程: diff --git a/curriculum/challenges/chinese-traditional/blocks/lab-business-card/6690e10ebe2181212abc9652.md b/curriculum/challenges/chinese-traditional/blocks/lab-business-card/6690e10ebe2181212abc9652.md index 4df1ce71a3e..f7781de60b0 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lab-business-card/6690e10ebe2181212abc9652.md +++ b/curriculum/challenges/chinese-traditional/blocks/lab-business-card/6690e10ebe2181212abc9652.md @@ -102,13 +102,15 @@ assert.exists(document.querySelector('p.company + hr')); 在第一個 `hr` 元素之後,應該有一個 `p` 元素,其文字為電子郵件位址。 ```js -assert.isNotEmpty(document.querySelectorAll('.business-card hr + p')[0].textContent.trim()); +assert.isNotEmpty(document.querySelectorAll('.business-card hr + p')[0]?.textContent.trim()); ``` 在電子郵件的 `p` 元素之後,應該有另一個 `p` 元素,其文字為你的電話號碼。 ```js -assert.match(document.querySelectorAll(".business-card p")[4].textContent,/.+/); +const phoneParagraph = document.querySelectorAll(".business-card p")[4]; +assert.exists(phoneParagraph); +assert.match(phoneParagraph.textContent, /.+/); ``` 在電話號碼 `p` 元素之後,應該有一個帶有 `portfolio-link` 類別的 `a` 元素。 @@ -120,13 +122,13 @@ assert.exists(document.querySelector('a.portfolio-link')); `.portfolio-link` 元素應該有 `Portfolio` 的文字。 ```js -assert.equal(document.querySelector('a.portfolio-link').textContent.trim(), 'Portfolio'); +assert.equal(document.querySelector('a.portfolio-link')?.textContent.trim(), 'Portfolio'); ``` 你的 `.portfolio-link` 元素應該有有效的 `href`。 ```js -assert.isAbove(document.querySelector('.portfolio-link').getAttribute('href').length, 0); +assert.isAbove(document.querySelector('.portfolio-link')?.getAttribute('href')?.length, 0); ``` 在包含你的作品集的 `a` 元素之後,應該有另一個 `hr` 元素作為分隔線。 @@ -211,19 +213,25 @@ const linkHrefValue = document.querySelector('link')?.dataset?.href; assert.strictEqual(linkHrefValue, 'styles.css'); ``` -你應該在 `body` 選擇器中設定頁面背景色為 `rosybrown`。 +你的頁面背景應該是 `rosybrown`。 ```js -assert.strictEqual(new __helpers.CSSHelp(document).getStyle('body')?.getPropVal('background-color'), 'rosybrown'); +const transparent = ['rgba(0, 0, 0, 0)', 'transparent']; +const htmlBackground = getComputedStyle(document.documentElement).backgroundColor; +const bodyBackground = getComputedStyle(document.body).backgroundColor; +const pageBackground = transparent.includes(htmlBackground) ? bodyBackground : htmlBackground; +assert.strictEqual(pageBackground, 'rgb(188, 143, 143)'); ``` -你應該在 `body` 元素中將頁面字型設定為 `Arial`,並以 `sans-serif` 作為備用字型。 +你的頁面整體字型應該是 `Arial`,備用字型為 `sans-serif`。 ```js -const el = new __helpers.CSSHelp(document).getStyle('body')?.getPropVal('font-family'); -const condition1= el === 'Arial, sans-serif'; -const condition2= el === '"Arial", sans-serif'; -assert.isTrue(condition1 || condition2); +const elements = [...document.body.querySelectorAll('*')]; +assert.isNotEmpty(elements); +for (const element of elements) { + const fontFamily = getComputedStyle(element).fontFamily.replace(/["']/g, ''); + assert.match(fontFamily, /^Arial,\s*sans-serif$/i); +} ``` 你的 `.business-card` 選擇器應該有一個 `width` 屬性,值為 `300px`。 @@ -278,17 +286,23 @@ assert.equal(new __helpers.CSSHelp(document).getStyle('.profile-image')?.getProp 你的 `p` 元素應該有上下各 `5px` 的 `margin`。 ```js -const marginTop = new __helpers.CSSHelp(document).getStyle('p')?.getPropVal('margin-top'); -const marginBottom = new __helpers.CSSHelp(document).getStyle('p')?.getPropVal('margin-bottom'); - -assert.equal(marginTop, '5px'); -assert.equal(marginBottom, '5px'); +const paragraphs = [...document.querySelectorAll('p')]; +assert.isNotEmpty(paragraphs); +for (const paragraph of paragraphs) { + const { marginTop, marginBottom } = getComputedStyle(paragraph); + assert.strictEqual(marginTop, '5px'); + assert.strictEqual(marginBottom, '5px'); +} ``` 頁面的聯結不應該有底線。 ```js -assert.equal(new __helpers.CSSHelp(document).getStyle('a')?.getPropVal('text-decoration'), 'none'); +const links = [...document.querySelectorAll('a')]; +assert.isNotEmpty(links); +for (const link of links) { + assert.strictEqual(getComputedStyle(link).textDecorationLine, 'none'); +} ``` # --seed-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lab-device-loan-ledger/69f0a37c3bf194a7c9c62492.md b/curriculum/challenges/chinese-traditional/blocks/lab-device-loan-ledger/69f0a37c3bf194a7c9c62492.md index ec3b0a17880..6f6ab9b859b 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lab-device-loan-ledger/69f0a37c3bf194a7c9c62492.md +++ b/curriculum/challenges/chinese-traditional/blocks/lab-device-loan-ledger/69f0a37c3bf194a7c9c62492.md @@ -29,12 +29,12 @@ const ledger = { 1. 你應該將帳本建模為一個物件,其中每個裝置以其資產標籤作為鍵,並擁有 `type`、`status`、`borrower`(包含 `name` 和 `email`)以及 `dueDate` 屬性。 -1. 你應該實作一個 `checkoutDevice(ledger, assetTag, borrower)` 函式,該函式接收一個帳本物件並複製它,而不改變原始物件。在複製的帳本上,應設定 `borrower` 物件的 `name` 和 `email`,更新 `status` 為 `"CheckedOut"`,並傳回一個形式為 `{ ledger: updatedLedger, message: confirmationString }` 的物件,其中 `message` 包含資產標籤和 `borrower` 物件的 `name`。 +1. 你應該實作一個 `checkoutDevice(ledger, assetTag, borrower)` 函式,該函式接收一個 ledger 物件,並使用 `serializeLedger` 和 `loadLedger` 複製它,而不會改變原本的物件。在複製的物件上,應設定 `borrower` 物件的 `name` 和 `email`,更新 `status` 為 `"CheckedOut"`,並傳回一個形式為 `{ ledger: updatedLedger, message: confirmationString }` 的物件,其中 `message` 包含資產標籤和 `borrower` 物件的 `name`。 - 如果 `assetTag` 在帳本中不存在,該函式應傳回未改變的帳本,並附帶一則包含資產標籤且說明未找到的 `message`。 - 如果該裝置已經是 `"CheckedOut"`,函式應傳回未改變的帳本,保留現有借用者,並附帶一則包含資產標籤且說明裝置已被借出的 `message`。 -1. 你應該實作一個 `checkinDevice(ledger, assetTag)` 函式,該函式接收一個帳本物件並複製它,而不改變原始物件。在複製的帳本上,應清除 `borrower` 物件的 `name` 和 `email`,將 `dueDate` 重設為 `""`,更新 `status` 為 `"CheckedIn"`,並傳回一個形式為 `{ ledger: updatedLedger, message: confirmationString }` 的物件,其中 `message` 包含資產標籤。 +1. 你應該實作一個 `checkinDevice(ledger, assetTag)` 函式,該函式接收一個 ledger 物件,並使用 `serializeLedger` 和 `loadLedger` 複製它,而不會改變原本的物件。在複製的物件上,應清除 `borrower` 物件的 `name` 和 `email`,將 `dueDate` 重設為 `""`,更新 `status` 為 `"CheckedIn"`,並傳回一個形式為 `{ ledger: updatedLedger, message: confirmationString }` 的物件,其中 `message` 包含資產標籤。 - 如果 `assetTag` 在帳本中不存在,該函式應傳回未改變的帳本,並附帶一則包含資產標籤且說明未找到的 `message`。 @@ -87,6 +87,14 @@ checkoutDevice(ledger, "1", { name: "Alice", email: "alice@test.com" }); assert.deepEqual(ledger, original); ``` +你的 `checkoutDevice` 函式應該使用 `serializeLedger` 和 `loadLedger` 來複製 ledger。 + +```js +const source = __helpers.removeJSComments(checkoutDevice.toString()); +assert.match(source, /\bserializeLedger\s*\(/); +assert.match(source, /\bloadLedger\s*\(/); +``` + 你的 `checkoutDevice` 函式應該設定借用者的 `name` 和 `email`,並將 `status` 設為 `"CheckedOut"`。 ```js @@ -161,6 +169,14 @@ checkinDevice(ledger, "1"); assert.deepEqual(ledger, original); ``` +你的 `checkinDevice` 函式應該使用 `serializeLedger` 和 `loadLedger` 來複製 ledger。 + +```js +const source = __helpers.removeJSComments(checkinDevice.toString()); +assert.match(source, /\bserializeLedger\s*\(/); +assert.match(source, /\bloadLedger\s*\(/); +``` + 你的 `checkinDevice` 函式應該清除借用者的 `name` 和 `email`,將 `dueDate` 重設為 `""`,並將 `status` 設為 `"CheckedIn"`。 ```js @@ -313,7 +329,7 @@ function loadLedger(json) { } function checkoutDevice(ledger, assetTag, borrower) { - const updatedLedger = JSON.parse(JSON.stringify(ledger)); + const updatedLedger = loadLedger(serializeLedger(ledger)); if (!updatedLedger[assetTag]) { return { @@ -337,7 +353,7 @@ function checkoutDevice(ledger, assetTag, borrower) { } function checkinDevice(ledger, assetTag) { - const updatedLedger = JSON.parse(JSON.stringify(ledger)); + const updatedLedger = loadLedger(serializeLedger(ledger)); if (!updatedLedger[assetTag]) { return { diff --git a/curriculum/challenges/chinese-traditional/blocks/lab-implement-a-stack/69a92f0b9cc04bb0d5327bb5.md b/curriculum/challenges/chinese-traditional/blocks/lab-implement-a-stack/69a92f0b9cc04bb0d5327bb5.md index dd848ed67b5..3ed9edaf685 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lab-implement-a-stack/69a92f0b9cc04bb0d5327bb5.md +++ b/curriculum/challenges/chinese-traditional/blocks/lab-implement-a-stack/69a92f0b9cc04bb0d5327bb5.md @@ -13,12 +13,12 @@ dashedName: implement-a-stack **使用者故事:** -1. 你應該有一個 `initStack` 函式,回傳一個物件,該物件有一個 `collection` 屬性,並設為空陣列。 -1. 你應該有一個 `push` 函式,能將元素加入堆疊頂端。 -1. 你應該有一個 `pop` 函式,能移除並返回堆疊頂端的元素,若沒有元素則返回 `undefined`。 -1. 你應該有一個 `peek` 函式,能返回堆疊頂端的元素但不移除它,若沒有元素則返回 `undefined`。 -1. 你應該有一個 `isEmpty` 函式,當堆疊沒有元素時返回 `true`,否則返回 `false`。 -1. 你應該有一個 `clear` 函式,能移除堆疊中所有元素。 +1. 你應該有一個 `initStack` 函式,傳回一個物件,該物件的 `collection` 屬性設為空陣列。`collection` 的最後一個元素代表堆疊的頂端。 +1. 你應該有一個 `push` 函式,接受一個堆疊物件和一個元素作為引數,並將該元素加入堆疊頂端,也就是放在堆疊的 `collection` 陣列末端。 +1. 你應該有一個 `pop` 函式,接受一個堆疊物件作為引數,移除並傳回堆疊頂端的元素,如果沒有元素則傳回 `undefined`。 +1. 你應該有一個 `peek` 函式,接受一個堆疊物件作為引數,傳回堆疊頂端的元素但不移除它,如果沒有元素則傳回 `undefined`。 +1. 你應該有一個 `isEmpty` 函式,接受一個堆疊物件作為引數,當堆疊沒有元素時傳回 `true`,否則傳回 `false`。 +1. 你應該有一個 `clear` 函式,接受一個堆疊物件作為引數,移除堆疊 `collection` 中的所有元素。 **注意:** 大多數測試依賴 `initStack` 和 `push` 函式。請先實作它們,因為 `pop`、`peek`、`isEmpty` 和 `clear` 的測試需要先將元素加入堆疊。 @@ -45,7 +45,7 @@ assert.deepEqual(stack.collection, ['first', 'second']); assert.isFunction(pop); ``` -`pop` 函式應該移除並返回堆疊頂端的元素。 +`pop` 函式應該移除並傳回堆疊頂端的元素。 ```js const stack = initStack(); @@ -53,17 +53,19 @@ push(stack, 'first'); push(stack, 'second'); push(stack, 'third'); assert.strictEqual(pop(stack), 'third'); +assert.deepEqual(stack.collection, ['first', 'second']); assert.strictEqual(pop(stack), 'second'); +assert.deepEqual(stack.collection, ['first']); ``` -`pop` 函式應該在堆疊為空時返回 `undefined`。 +如果堆疊為空,`pop` 函式應該傳回 `undefined`。 ```js const stack = initStack(); assert.isUndefined(pop(stack)); ``` -`pop` 函式應該正確返回假值。 +`pop` 函式應該正確傳回假值(falsy values)。 ```js const stack = initStack(); @@ -78,7 +80,7 @@ assert.lengthOf(stack.collection, 0); assert.isFunction(peek); ``` -`peek` 函式應該返回堆疊頂端的元素但不移除它。 +`peek` 函式應該傳回堆疊頂端的元素但不移除它。 ```js const stack = initStack(); @@ -86,16 +88,17 @@ push(stack, 'first'); push(stack, 'second'); assert.strictEqual(peek(stack), 'second'); assert.strictEqual(peek(stack), 'second'); +assert.deepEqual(stack.collection, ['first', 'second']); ``` -`peek` 函式應該在堆疊為空時返回 `undefined`。 +如果堆疊為空,`peek` 函式應該傳回 `undefined`。 ```js const stack = initStack(); assert.isUndefined(peek(stack)); ``` -`peek` 函式應該正確返回假值。 +`peek` 函式應該正確傳回假值(falsy values)。 ```js const stack = initStack(); @@ -109,14 +112,14 @@ assert.strictEqual(peek(stack), 0); assert.isFunction(isEmpty); ``` -`isEmpty` 函式應該在堆疊為空時返回 `true`。 +當堆疊為空時,`isEmpty` 函式應該傳回 `true`。 ```js const stack = initStack(); assert.isTrue(isEmpty(stack)); ``` -`isEmpty` 函式應該在堆疊非空時返回 `false`。 +當堆疊非空時,`isEmpty` 函式應該傳回 `false`。 ```js const stack = initStack(); @@ -124,7 +127,7 @@ push(stack, 'element'); assert.isFalse(isEmpty(stack)); ``` -`isEmpty` 函式應該在頂端元素為假值時返回 `false`。 +當堆疊頂端元素為假值(falsy)時,`isEmpty` 函式應該傳回 `false`。 ```js const stack = initStack(); @@ -132,13 +135,13 @@ push(stack, false); assert.isFalse(isEmpty(stack)); ``` -你應該有一個 `clear` 函式。 +你應該有一個 `clear` 函式(程式)。 ```js assert.isFunction(clear); ``` -`clear` 函式應該移除堆疊中所有元素。 +`clear` 函式應該移除堆疊中的所有元素。 ```js const stack = initStack(); diff --git a/curriculum/challenges/chinese-traditional/blocks/lab-isbn-validator/686b9720ee1d032bd77a480a.md b/curriculum/challenges/chinese-traditional/blocks/lab-isbn-validator/686b9720ee1d032bd77a480a.md index 9ed1245e23a..6d73aeaf5f0 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lab-isbn-validator/686b9720ee1d032bd77a480a.md +++ b/curriculum/challenges/chinese-traditional/blocks/lab-isbn-validator/686b9720ee1d032bd77a480a.md @@ -7,19 +7,23 @@ dashedName: debug-an-isbn-validator # --description-- -ISBN(國際標準書號)是指定給商業書籍的唯一識別符號。它可以是 10 位或 13 位數字,最後一位數字是根據其他數字計算出的檢查碼。 +ISBN(國際標準書號)是分配給商業書籍的唯一識別符號。它的長度為 10 或 13 個字元。最後一個字元是檢查碼,該檢查碼是根據前面的數字計算出來的,這些數字稱為主要字元。 Camperbot 嘗試建置他們自己的 ISBN 驗證器。然而,他們在過程中犯了幾個錯誤。 在這個實驗中,你將修正現有的程式碼並使其正常運作。 -預期行為: 當使用者執行程式時,會顯示提示 `Enter ISBN and length: `。使用者可以以 `ISBN,length` 格式輸入他們想要驗證的 ISBN 碼。ISBN 碼不應包含連字號,後面接著其長度(`10` 或 `13`),兩者以逗號分隔。 +預期行為: +當使用者執行程式時,會顯示提示 `Enter ISBN and length: `。使用者可以以 `ISBN,length` 格式輸入他們想要驗證的 ISBN 碼。輸入 ISBN 時不包含連字號,接著輸入逗號和其長度(`10` 或 `13`)。 範例輸入:`1530051126,10` 用於 ISBN-10 碼。`9781530051120,13` 用於 ISBN-13 碼。 如何尋找檢查碼: -- 你不需要知道這個實驗室中詳細的計算邏輯。函式 `calculate_check_digit_10` 和 `calculate_check_digit_13` 會處理計算並傳回預期的校驗碼字串。 +- 主要字元是 ISBN-10 碼的前 9 個字元,或 ISBN-13 碼的前 12 個字元。它們必須全部是數字。 +- 最後一個字元是給定的檢查碼。預期的檢查碼是根據主要字元計算出來的,只有當兩者相符時,ISBN 碼才有效。 +- 例如,在 ISBN-10 碼 `1530051126` 中,主要字元是 `153005112`,給定的檢查碼是 `6`。在 ISBN-13 碼 `9781530051120` 中,主要字元是 `978153005112`,給定的檢查碼是 `0`。 +- 你不需要知道詳細的計算邏輯。本實驗中的函式(程式)`calculate_check_digit_10` 和 `calculate_check_digit_13` 會負責計算並以字串形式傳回預期的檢查碼。 - ISBN-10 碼的檢查碼可以是從 `0` 到 `9` 的數字或大寫字母 `X`。 - ISBN-13 碼的檢查碼可以是從 `0` 到 `9` 的數字。 @@ -28,41 +32,41 @@ Camperbot 嘗試建置他們自己的 ISBN 驗證器。然而,他們在過程 **使用者故事:** 1. 你應該修正目前程式碼中的 `IndentationError`。 -1. 即使使用者未輸入逗號分隔值,程式也應該處理 `IndexError` 而不會當機。 -1. 當使用者未輸入以逗號分隔的值時,他們應該在主控台看到訊息 `Enter comma-separated values.`,並且程式應該終止。 -1. 即使使用者輸入非數值的長度,程式也應該處理 `ValueError` 而不會當機。 +1. 即使使用者沒有輸入以逗號分隔的值,程式也應該能處理 `IndexError` 而不會崩潰。 +1. 當使用者沒有輸入以逗號分隔的值時,他們應該在主控台看到訊息 `Enter comma-separated values.`,並且程式應該終止。 +1. 即使使用者輸入非數字的長度值,程式也應該能處理 `ValueError` 而不會崩潰。 1. 當使用者輸入非數字的長度值時,他們應該在主控台看到訊息 `Length must be a number.`,並且程式應該終止。 -1. 你應該修正 `validate_isbn` 函式中的離一錯誤。 -1. 你應該修正當使用者輸入有效的 ISBN 碼時,在目前的程式碼中發生的 `TypeError`。 -1. 當使用者輸入有效的 ISBN 代碼時,你應該修正目前程式碼中的 `IndexError`。 -1. 即使使用者輸入包含非數字字元的錯誤 ISBN 控制代碼,程式也應該處理發生的 `ValueError`,而不會當機。 -1. 當使用者輸入包含非數字字元的錯誤 ISBN 程式碼時,他們應該在主控台看到訊息 `Invalid character was found.`。 -1. 當使用者輸入 `1530051126,10` 時,他們應該會看到訊息 `Valid ISBN Code.`。 -1. 當使用者輸入 `9781530051120,13` 時,他們應該會看到訊息 `Valid ISBN Code.` +1. 你應該修正 `validate_isbn` 函式(程式)中的越界錯誤。 +1. 你應該修正目前程式碼中使用者輸入有效 ISBN 碼時發生的 `TypeError`。 +1. 你應該修正目前程式碼中使用者輸入有效 ISBN 碼時發生的 `IndexError`。 +1. 即使使用者輸入的 ISBN 碼主要字元包含非數字字元,程式也應該能處理發生的 `ValueError` 而不會崩潰。 +1. 當使用者輸入的 ISBN 碼主要字元包含非數字字元時,他們應該在主控台看到訊息 `Invalid character was found.`。 +1. 當使用者輸入 `1530051126,10` 時,他們應該看到訊息 `Valid ISBN Code.`。 +1. 當使用者輸入 `9781530051120,13` 時,他們應該看到訊息 `Valid ISBN Code.`。 **重要**:你需要在全域空間中將 `main()` 呼叫註解掉,測試才能正確執行。 當你完成專案時,使用者應該根據他們輸入的值看到以下訊息。 -| ISBN Code | Length | Message | Example input | +| ISBN 碼 | 長度 | 訊息 | 範例輸入 | |-----------|--------|---------| ------------- | -| Valid | Valid | `Valid ISBN Code.` | `1530051126,10` | -| Invalid Number | Valid | `Invalid ISBN Code.` | `1530051125,10` | -| Does not match specified length or left blank | Valid | `ISBN-10 code should be 10 digits long.` or `ISBN-13 code should be 13 digits long.`, depending on the length they entered. | `9781530051120,10` or `1530051126,13` | -| Contains non-numeric characters (except for the check digit) | Valid | `Invalid character was found.` | `15-0051126,10` | -| Any | Invalid Number | `Length should be 10 or 13.` | `1530051126,9` | -| Any | Contains non-numeric characters or left blank | `Length must be a number.` | `1530051125,A` | -| Not comma-separated | Not comma-separated | `Enter comma-separated values.` | `1530051125` | +| 有效 | 有效 | `Valid ISBN Code.` | `1530051126,10` | +| 無效數字 | 有效 | `Invalid ISBN Code.` | `1530051125,10` | +| 與指定長度不符或留空 | 有效 | `ISBN-10 code should be 10 digits long.` 或 `ISBN-13 code should be 13 digits long.`,視輸入的長度而定。 | `9781530051120,10` 或 `1530051126,13` | +| 主要字元包含非數字字元 | 有效 | `Invalid character was found.` | `15-0051126,10` | +| 任意 | 無效數字 | `Length should be 10 or 13.` | `1530051126,9` | +| 任意 | 包含非數字字元或留空 | `Length must be a number.` | `1530051125,A` | +| 非逗號分隔 | 非逗號分隔 | `Enter comma-separated values.` | `1530051125` | 如果你想手動測試你的程式碼,可以使用以下值。 -有效的 ISBN-10 碼範例輸入: -`1530051126,10` -`9971502100,10` +有效的 ISBN-10 碼範例輸入: +`1530051126,10` +`9971502100,10` `080442957X,10` -有效的 ISBN-13 碼範例輸入: -`9781530051120,13` +有效的 ISBN-13 碼範例輸入: +`9781530051120,13` `9781947172104,13` # --hints-- @@ -107,7 +111,7 @@ Camperbot 嘗試建置他們自己的 ISBN 驗證器。然而,他們在過程 }) ``` -當使用者輸入的值不是逗號分隔值時,你應該在主控台看到訊息 `Enter comma-separated values.`。 +當使用者輸入非逗號分隔的值時,你應該在主控台看到訊息 `Enter comma-separated values.`。 ```js ({test: () => {runPython(` @@ -160,7 +164,7 @@ assert "Length must be a number." in out }}) ``` -當使用者輸入包含非數字字元的錯誤 ISBN 程式碼時,你應該在主控台看到訊息 `Invalid character was found.`。 +當使用者輸入的 ISBN 碼主要字元包含非數字字元時,你應該在主控台看到訊息 `Invalid character was found.`。 ```js ({test: () => {runPython(` @@ -241,7 +245,7 @@ assert "Valid ISBN Code." in out }}) ``` -當使用者輸入 `1530051125,10` 時,你應該會看到訊息 `Invalid ISBN Code.`。 +當使用者輸入 `1530051125,10` 時,你應該看到訊息 `Invalid ISBN Code.`。 ```js ({test: () => {runPython(` diff --git a/curriculum/challenges/chinese-traditional/blocks/lab-leap-year-calculator/66c06fad3475cd92421b9ac2.md b/curriculum/challenges/chinese-traditional/blocks/lab-leap-year-calculator/66c06fad3475cd92421b9ac2.md index 73321df3943..7505b9c662e 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lab-leap-year-calculator/66c06fad3475cd92421b9ac2.md +++ b/curriculum/challenges/chinese-traditional/blocks/lab-leap-year-calculator/66c06fad3475cd92421b9ac2.md @@ -22,8 +22,8 @@ dashedName: build-a-leap-year-calculator - 除非該年也能被 `100` 整除,否則它不是閏年。 - 除非該年份也能被 `400` 整除,否則它是閏年。 -5. 如果該年是閏年,傳回 `[year] is a leap year.`。否則,傳回 `[year] is not a leap year.`。你將會用在 `isLeapYear` 函式中定義的參數取代 `[year]`。 -6. 你應該以 `year` 作為引數呼叫 `isLeapYear` 函式,並將結果指定到名為 `result` 的變數。 +5. 如果該年是閏年,傳回 `[year] is a leap year.`。否則,傳回 `[year] is not a leap year.`。你會用 `isLeapYear` 函式中定義的參數來替換 `[year]`。 +6. 你應該宣告一個名為 `result` 的變數,並將呼叫 `isLeapYear` 函式並以 `year` 作為引數所傳回的值指定給它。 7. 你應該使用 `console.log()` 將 `result` 變數輸出到主控台。 # --hints-- @@ -74,10 +74,16 @@ assert.strictEqual(isLeapYear(1900), '1900 is not a leap year.'); ``` +當 `year` 變數的值為 `1901` 時,`result` 應該是 `1901 is not a leap year.` + +```js +assert.strictEqual(isLeapYear(1901), '1901 is not a leap year.'); +``` + 你應該呼叫 `isLeapYear` 函式(程式),並傳遞 `year` 作為參數。 ```js -assert.match(__helpers.removeJSComments(code), /isLeapYear\(\s*year\s*\)/); +assert.match(__helpers.removeJSComments(code), /isLeapYear\s*\(\s*year\s*\)/); ``` 你應該宣告一個 `result` 變數。 @@ -86,16 +92,19 @@ assert.match(__helpers.removeJSComments(code), /isLeapYear\(\s*year\s*\)/); assert.isDefined(result); ``` -你應該將呼叫 `isLeapYear` 函式的結果儲存在名為 `result` 的變數中。 +你應該宣告一個名為 `result` 的變數,並將呼叫 `isLeapYear` 並以 `year` 作為引數所傳回的值指定給它。 ```js -assert.match(__helpers.removeJSComments(code), /result\s*=\s*isLeapYear\(\s*year\s*\)/); +const explorer = await __helpers.Explorer(code); +const { result } = explorer.variables; +assert.exists(result); +assert.isTrue(result.value.matches('isLeapYear(year)')); ``` 你應該使用 `console.log()` 將 `result` 輸出到主控台。 ```js -assert.match(__helpers.removeJSComments(code), /console\.log\(\s*result\s*\)/); +assert.match(__helpers.removeJSComments(code), /console\s*\.\s*log\s*\(\s*result\s*\)/); ``` # --seed-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lab-number-pattern-generator/6842a6cd9836f0114a5b7a8a.md b/curriculum/challenges/chinese-traditional/blocks/lab-number-pattern-generator/6842a6cd9836f0114a5b7a8a.md index d6cd578ff3c..803c81785dc 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lab-number-pattern-generator/6842a6cd9836f0114a5b7a8a.md +++ b/curriculum/challenges/chinese-traditional/blocks/lab-number-pattern-generator/6842a6cd9836f0114a5b7a8a.md @@ -13,11 +13,11 @@ dashedName: build-a-number-pattern-generator **使用者故事:** -1. 你應該定義一個名為 `number_pattern` 的函式(程式),它接受一個單一參數 `n`(表述一個正整數)。 +1. 你應該定義一個名為 `number_pattern` 的函式(程式),它接受一個參數 `n`(代表一個正整數)。 1. `number_pattern` 應該使用 `for` 迴圈。 -1. `number_pattern(n)` 應該傳回一個字串,該字串包含從 1 到 `n`(包含)所有整數,並以空格分隔。 例如,`number_pattern(4)` 應該傳回字串 `1 2 3 4`。 -1. 如果傳遞給函式的引數不是整數值,函式應該傳回 `Argument must be an integer value.`。 -1. 如果傳遞給函式的引數小於 1,該函式應該傳回 `Argument must be an integer greater than 0.`。 +1. `number_pattern(n)` 應該傳回一個字串,包含從 1 到 `n`(含)的所有整數,並以空格分隔。舉例來說,`number_pattern(4)` 應該傳回字串 `1 2 3 4`。 +1. 如果傳入函式的引數不是整數值,函式應該傳回 `Argument must be an integer value.` +1. 如果傳入函式的引數小於 1,函式應該傳回 `Argument must be an integer greater than 0.` # --hints-- @@ -61,7 +61,7 @@ dashedName: build-a-number-pattern-generator }) ``` -`number_pattern` 應該傳回以空格分隔的正整數列表。 +`number_pattern` 應該為任何正整數傳回以空格分隔的數字列表。 ```js ({ diff --git a/curriculum/challenges/chinese-traditional/blocks/lab-rpg-character/67d83df6f82eda3868dd2a84.md b/curriculum/challenges/chinese-traditional/blocks/lab-rpg-character/67d83df6f82eda3868dd2a84.md index 420d980e95f..0857b2fc652 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lab-rpg-character/67d83df6f82eda3868dd2a84.md +++ b/curriculum/challenges/chinese-traditional/blocks/lab-rpg-character/67d83df6f82eda3868dd2a84.md @@ -14,20 +14,20 @@ dashedName: build-an-rpg-character **使用者故事:** 1. 你應該有一個名為 `create_character` 的函式(程式)。 -1. 該函式(程式)應依序接受一個字元名稱,接著是三個屬性:力量、智力和魅力。 -1. 字元名稱應該被驗證: - - 如果字元名稱不是字串,該函式應該傳回 `The character name should be a string`。 - - 如果字元名稱是空字串,該函式應該傳回 `The character should have a name`。 - - 如果字元名稱長度超過 10 個字元,函式應該傳回 `The character name is too long`。 - - 如果字元名稱包含空格,函式應該傳回 `The character name should not contain spaces`。 -1. 這些統計數據也應該被驗證: - - 如果一個或多個統計數據不是整數,該函式應該傳回 `All stats should be integers`。 - - 如果一個或多個統計數據小於 1,該函式(程式)應該傳回 `All stats should be no less than 1`。 - - 如果一個或多個統計數值大於 4,該函式(程式)應該傳回 `All stats should be no more than 4`。 - - 如果所有屬性的總和不等於 7,該函式應該傳回 `The character should start with 7 points`。 -1. 如果所有值都通過驗證,該函式應該傳回一個包含四行的字串: - - 第一行應包含字元名稱 - - 第 2-4 行應以屬性縮寫 `STR`、`INT` 或 `CHA`(依此順序)開頭,接著一個空格,然後是與該屬性值相等數量的實心點(`●`),再以空心點(`○`)補足至 10 個。點數由編輯器提供。 +1. 該函式應依序接受一個角色名稱,接著是三個屬性:力量、智力和魅力。 +1. 角色名稱應該被驗證: + - 如果角色名稱不是字串,函式應傳回 `The character name should be a string`。 + - 如果角色名稱是空字串,函式應傳回 `The character should have a name`。 + - 如果角色名稱長度超過 10 個字元,函式應傳回 `The character name is too long`。 + - 如果角色名稱包含空白,函式應傳回 `The character name should not contain spaces`。 +1. 屬性也應該被驗證: + - 如果一個或多個屬性不是整數,函式應傳回 `All stats should be integers`。 + - 如果一個或多個屬性小於 1,函式應傳回 `All stats should be no less than 1`。 + - 如果一個或多個屬性大於 4,函式應傳回 `All stats should be no more than 4`。 + - 如果所有屬性的總和不等於 7,函式應傳回 `The character should start with 7 points`。 +1. 如果所有值都通過驗證,函式應傳回一個包含四行的字串: + - 第一行應包含角色名稱。 + - 第 2 至 4 行應依序以屬性縮寫 `STR`、`INT`、`CHA` 開頭,接著一個空格,然後是與該屬性值相等數量的實心點(`●`),以及補足到 10 個的空心點(`○`)。例如:如果力量值是 3,則應有 3 個實心點後接 7 個空心點。點的符號已在編輯器中提供。 以下是 `create_character('ren', 4, 2, 1)` 應該傳回的字串: @@ -38,7 +38,7 @@ dashedName: build-an-rpg-character CHA ●○○○○○○○○○ ``` -注意:雖然 `str` 和 `int` 是統計資料的常用縮寫,但請記得這些是 Python 的保留關鍵字,不應用作變數名稱。 +**注意:** 雖然 `str` 和 `int` 是常見的屬性縮寫,但 Python 也使用這些名稱代表字串和整數型別,因此最好避免將它們用作變數名稱。 # --hints-- @@ -54,7 +54,7 @@ assert _Node(_code).has_function('create_character') }) ``` -當 `create_character` 被呼叫且第一個引數是 **非** 字串時,應該傳回 `The character name should be a string`。 +當 `create_character` 被呼叫且第一個引數 **不是** 字串時,應傳回 `The character name should be a string`。 ```js ({ @@ -68,7 +68,7 @@ for wrong_type in wrong_types: }) ``` -當 `create_character` 被呼叫且第一個引數是字串時,不應該傳回 `The character name should be a string`。 +當 `create_character` 被呼叫且第一個引數是字串時,**不應** 傳回 `The character name should be a string`。 ```js ({ @@ -102,7 +102,7 @@ assert create_character('ren', 4, 2, 1) != 'The character should have a name' }) ``` -當 `create_character` 被呼叫且第一個引數長度超過 10 個字元時,應該傳回 `The character name is too long`。 +當 `create_character` 被呼叫且第一個引數長度超過 10 個字元時,應傳回 `The character name is too long`。 ```js ({ @@ -115,7 +115,7 @@ for length in range(11, 27): }) ``` -`create_character` 函式(程式)**不應該**在字元長度不超過 10 個字元時顯示字元過長的訊息。 +當角色名稱長度不超過 10 個字元時,`create_character` 函式**不應**說角色名稱太長。 ```js ({ @@ -128,7 +128,7 @@ for length in range(0, 11): }) ``` -當 `create_character` 被呼叫且第一個引數包含空格時,應該傳回 `The character name should not contain spaces`。 +當 `create_character` 被呼叫且第一個引數包含空白時,應傳回 `The character name should not contain spaces`。 ```js ({ @@ -140,7 +140,7 @@ assert create_character('cha cha', 4, 1, 2) == 'The character name should not co }) ``` -當 `create_character` 被呼叫且第一個引數*不*包含空格時,不應該傳回 `The character name should not contain spaces`。 +當 `create_character` 被呼叫且第一個引數*不*包含空白時,*不應*傳回 `The character name should not contain spaces`。 ```js ({ @@ -152,7 +152,7 @@ assert create_character('chacha', 4, 2, 1) != 'The character name should not con }) ``` -當 `create_character` 被呼叫且第二、第三或第四個引數是 **非** 整數時,應該傳回 `All stats should be integers`。 +當 `create_character` 被呼叫且第二、三或四個引數**不是**整數時,應傳回 `All stats should be integers`。 ```js ({ @@ -168,7 +168,7 @@ for wrong_type in wrong_types: }) ``` -當 `create_character` 被呼叫且第二、第三和第四個引數皆為整數時,不應該傳回 `All stats should be integers`。 +當 `create_character` 被呼叫且第二、三和四個引數都是整數時,**不應**傳回 `All stats should be integers`。 ```js ({ @@ -180,7 +180,7 @@ assert create_character('friend', 4, 2, 1) != 'All stats should be integers' }) ``` -當 `create_character` 被呼叫且第二、第三或第四個引數小於 `1` 時,應該傳回 `All stats should be no less than 1`。 +當 `create_character` 被呼叫且第二、三或四個引數小於 `1` 時,應傳回 `All stats should be no less than 1`。 ```js ({ @@ -199,7 +199,7 @@ assert create_character('ren', 4, 4, -1) == expected }) ``` -當 `create_character` 被呼叫且第二、第三和第四個引數皆不小於 `1` 時,不應該傳回 `All stats should be no less than 1`。 +當 `create_character` 被呼叫且第二、三和四個引數都不小於 `1` 時,**不應**傳回 `All stats should be no less than 1`。 ```js ({ @@ -211,7 +211,7 @@ assert create_character('ren', 4, 2, 1) != 'All stats should be no less than 1' }) ``` -當 `create_character` 被呼叫且第二、第三或第四個引數大於 `4` 時,應該傳回 `All stats should be no more than 4`。 +當 `create_character` 被呼叫且第二、三或四個引數大於 `4` 時,應傳回 `All stats should be no more than 4`。 ```js ({ @@ -225,7 +225,7 @@ assert create_character('ren', 1, 1, 5) == 'All stats should be no more than 4' }) ``` -當 `create_character` 被呼叫且第二、第三和第四個引數皆不超過 `4` 時,不應該傳回 `All stats should be no more than 4`。 +當 `create_character` 被呼叫且第二、三和四個引數都不大於 `4` 時,**不應**傳回 `All stats should be no more than 4`。 ```js ({ @@ -237,7 +237,7 @@ assert create_character('ren', 4, 2, 1) != 'All stats should be no more than 4' }) ``` -當 `create_character` 被呼叫且第二、第三或第四個引數的總和**不等於** `7` 時,應該傳回 `The character should start with 7 points`。 +當傳入 `create_character` 的第二、三和四個引數**不**加總為 `7` 時,`create_character` 應傳回 `The character should start with 7 points`。 ```js ({ @@ -251,7 +251,7 @@ assert create_character('ren', 1, 2, 3) == 'The character should start with 7 po }) ``` -當 `create_character` 被呼叫且第二、第三和第四個引數加總為 `7` 時,不應該傳回 `The character should start with 7 points`。 +當 `create_character` 被呼叫且第二、三和四個引數加總為 `7` 時,**不應**傳回 `The character should start with 7 points`。 ```js ({ @@ -275,7 +275,7 @@ assert create_character('ren', 4, 2, 1) == f'ren\\nSTR ●●●●○○○○ }) ``` -當以有效值呼叫 `create_character` 時,應該輸出所需的字元屬性。 +當 `create_character` 被呼叫且引數有效時,應依要求輸出角色屬性。 ```js ({ @@ -317,7 +317,7 @@ def create_character(character_name, strength, intelligence, charisma): return 'The character name should not contain spaces' if type(strength) != int or type(intelligence) != int or type(charisma) != int: - return 'All stats should be integers' + return 'All stats should be integers' if strength < 1 or intelligence < 1 or charisma < 1: return 'All stats should be no less than 1' if strength > 4 or intelligence > 4 or charisma > 4: diff --git a/curriculum/challenges/chinese-traditional/blocks/lab-travel-weather-planner/694acade1d4afdbce71e5840.md b/curriculum/challenges/chinese-traditional/blocks/lab-travel-weather-planner/694acade1d4afdbce71e5840.md index 1e80a085053..d98efdee537 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lab-travel-weather-planner/694acade1d4afdbce71e5840.md +++ b/curriculum/challenges/chinese-traditional/blocks/lab-travel-weather-planner/694acade1d4afdbce71e5840.md @@ -1,6 +1,6 @@ --- id: 694acade1d4afdbce71e5840 -title: Build a Travel Weather Planner +title: 建置旅遊天氣規劃器 challengeType: 27 dashedName: build-a-travel-weather-planner --- @@ -11,26 +11,27 @@ dashedName: build-a-travel-weather-planner **目標:** 完成以下使用者故事並通過所有測試以完成實驗。 -**User Stories:** +**使用者故事:** 1. 你應該創建以下變數: - * `distance_mi`(一個表述要行駛英里數的數字) - * `is_raining`(一個布林值,表述使用者目前是否正經歷雨天) - * `has_bike`(一個表述使用者是否擁有自行車的布林值) - * `has_car`(一個表述使用者是否有車的布林值) - * `has_ride_share_app`(一個布林值,表述使用者是否有一個允許他們叫車的應用程式) -1. 你應該使用條件述語來根據這些變數的值判斷是否可以通勤。 -1. 你應該使用 `if`、`elif` 和 `else` 述語,依距離類別的遞增順序進行評估。 + * `distance_mi`(一個數字,代表要行駛的英里距離) + * `is_raining`(一個布林值,代表使用者目前是否正經歷下雨天氣) + * `has_bike`(一個布林值,代表使用者是否有自行車) + * `has_car`(一個布林值,代表使用者是否有汽車) + * `has_ride_share_app`(一個布林值,代表使用者是否有可叫車的應用程式) +1. 你應該使用條件述語根據這些變數的值判斷是否能通勤。 +1. 你應該使用 `if`、`elif` 和 `else` 述語,依距離類別由小到大進行評估。 +1. 你應該在程式碼中至少使用一個布林運算子(`and`、`or` 或 `not`)。 1. 如果 `distance_mi` 是假值: * 你應該列印 `False`。 -1. 如果距離**小於或相等於 1 英里**: - * 只有在**沒有下雨**時,你才應該列印 `True`。 +1. 如果距離是**小於或等於 1 英里**: + * 只有當**沒有下雨**時,你才應該列印 `True`。 * 否則,你應該列印 `False`。 -1. 如果距離**大於 1 英里且小於或相等於 6 英里**: - * 只有當該人有腳踏車**且**沒有下雨時,你才應該列印 `True`。 +1. 如果距離是**大於 1 英里且小於或等於 6 英里**: + * 只有當使用者有自行車**且**沒有下雨時,你才應該列印 `True`。 * 否則,你應該列印 `False`。 -1. 如果距離**大於 6 英里**: - * 如果此人有車 **或** 有共乘應用程式,你應該列印 `True`。 +1. 如果距離是**大於 6 英里**: + * 如果使用者有汽車**或**有叫車應用程式,你應該列印 `True`。 * 否則,你應該列印 `False`。 # --hints-- @@ -44,7 +45,7 @@ dashedName: build-a-travel-weather-planner 你應該為你的 `distance_mi` 變數指定一個數字。 ```js -({ test: () => runPython(`assert isinstance(distance_mi, (int, float))`) }) +({ test: () => runPython(`assert isinstance(distance_mi, (int, float)) and not isinstance(distance_mi, bool)`) }) ``` 你應該有一個名為 `is_raining` 的變數。 @@ -135,7 +136,8 @@ tree = ast.parse(_code) bool_ops = [ node for node in ast.walk(tree) - if isinstance(node, (ast.BoolOp, ast.UnaryOp)) + if isinstance(node, ast.BoolOp) + or (isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.Not)) ] assert len(bool_ops) >= 1 @@ -533,6 +535,54 @@ run_case( `) }) ``` +當距離介於 `1` 英里(不含)和 `6` 英里(含)之間,且有自行車但正在下雨時,程式應該列印 `False`。 + +```js +({ test: () => runPython(` +import ast, io, contextlib + +VARIABLES = { + "distance_mi", + "is_raining", + "has_bike", + "has_car", + "has_ride_share_app" +} + +def run_case(env, expected): + tree = ast.parse(_code) + + tree.body = [ + node for node in tree.body + if not ( + isinstance(node, ast.Assign) + and isinstance(node.targets[0], ast.Name) + and node.targets[0].id in VARIABLES + ) + ] + + clean_code = compile(tree, "", "exec") + + buffer = io.StringIO() + with contextlib.redirect_stdout(buffer): + exec(clean_code, env) + + assert buffer.getvalue().strip() == expected + + +run_case( + { + "distance_mi": 2, + "is_raining": True, + "has_bike": True, + "has_car": False, + "has_ride_share_app": False + }, + "False" +) +`) }) +``` + 當距離大於 `6` 英里且共乘應用程式可用時,程式應該列印 `True`。 ```js @@ -578,6 +628,17 @@ run_case( }, "True" ) + +run_case( + { + "distance_mi": 12, + "is_raining": True, + "has_bike": False, + "has_car": False, + "has_ride_share_app": True + }, + "True" +) `) }) ``` @@ -626,10 +687,21 @@ run_case( }, "True" ) + +run_case( + { + "distance_mi": 12, + "is_raining": True, + "has_bike": False, + "has_car": True, + "has_ride_share_app": False + }, + "True" +) `) }) ``` -當距離大於 `6` 英里且沒有車輛或共乘應用程式可用時,程式應該列印 `False`。 +當距離大於 `6` 英里且既沒有汽車也沒有叫車應用程式時,程式應該列印 `False`。 ```js ({ test: () => runPython(` diff --git a/curriculum/challenges/chinese-traditional/blocks/lab-user-configuration-manager/684aaf9ec670c68d20efd0d0.md b/curriculum/challenges/chinese-traditional/blocks/lab-user-configuration-manager/684aaf9ec670c68d20efd0d0.md index 2fce95dc703..ae2f7387f9f 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lab-user-configuration-manager/684aaf9ec670c68d20efd0d0.md +++ b/curriculum/challenges/chinese-traditional/blocks/lab-user-configuration-manager/684aaf9ec670c68d20efd0d0.md @@ -46,8 +46,8 @@ saveSubmissionToDB: true 1. `view_settings` 函式(程式)應該: - - 如果給定的設定字典為空,傳回 `No settings available.`。 - - 如果字典包含任何設定,傳回一個顯示設定的字串。該字串應以 `Current User Settings:` 開頭,接著是鍵值對,每個鍵值對各佔一行且鍵字首字母大寫。為你的例子,`view_settings({'theme': 'dark', 'notifications': 'enabled', 'volume': 'high'})` 應該傳回: + - 如果給定的設定字典是空的,傳回 `No settings available.`。 + - 如果字典中有任何設定,傳回一個顯示設定的字串。該字串應以 `Current User Settings:` 開頭,接著是每個鍵值對,每行一個,且鍵的首字母要大寫,最後一個設定後字串應以換行字元結尾。舉例來說,`view_settings({'theme': 'dark', 'notifications': 'enabled', 'volume': 'high'})` 應該傳回: ```md Current User Settings: @@ -117,7 +117,7 @@ saveSubmissionToDB: true }) ``` -`add_setting({'theme': 'light'}, ('THEME', 'dark'))` 應該傳回錯誤訊息 `Setting 'theme' already exists! Cannot add a new setting with this name.`。 +`add_setting({'theme': 'light', 'language': 'English'}, ('THEME', 'dark'))` 應該傳回錯誤訊息 `Setting 'theme' already exists! Cannot add a new setting with this name.`。 ```js ({ @@ -206,7 +206,7 @@ saveSubmissionToDB: true }) ``` -`update_setting({'theme': 'light'}, ('theme', 'dark'))` 應該更新現有的鍵並傳回成功訊息 `Setting 'theme' updated to 'dark' successfully!`。 +`update_setting({'theme': 'light', 'language': 'English'}, ('theme', 'dark'))` 應該更新現有的鍵並傳回成功訊息 `Setting 'theme' updated to 'dark' successfully!`。 ```js ({ @@ -281,7 +281,7 @@ saveSubmissionToDB: true }) ``` -`delete_setting({'theme': 'light'}, 'theme')` 應該移除現有的鍵並傳回成功的訊息 `Setting 'theme' deleted successfully!`。 +`delete_setting({'theme': 'light', 'language': 'English'}, 'theme')` 應該移除現有的鍵並傳回成功訊息 `Setting 'theme' deleted successfully!`。 ```js ({ diff --git a/curriculum/challenges/chinese-traditional/blocks/learn-about-speculation-and-requests/67eea33bbc314f248d210c93.md b/curriculum/challenges/chinese-traditional/blocks/learn-about-speculation-and-requests/67eea33bbc314f248d210c93.md index 2ee199c1fce..688b965406e 100644 --- a/curriculum/challenges/chinese-traditional/blocks/learn-about-speculation-and-requests/67eea33bbc314f248d210c93.md +++ b/curriculum/challenges/chinese-traditional/blocks/learn-about-speculation-and-requests/67eea33bbc314f248d210c93.md @@ -54,7 +54,7 @@ Sophie 沒有提到任何註解說明該迴圈是否有效。 要找到正確答案,請專注於 Sophie 如何給予回授。 -她說 `explaining why you chose a particular loop structure`。這表示她並不是說這個迴圈是錯的——只是應該解釋背後的決定原因。 +她說了 `explaining why you chose a particular loop structure`。這表示她並不是說這個迴圈有錯,而是應該解釋背後的決定原因。 這有助於其他人理解程式碼背後的思考,這就是為什麼註解很有用。 diff --git a/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/658147bb3dbda824437fd6f9.md b/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/658147bb3dbda824437fd6f9.md index d4449604c54..d6d92190b2f 100644 --- a/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/658147bb3dbda824437fd6f9.md +++ b/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/658147bb3dbda824437fd6f9.md @@ -10,11 +10,11 @@ lang: en-US # --description-- -`To grow` 意思是以某種方式增加或發展。 +`To grow` 意思是以某種方式增加或發展。 -例如,`Plants grow quickly in the summer.` +例如,`Plants grow quickly in the summer.` -當你 `grow professionally`,你會提升你的技能或職涯。 +當你 `grow professionally`,你會提升你的技能或職涯。 字 `professionally` 與你的工作或職業有關。例如,`He behaves very professionally at work` 意思是他在工作中表現得很專業。 @@ -30,7 +30,7 @@ lang: en-US ### --feedback-- -這個字是關於獲得新知識或技能。想想你在學校或學習新事物時所做的事情。這個字是大寫的。 +這個字是關於獲得新知識或技能。想想你在學校或學習新事物時所做的事情。這個字是大寫的。 --- @@ -46,7 +46,7 @@ lang: en-US ### --feedback-- -這個字與工作或職業有關。它描述以展現良好技能和行為的方式完成某事。它以 `-ly` 結尾。 +這個字與工作或職業有關。它描述以展現良好技能和職場行為的方式做事。它以 `-ly` 結尾。 # --scene-- diff --git a/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35429c637c13540c9be80.md b/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35429c637c13540c9be80.md index 48b2b8eefaa..cb84787a1db 100644 --- a/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35429c637c13540c9be80.md +++ b/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35429c637c13540c9be80.md @@ -26,7 +26,7 @@ lang: en-US ### --feedback-- -這個動詞表示授權或使某事成為可能。這個動詞以第三人稱單數變化,所以記得加上 `-s`。 +這個動詞表示允許或使某事成為可能。它是第三人稱單數形式,所以記得加上 `-s`。 --- diff --git a/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35c7b9d642f478d6cabba.md b/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35c7b9d642f478d6cabba.md index 00dc8bd1e04..452006d3b78 100644 --- a/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35c7b9d642f478d6cabba.md +++ b/curriculum/challenges/chinese-traditional/blocks/learn-how-to-have-a-conversation-about-preferences-and-motivations/65a35c7b9d642f478d6cabba.md @@ -24,7 +24,7 @@ lang: en-US ### --feedback-- -這個副詞用來強調述語的真實性或重要性,表示強烈的同意或信念。它以 `ly` 結尾。 +這個副詞用來強調陳述的真實性或重要性,表達強烈的同意或信念。它以 `ly` 結尾。 # --scene-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-browsing-the-web-effectively/672ac9705b07a64439b73b59.md b/curriculum/challenges/chinese-traditional/blocks/lecture-browsing-the-web-effectively/672ac9705b07a64439b73b59.md index 3654424a5c8..2289e578e2f 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-browsing-the-web-effectively/672ac9705b07a64439b73b59.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-browsing-the-web-effectively/672ac9705b07a64439b73b59.md @@ -15,26 +15,38 @@ dashedName: how-to-use-a-search-engine-effectively-to-achieve-optimal-results 這是一個針對 `freecodecamp curriculum` 的基本搜尋查詢範例。 +A search engine search box containing the query freecodecamp curriculum. + 當你搜尋 `freecodecamp curriculum` 時,搜尋引擎會傳回符合 *任一* 這些關鍵字的結果-通常依相關性排序(它們與你的查詢相符或相關的可能性有多高)。 但是如果你只想要同時符合兩個關鍵字的結果呢?你可能聽說過可以用引號將查詢包起來,例如 `"freecodecamp curriculum"`。 +A search engine search box containing the query freecodecamp curriculum wrapped in quotation marks. + 然而,這個查詢特別匹配 *phrase* `freecodecamp curriculum`。這表示你看到的結果將限於同時包含 `freecodecamp curriculum` 的網站,而非同時包含 `freecodecamp` 和 `curriculum` 的網站。 如果你想要符合同時包含這兩個詞彙的網站,但不一定要作為一個片語相鄰,你可以為每個詞彙加上加號符號前置式,如此:`+freecodecamp +curriculum` +A search engine search box containing the query +freecodecamp +curriculum, with a plus symbol before each term. + 或者,你可能對 freeCodeCamp 課程外的計畫感興趣。在這種情況下,你可以在詞彙 `curriculum` 前面加上減號符號,如此:`+freecodecamp -curriculum`。 +A search engine search box containing the query +freecodecamp -curriculum, with a plus symbol before freecodecamp and a minus symbol before curriculum. + 這將傳回提及 `freecodecamp`,但排除同時提及 `curriculum` 的結果。 或者你可能有特定的網站想要搜尋,例如我們的新聞平台?你可以使用 `site:` 後接你想搜尋的網站 URL :`site:freecodecamp.org/news curriculum`。 +A search engine search box containing the query site:freecodecamp.org/news curriculum. + 此查詢會傳回所有來自 `freecodecamp.org/news` 且包含字 `curriculum` 的結果。 透過結合這些工具,你可以提出非常具體的查詢,以取得你所需的精確資訊。 例如,查詢 `site:freecodecamp.org/news +python -curriculum` 將會在我們的新聞網站上搜尋 Python 文章,但排除可能談論我們課程的文章。 +A search engine search box containing the query site:freecodecamp.org/news +python -curriculum. + 搜尋運算子可能會有所不同,因此務必檢查你偏好的搜尋引擎的文件。 但你現在應該能夠從你的網路搜尋中獲得你想要的精確結果。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/68420bd261d0d35f61922d4b.md b/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/68420bd261d0d35f61922d4b.md index 4f757045235..3f3a5929454 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/68420bd261d0d35f61922d4b.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/68420bd261d0d35f61922d4b.md @@ -13,6 +13,8 @@ dashedName: how-do-classes-work-and-how-do-they-differ-from-objects 讓我們來看看什麼是類別,以及如何使用它們來創建物件。 +## 建立類別 + 要創建一個類別,你使用 `class` 關鍵字,後面接類別名稱和冒號。然後在類別內,你可以添加初始化函式,以及任何屬性和方法。 屬性就像類別中的變數,用來儲存資料。方法是在類別中定義的函式(程式),是使用類別創建的物件可以執行的行為。 @@ -32,7 +34,7 @@ class ClassName: * `class ClassName` 是由 `class` 關鍵字用來創建類別,接著是類別的名稱,這裡稱為 `ClassName`。在 Python 中,命名類別時通常使用 **PascalCase** 慣例。 * `def __init__(self, name, age)` 是在創建新物件時自動呼叫的特殊方法。它初始化將由類別創建的物件的屬性。 - + 除此之外,`__init__` 的第一個參數總是對正在創建或使用的特定物件的引用。依慣例,這個參數命名為 `self`,但技術上你可以使用任何名稱。`self` 讓你存取物件自身的屬性和方法。 * `self.name = name` 和 `self.age = age` 是物件將擁有的屬性。 @@ -42,6 +44,8 @@ class ClassName: * `print(self.name.upper())` 是 `sample_method` 方法會執行的動作,在此情況下,它會列印大寫的名稱。 +## 一個 `Dog` 類別範例 + 如果這聽起來很多,不用擔心。讓我們來看看一個類似的 `Dog` 類別範例,以及你如何從中創建物件: ```python @@ -54,6 +58,8 @@ class Dog: print(f"{self.name.upper()} says woof woof!") ``` +## 從類別建立物件 + 使用這個 `Dog` 類別,你可以創建一個物件。以下是從類別創建物件的基本語法: ```python @@ -91,6 +97,8 @@ dog_2.bark() # THATCHER says woof woof! I'm 5 years old! 然後當你對 `dog_1` 和 `dog_2` 呼叫 `.bark()` 方法時,你可以看到兩者的輸出如何不同,並使用你在建立每個物件時傳入的獨特 `name` 和 `age` 屬性。 +## 類別與物件的差異 + 總結來說,類別和物件的差異在於類別是模板或藍圖,而物件是使用該模板所創建的。 此外,類別定義物件應該擁有的資料和行為,而物件則持有實際的資料並使用該行為。你撰寫類別一次,就可以從中建立許多物件,每個物件擁有不同的資料。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/6874b7d3b286c538b39d0c25.md b/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/6874b7d3b286c538b39d0c25.md index 8c027f84871..038aacef6a9 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/6874b7d3b286c538b39d0c25.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/6874b7d3b286c538b39d0c25.md @@ -7,6 +7,8 @@ dashedName: what-are-special-methods-and-what-are-they-used-for # --description-- +## 什麼是特殊方法? + Python 中的特殊方法,也稱為「魔術方法」或「dunder 方法」,是以雙底線(`__`)開頭和結尾的特殊 Python 方法。字「dunder」本身來自於雙底線(**d** 代表 double,**under** 代表 underscores)。 你可能已經在不知不覺中使用過特殊方法。每當你寫下像 `3 + 4` 這樣的東西時,Python 會在背後靜靜地執行 `3.__add__(4)`。這就是特殊方法的運作方式。所以雖然你*可以*直接呼叫特殊方法,但你很少這麼做。像 `3 + 4` 這樣的寫法比你自己呼叫 `3.__add__(4)` 更清楚且更容易閱讀。 @@ -15,6 +17,8 @@ Python 中的特殊方法,也稱為「魔術方法」或「dunder 方法」, 將特殊方法視為程式設計者與 Python 直譯器本身之間活動的導演。 +## 何時 Python 會呼叫特殊方法 + 請記住,你不需要直接呼叫特殊方法。相反地,當發生某些操作行為時,Python 會自動呼叫它們。這些操作行為包括: - **像加法、減法、乘法、除法等算術操作**。對於加法,會呼叫 `__add__()`,`__sub__()` 用於減法,`__mul__()` 用於乘法,以及 `__truediv__()` 用於除法。 @@ -26,6 +30,8 @@ Python 中的特殊方法,也稱為「魔術方法」或「dunder 方法」, - **像是讓物件可迭代以及在項目中前進的迭代操作行為**。會呼叫 `__iter__()` 來傳回迭代器,並呼叫 `__next__()` 來取得下一個項目。 +## 為什麼訂製類別需要特殊方法 + 通常,Python 資料型別像是字串和數字已經知道如何進行加法、串接、比較相等性、用於迴圈等操作。 但是當你創建你自己的類別時,Python 不會自動知道如何控制代碼。 @@ -57,6 +63,8 @@ print(book1 == book2) # False even though they have the same number of pages - `book1 == book2` 結果為 `False`,因為 Python 只是檢查兩個物件是否在記憶體中相同,而不是依內容比較。 +## 定義你自己的特殊方法 + 以下是你如何定義自己的 `__len__()`、`__str__()` 和 `__eq__()` 特殊方法,以便更輕鬆地操作從 `Book` 類別產生的物件: ```python @@ -84,6 +92,8 @@ print(str(book2)) # 'Be Your Own Start' has 420 pages print(book1 == book2) # True ``` +## 購物車範例 + 另一個範例是一個購物車,在那裡你執行以下操作: - 將項目添加到購物車 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/6908d38f7cccc31602743340.md b/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/6908d38f7cccc31602743340.md index 141de526b6b..92f97067682 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/6908d38f7cccc31602743340.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-classes-and-objects/6908d38f7cccc31602743340.md @@ -30,6 +30,8 @@ Python 提供你四個方便的內建函式(程式)來動態操作物件屬 它們讓你使用變數名稱來存取、創建、檢查和移除屬性。讓我們來看看每一個的實際操作。 +## `getattr()` + `getattr()` 讓你能在執行期才知道名稱時,從物件讀取屬性。如果該屬性不存在,會引發 `AttributeError`,除非你提供預設值。 要使用它,你需要傳入物件、屬性名稱,以及選用的預設值: @@ -75,6 +77,8 @@ print(getattr(person, attr_name, 'Attribute not found')) 這正是動態屬性處理發揮作用的地方。它讓你的程式碼能夠回應之前未曾見過的輸入和資料。 +## 使用 `dir()` 列出屬性 + 此外,你可能想查看物件擁有的所有屬性,而不只是你已經知道的那些。內建的 `dir()` 函式讓你可以做到這一點。它會傳回物件上所有屬性名稱的列表。以下是使用方法: ```python @@ -99,6 +103,8 @@ for attr in dir(person): 在上面的迴圈中,`callable()` 是一個內建函式,當傳入的物件可以像函式或方法一樣被呼叫時,會回傳 `True`,否則回傳 `False`。透過檢查 `not callable(getattr(person, attr))`,迴圈會跳過方法,只列印像 `name` 和 `age` 這樣的資料屬性。 +## `setattr()` + `setattr()` 函式(程式)讓你動態地創建新的屬性或更新現有的屬性。語法如下: ```python @@ -128,6 +134,8 @@ print(config_obj.server_url) # https://api.example.com print(config_obj.timeout_sec) # 30 ``` +## `hasattr()` + 還有 `hasattr()`。在你對屬性做某些操作或刪除它之前,檢查它是否存在是一個良好的習慣。這就是 `hasattr()` 所能做到的。它會檢查屬性是否存在,並根據結果傳回 `True` 或 `False`。 以下是基本語法: @@ -163,6 +171,8 @@ for attr in required_attributes: 錯誤輸出發生是因為 `inventory_id` 類別及其實體中缺少 `Product`。 +## `delattr()` + 最後,`delattr()` 讓你動態移除屬性: ```python diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-git-and-github/6882904fd7063f7258c0aef3.md b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-git-and-github/6882904fd7063f7258c0aef3.md index 60888da7791..6b3b521d5ad 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-git-and-github/6882904fd7063f7258c0aef3.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-git-and-github/6882904fd7063f7258c0aef3.md @@ -7,10 +7,14 @@ dashedName: how-do-you-handle-security-requirements-like-ssh-and-gpg-keys # --description-- +## 什麼是 SSH 和 GPG 金鑰? + 在你可以將你的儲存庫推送到 GitHub 之前,你需要先通過驗證。SSH 和 GPG 金鑰都使用公私配對。這表示你會將私鑰保存在你的區域的機器上,用來驗證你自己。你會將公鑰分享給需要驗證你身份的人或服務。換句話說,執行動作需要私鑰,而驗證動作則使用公鑰。 GPG,或稱 GNU Privacy Guard,金鑰通常用來簽署檔案或提交。其他人可以使用你的公開 GPG 金鑰來驗證該檔案的簽名是否來自你的金鑰,並確認檔案內容未被修改或竄改。SSH,或稱 Secure SHell,金鑰通常用來透過 `ssh` 工具驗證遠端連線到伺服器。不過,正如你在本課程中會學到的,你也可以使用 SSH 金鑰來簽署提交。 +## 產生 SSH 和 GPG 金鑰 + 要產生 GPG 金鑰,你需要執行: ```sh @@ -27,6 +31,8 @@ ssh-keygen -t ed25519 -C "your_email@example.com" 這兩個指令都應該要求輸入密碼短語以保護金鑰。這些是選用的,但強烈建議使用。 +## 尋找你的公鑰 + 對於 SSH 金鑰,你會得到兩個檔案-一個是你的私鑰,另一個是你的公鑰。公鑰檔案名稱會以 `.pub` 結尾,因此你不會意外分享你的私鑰。這些檔案會位於 `~/.ssh`。 GPG 金鑰將會位於隱藏且加密的目錄中。相反地,要列出你的公開金鑰,你需要執行: @@ -41,6 +47,8 @@ gpg --list-secret-keys --keyid-format=long gpg --armor --export "" ``` +## 使用 GPG 金鑰簽署提交 + 但是你可以用這些新金鑰做什麼呢?我們已經談過簽署你的提交,而你可以使用這些金鑰中的任何一個來做這件事。 為了使用你的 GPG 金鑰簽署你的提交,你需要將你的公鑰(而非私鑰)上傳到你的 GitHub 帳戶。然後,使用先前列出金鑰時取得的短 ID,並執行此命令將其設為你的 git 簽署金鑰: @@ -55,6 +63,8 @@ git config --global user.signingkey git config --global commit.gpgsign true ``` +## 使用 SSH 金鑰簽署提交 + 要使用 SSH 金鑰簽署,這是 GitHub 上相對較新的特性,你需要先將金鑰上傳到你的 GitHub 帳戶。然後你需要設定 git 的簽署模式以使用 SSH: ```sh diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e3a9cc78faaf4248d335.md b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e3a9cc78faaf4248d335.md index 24b36859b5c..eeb64c4eeb2 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e3a9cc78faaf4248d335.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e3a9cc78faaf4248d335.md @@ -9,6 +9,8 @@ dashedName: what-is-the-role-of-js-libraries-and-frameworks-and-why-are-they-use JavaScript 函式庫和框架提供預先建置的程式碼,簡化開發流程。雖然函式庫和框架都能提升生產力並標準化程式撰寫方式,但它們在方法和給予開發者的控制元件層次上有所不同。 +## 什麼是函式庫? + 函式庫通常更專注於為特定任務提供解決方案,例如操作 DOM、處理事件或管理 AJAX 請求。 JavaScript 函式庫的範例是 jQuery。 @@ -17,16 +19,22 @@ jQuery 在 2010 年代初期變得非常流行,並被廣泛用於簡化 DOM 雖然 jQuery 不再像以前那樣廣泛使用,但它大大幫助了開發者,使在純 JavaScript 中複雜的任務變得更容易實作。 +## 什麼是框架? + 另一方面,框架提供了更明確的結構來建置應用程式。它們通常附帶一套開發者需要遵循的規則和慣例。 例如,Angular 鼓勵以組件為基礎的架構,並提供一套慣例和工具,為組織和建置應用程式提供有結構的方法。Angular 為開發者提供明確的指引,說明如何結構組件、管理狀態、控制路由以及與服務互動,使其成為一個更具意見性的框架。 其他框架的範例包括 Remix 和 Next.js。 +## 函式庫與框架的比較 + 相較之下,React 是一個 UI 函式庫,較為彈性且不強制任何特定的架構樣式。React 主要專注於視圖層,並將許多應用程式設計的選擇留給開發者。 雖然函式庫和框架會用於各種規模的專案,但選擇使用哪一種通常取決於專案的需求。函式庫為特定功能提供彈性,而框架則為複雜應用程式提供結構化的方法。 +## 為什麼業界會使用函式庫和框架 + 在業界中,函式庫和框架因多種原因被廣泛使用。它們透過為常見問題提供快速解決方案,大幅加快開發速度。 JavaScript 中一個常見的問題是處理日期和時區。但市面上有些函式庫內建了解決方案,能協助你操作日期、時區,以及解析和格式化日期。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e879c78ee6c61db25b90.md b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e879c78ee6c61db25b90.md index de5b2c0fd4f..dae474cf0e2 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e879c78ee6c61db25b90.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/6734e879c78ee6c61db25b90.md @@ -15,6 +15,8 @@ React 中的組件有兩種類型:函式組件和類別組件。在現代 Reac 此使用者介面是使用 JSX 描述的,JSX 是 JavaScript 的一種語法擴充套件,看起來類似 HTML,但允許你以更宣告式的方式撰寫使用者介面元素。 +## 基本組件 + 讓我們來看一個 React 組件的範例: ```jsx @@ -43,12 +45,16 @@ function Greeting() { {/* Block Comments */} ``` +## 組件命名 + 你可能還注意到,我們在組件名稱的開頭使用了大寫字母。但為什麼不能全部使用小寫字母呢? 這是因為 React 將大寫字母開頭的組件視為訂製組件,而小寫字母開頭的元素則被視為內建的 HTML 元素。 當 React 遇到小寫的頁籤,例如 `
` 或 ``,它會假設這是標準的 HTML 元素。然而,如果組件名稱以大寫字母開頭,React 會將其視為使用者定義的組件並相應地呈現。這種區分有助於 React 區分原生的 HTML 頁籤和你創建的組件。 +## 使用組件 + 要在我們的應用程式中使用這個 `Greeting` 組件,我們會這樣寫: ```jsx @@ -63,6 +69,8 @@ function Greeting() { {/* /> is required */} ``` +## 呈現多個元素 + 到目前為止,我們只看過如何呈現單一的 `h1` 元素。但你實際上可以呈現多個元素。 讓我們來看看以下的範例程式碼: @@ -84,6 +92,8 @@ function Greeting() { 你會看到錯誤訊息的原因是因為多個同層元素必須包在一個父元素裡。雖然你可以用簡單的 `div` 包住 `h1` 和 `p` 元素,但還有另一種方法可以滿足這個需求。 +## React 片段 + React 片段用於將元素群組在一起。以下是修訂後的範例外觀: ```jsx diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/674ba6876f7ada867135bb95.md b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/674ba6876f7ada867135bb95.md index 5d9bbb9072e..4a1728de2ca 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/674ba6876f7ada867135bb95.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-javascript-libraries-and-frameworks/674ba6876f7ada867135bb95.md @@ -13,6 +13,8 @@ dashedName: how-can-you-import-and-export-components-in-react 在本課程中,你將學習如何使用預設匯出和具名匯出來匯出 React 組件,以及如何在需要的地方匯入它們。 +## 使用預設匯出 + 在這個範例中,我們有一個 `Cat` 組件,它屬於一個名為 `Cat.jsx` 的檔案。我們使用 `.jsx` 副檔名是因為這個檔案主要處理 JSX。 這個 `Cat` 組件傳回包含標題和一隻名叫 Mr. Whiskers 的貓的影像的 JSX 標記: @@ -65,6 +67,8 @@ export default function Cat() { } ``` +## 匯入預設匯出 + 你可以選擇在其他父組件檔案中匯入子組件,或是在根組件檔案中匯入它們。以此範例,我們將在根組件檔案中匯入 `Cat` 組件。 每個 React 專案都有一個頂層組件,通常稱為 `App`,定義在名為 `App.jsx` 的檔案中。 @@ -101,6 +105,8 @@ export default function App() { 當一個檔案負責匯出單一主要組件時,這種方法運作良好,能保持匯入語法簡單且易於閱讀。請記住,一個檔案只能有一個預設匯出,這使得它非常適合主要包含單一組件的檔案。 +## 使用命名匯出 + 現在你已經知道如何使用預設匯出,讓我們來看看命名匯出。命名匯出允許一個檔案分享多個組件或函式。與預設匯出不同,這些必須使用它們被匯出時的精確名稱來匯入(除非你使用 `as` 關鍵字重新命名)。 當一個檔案作為組件函式庫時,這非常有用。舉例來說,這裡有一個包含兩個組件 `Cat` 和 `Dog` 的檔案: @@ -141,6 +147,8 @@ export default function App() { } ``` +## 結合預設匯出與命名匯出 + 最後,一個檔案可以有一個預設匯出和多個具名匯出。 ```jsx diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-python/67fe81c9c6fd3714343a45ad.md b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-python/67fe81c9c6fd3714343a45ad.md index 56f6dbf0a2e..cada9eba43a 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-python/67fe81c9c6fd3714343a45ad.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-introduction-to-python/67fe81c9c6fd3714343a45ad.md @@ -7,27 +7,25 @@ dashedName: what-is-python-and-what-are-some-common-uses-in-the-industry # --description-- -Python 是一種通用的程式設計語言,以其簡單和易用性著稱。這種易用性使 Python 成為現代最受歡迎的程式設計語言。 +Python 是一種通用程式設計語言,以其簡單易用著稱。它簡短且易讀的語法,以及解決各種不同問題的彈性,使它成為世界上最受歡迎的程式語言之一。這也是為什麼它常被推薦作為第一門語言。 -Python 用於許多領域,如資料科學和機器學習、網頁開發、腳本和自動化、嵌入式系統、物聯網等。 +Python 廣泛用於處理資料。資料科學家使用它來清理混亂的資訊、計算統計數據、尋找樣式、製作圖表,以及更多其他用途。 -Python 是大多數資料科學家和機器學習工程師目前使用的主要語言。像 Pandas 和 NumPy 這類函式庫讓資料分析不再那麼繁瑣,而 TensorFlow 和 Scikit-learn 則讓機器學習和操作 AI 模型變得更加容易。 +Python 也是建置和訓練機器學習模型最常用的語言。這些系統是影像辨識、產品推薦和聊天機器人的背後技術。 -在網頁開發中,像 Django、FastAPI 和 Flask 這類 Python 框架讓開發者能以最小的努力建置可擴充且安全的後端系統。許多社群媒體平台像 Instagram 和 Pinterest 都在後端使用 Python。 +在網頁開發中,Python 常用於網站的伺服端。這是幕後運作的部分,負責處理使用者帳號、表單提交和儲存資訊等任務。許多社群媒體平台,如 Instagram 和 Pinterest,都在後端使用 Python。 -資安專業人員和道德駭客使用 Python 來偵測惡意軟體和其他病毒等漏洞、建置自動化安全掃描,並分析威脅。 +資安專業人員和道德駭客使用 Python 來偵測漏洞和惡意軟體,建置自動化安全掃描,並分析威脅。 -Python 在像 Raspberry Pi 和相容 MicroPython 的開發板等微型電腦上執行良好,因此你可以建置各種物聯網專案,例如智慧家庭裝置、氣象監測站等等。 +Python 在像 Raspberry Pi 這類微型電腦和其他相容 MicroPython 的開發板上運行良好,因此你可以建置各種物聯網專案,例如智慧家庭裝置和氣象監測站。 -Python 廣泛用於 DevOps 中撰寫 CI/CD 腳本及管理開發流程中的基礎建設。它也常用於建造後端服務和內部 API。 +在 DevOps 領域,Python 廣泛用於撰寫 CI/CD 腳本和管理開發流程中的基礎建設。它也常用於建置後端服務和內部 API。 -在軟體測試中,Python 工具如 pytest 用於創建可靠的測試套件,而系統管理員則依賴 Python 進行伺服器監控、日誌管理和系統層級任務。 +在軟體測試中,Python 用來創建可靠的測試套件,而系統管理員則依賴 Python 進行伺服器監控、日誌管理和系統層級任務。 -最後,Python 最大的優勢之一是自動化。你可以撰寫簡單的腳本來幫助你處理重複性的工作,例如從試算表中擷取資料、發送電子郵件,以及操作你區域的機器上的檔案。 +最後,Python 最大的優勢之一是自動化。你可以撰寫簡單的腳本來處理重複性工作,例如從試算表擷取資料、發送電子郵件,以及操作本地機器上的檔案。 -像 Selenium 和 BeautifulSoup 這樣的函式庫也讓與網站互動變得簡單,因此你可以擷取公開資料、透過網頁使用者介面自動化任務,甚至管理你的專案的雲端部署。 - -如你所見,Python 是一種非常強大的語言,且容易學習。從簡單的自動化腳本到大型工業層級的應用程式,你幾乎可以用 Python 做任何事情。 +如你所見,Python 是一種非常強大的語言,卻又容易學習。從簡單的自動化腳本到大型工業級應用,你幾乎可以用 Python 做任何事。 Python 是任何想學習程式設計的人都很好的選擇,無論他們之後選擇專攻什麼領域。 @@ -35,35 +33,35 @@ Python 是任何想學習程式設計的人都很好的選擇,無論他們之 ## --text-- -在 Python 中,哪些函式庫常用於資料分析? +資料科學家如何使用 Python? ## --answers-- -Pandas 和 NumPy +用來清理混亂的資訊、計算統計數據、尋找樣式和製作圖表。 --- -TensorFlow 和 Scikit-learn +用來設計網頁的視覺版面。 ### --feedback-- -思考那些有助於高效處理大量資料的函式庫。 +想想處理資料涉及什麼。 --- -React 和 Vue +用來建造智慧家庭裝置的硬體。 ### --feedback-- -思考那些有助於高效處理大量資料的函式庫。 +想想處理資料涉及什麼。 --- -Django 和 Flask +用來完全取代試算表和資料庫。 ### --feedback-- -思考那些有助於高效處理大量資料的函式庫。 +想想處理資料涉及什麼。 ## --video-solution-- @@ -107,35 +105,35 @@ Python 如何用於嵌入式系統和物聯網? ## --text-- -哪些 Python 框架用於網頁開發? +在網頁開發中,Python 常用於網站的哪一部分? ## --answers-- -React、Vue、Angular +頁面的顏色和字型。 ### --feedback-- -思考那些幫助網頁開發者建置可擴充後端系統的框架。 +想想網站幕後運作的部分。 --- -TensorFlow、PyTorch、Scikit-learn +使用者捲動時看到的動畫。 ### --feedback-- -思考那些幫助網頁開發者建置可擴充後端系統的框架。 +想想網站幕後運作的部分。 --- -NumPy、Pandas、Matplotlib +按鈕和圖片的版面配置。 ### --feedback-- -思考那些幫助網頁開發者建置可擴充後端系統的框架。 +想想網站幕後運作的部分。 --- -Django、FastAPI、Flask +伺服端,負責處理使用者帳號、表單提交和儲存資訊等任務。 ## --video-solution-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-python-installation/67fe8567f141d632afaeb71b.md b/curriculum/challenges/chinese-traditional/blocks/lecture-python-installation/67fe8567f141d632afaeb71b.md index b801757cfe9..2257c142fc4 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-python-installation/67fe8567f141d632afaeb71b.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-python-installation/67fe8567f141d632afaeb71b.md @@ -7,12 +7,18 @@ dashedName: how-do-you-install-configure-and-use-python-in-your-local-environmen # --description-- +## 為什麼要在本機安裝 Python? + 在所有的工作坊和實驗中,你都會使用 freeCodeCamp 的 Python 編輯器。但學會如何在你的區域電腦上設定 Python 也很重要。 +## 下載 Python + 在 Windows 和 Mac 上安裝 Python 最簡單的方法是從官方 Python 網站下載安裝程式。我們稍後也會介紹如何在 Linux 上執行 Python。 前往 `https://www.python.org/` 並將滑鼠暫留在「Downloads」上。會跳出一個視窗,顯示你作業系統(OS)目前的 Python 版本。 +## 在 macOS 上安裝 Python + 我們先介紹如何在 macOS 電腦上安裝 Python: - 點擊剛剛視窗中顯示的 Python 版本按鈕,會自動開始下載 `.pkg` 安裝檔。 @@ -22,14 +28,22 @@ dashedName: how-do-you-install-configure-and-use-python-in-your-local-environmen - 安裝完成後,會看到一則恭喜訊息,表示 Python 已成功安裝。 - 點擊「Close」按鈕,完成安裝! +## 驗證安裝 + 你可以打開終端機,執行 `python --version` 或 `python3 --version` 來驗證安裝。 你也可以在終端機執行 `python` 或 `python3` 來開啟 Python 直譯器。Python 直譯器是讀取 Python 程式碼、將其轉換成電腦能理解的指令並執行的程式。 +## 什麼是終端機? + 終端機是一種以文字為基礎的介面,讓你透過輸入指令與電腦互動。每個作業系統都會附帶預設的終端機應用程式。macOS 可以使用 Terminal 應用程式,Windows 可以使用命令提示字元或 PowerShell,Linux 則依桌面環境不同,有 GNOME Terminal 或 Konsole 等預設終端機。 +## 使用 `python` 與 `python3` 的差異 + 請注意,在某些較舊的 macOS 和 Linux 系統中,`python` 可能是保留給 Python 2 使用,而 `python3` 則是專門給 Python 3。如果你執行 `python --version`,看到像 `Python 2.7.18` 這樣的 Python 2 版本,那可能是你的作業系統依賴某些用舊版 Python 撰寫的軟體。如果是這樣,你應該改用 `python3` 來執行 Python 程式。Python 2 已經終止支援,不應用於任何新開發。 +## 在 Windows 上安裝 Python + 在 Windows 上安裝 Python,請依照以下步驟: - 前往 `https://www.python.org/`,將滑鼠暫留在「Downloads」上。會看到一個視窗寫著「Download for Windows」和一個帶有目前 Python 版本的下載按鈕。 @@ -37,8 +51,11 @@ dashedName: how-do-you-install-configure-and-use-python-in-your-local-environmen - 下載完成後,雙擊 Python 安裝程式,並依照指示操作。 - 當看到 `Add python.exe to Path` 選項時,勾選該選項,然後點擊 `Install Now`。這樣以後會更方便。 + 你可以打開命令列殼層(例如 PowerShell),執行 `python --version` 來驗證安裝。你也可以執行 `python` 來開啟 Python 直譯器。 +## 在 Linux 上安裝 Python + 在 Linux 上,大多數主要發行版如 Ubuntu、Debian 和 Fedora 都預載 Python。 只要打開終端機,執行 `python --version` 或 `python3 --version`: diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-python-installation/69fd6b21fcaa14b089c27182.md b/curriculum/challenges/chinese-traditional/blocks/lecture-python-installation/69fd6b21fcaa14b089c27182.md index 233c30e3c3f..fda7793350f 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-python-installation/69fd6b21fcaa14b089c27182.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-python-installation/69fd6b21fcaa14b089c27182.md @@ -7,6 +7,8 @@ dashedName: how-to-run-python-scripts # --description-- +## 安裝程式碼編輯器或整合開發環境 + 在上一課中,你學會了如何在你的區域裝置上安裝 Python。在本課中,你將學習如何在本地執行 Python 程式碼。 在你開始在本地建置 Python 腳本之前,你需要先安裝一個程式碼編輯器或整合開發環境(IDE)。IDE 是整合開發環境的縮寫,它包含了程式碼編輯器、測試工具、終端機等多種功能。 @@ -18,6 +20,8 @@ dashedName: how-to-run-python-scripts - PyCharm - Spyder +## 建立 Python 檔案 + 下載好你的編輯器後,打開它。打開後,你需要開啟一個資料夾。你可以點擊左上角的 `File` 選單選項,然後點擊 `Open Folder`。接著,你可以選擇或建立一個專案資料夾。為了課外練習,你可能想要一個名為 `python-projects` 的資料夾。 當你設定好資料夾後,可以打開 VS Code 左側邊欄的檔案總管。點擊看起來像一張紙上有加號的 `New File` 圖示。接著創建一個名為 `main.py` 的檔案,然後按下 Enter。`.py` 是一個副檔名,表示這是一個 Python 檔案。 @@ -28,6 +32,8 @@ dashedName: how-to-run-python-scripts print("Hello, world!") ``` +## 執行你的 Python 腳本 + 要執行這段程式碼,你有幾種選擇。第一種是點擊位於右上角看起來像播放按鈕的執行按鈕。這會開啟終端機並執行你的 Python 腳本。你應該會看到文字 `"Hello, world!"`。 另一種選擇是打開終端機,手動使用以下指令執行程式: @@ -48,6 +54,8 @@ cd python-projects python main.py ``` +## 使用 `python3` 取代 `python` + 在某些環境中,特別是在 macOS 和 Linux 系統上同時安裝了 Python 2 和 Python 3 時,你可能需要使用 `python3` 來取代 `python`。這種情況常見於 `python` 指令不存在或指向較舊版本的 Python。 ```bash diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5b78609f97400923f7f.md b/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5b78609f97400923f7f.md index 9719e5b9351..b7bfe45e7dc 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5b78609f97400923f7f.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5b78609f97400923f7f.md @@ -19,9 +19,13 @@ dashedName: what-are-state-management-libraries-and-when-should-you-use-them 讓我們來看看你擁有的幾種不同狀態管理選項,可選方案以及何時使用它們。 +## Context API + Context API 是內建於 React 的狀態管理器,讓你能在組件之間共享狀態,而無需使用第三方函式庫。它是 `useState` 掛鉤的成熟升級版,因此非常適合用於主題切換或使用者身份驗證狀態等情況。 -然而,Context API 無法良好控制頻繁的更新,且可能導致不必要的重新呈現,使其不太適合像電子商務和社交媒體平台這類具有複雜狀態需求的應用程式。  +然而,Context API 無法良好控制頻繁的更新,且可能導致不必要的重新呈現,使其不太適合像電子商務和社交媒體平台這類具有複雜狀態需求的應用程式。 + +### 建立 Context 這是一個計數器組件,示範了 Context API 的基本用法: @@ -49,6 +53,8 @@ export { CounterContext, CounterProvider }; 因此,當你用 `CounterProvider` 包裹整個應用程式時,`count` 狀態在你的應用程式中隨處可用。 +### 包裹應用程式 + 以下是你如何將 `CounterProvider` 包裹在你的應用程式周圍的方法: ```jsx @@ -65,6 +71,8 @@ function App() { export default App; ``` +### 使用 Context + 以下是你如何使用 `count` 狀態的方法: ```jsx @@ -93,10 +101,12 @@ const Counter = () => { export default Counter; ``` -如你所見,`count` 及其設值函式 `setCount` 是透過 `useContext` 函式初始化的。 +如你所見,`count` 及其設值函式 `setCount` 是透過 `useContext` 函式初始化的。 接著會顯示目前的 `count` 狀態,並且當使用者分別點擊遞減和遞增按鈕時,會使用 `setCount` 來增加和減少 `count` 狀態。 +## Redux + 另一個受歡迎的狀態管理程式庫是 Redux,它是與 React 一起使用的最受歡迎的狀態管理程式庫之一。它已經存在很長時間,非常適合較大型的應用程式,例如電子商務和社交媒體平台、論壇等等。 Redux 透過提供一個中央儲存庫和對狀態更新的嚴格控制元件來處理狀態管理。它使用包含 actions、reducers 和 middleware 的可預測樣式。 @@ -111,6 +121,8 @@ Reducers 是指定狀態應如何回應那些動作而改變的函式,確保 你通常會在單一檔案中使用 `createSlice()` 函式(程式)定義動作和 reducers。檔案名稱通常會以字 `Slice` 結尾,例如 `productSlice`、`userSlice`、`counterSlice` 等等。 +### `counterSlice` 檔案 + 這裡有一個 `counterSlice` 檔案,向你展示基礎知識: ```jsx @@ -138,12 +150,16 @@ export default counterSlice.reducer; 從這裡開始,你需要用 `Provider` 包裹整個應用程式,使用 `useSelector()` 從 slice 中選取一部分狀態,然後使用 `useDispatch()` 來使狀態處於作用中。 +## Zustand + 另一個可考慮的選項是 Zustand。 Zustand 是一個輕量級的狀態管理程式庫,具有簡單的 API。它是基於掛鉤,因此與 Redux 相比,樣板程式碼較少,使設定更簡單且更快速。 Zustand 非常適合小型到中型應用程式。它透過使用 `useStore` 掛鉤直接在組件和頁面中存取狀態來運作。這讓你可以在不需要 actions、reducers 或 provider 的情況下修改和存取資料。 +### Zustand 計數器範例 + 這裡有一個實作另一個計數器功能的 `useCounterStore`: ```jsx diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5dacd5e0c749e5d534c.md b/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5dacd5e0c749e5d534c.md index 5cccb4f6546..09cb893bd9f 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5dacd5e0c749e5d534c.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5dacd5e0c749e5d534c.md @@ -11,12 +11,16 @@ dashedName: how-can-you-debug-your-react-components-using-react-devtools 然而,它們並不適合用來尋找和修正 React 應用程式中的錯誤。因此,React 團隊開發了一個名為「React Developer Tools」(又稱 React DevTools)的工具,讓你可以檢查、偵錯和評測 React 應用程式。 +## 安裝 React DevTools + React DevTools 可作為 Chrome、Edge 和 Firefox 的瀏覽器擴充套件使用。如果你使用的是 Chrome 或 Edge,請前往 Chrome 線上應用程式商店,搜尋「React Developer Tools」,並將它添加到你的瀏覽器。 如果你使用 Firefox,請前往 Firefox 增益集頁面,搜尋該工具,並將它添加到你的瀏覽器。 如果你使用 Safari,你可以透過執行 `npm install -g react-devtools` 或 `yarn global add react-devtools` 從 npm 安裝 React DevTools。 +## 探索 Components 和 Profiler 分頁 + 安裝並啟用 React DevTools 後,如果你在瀏覽器中開啟 React 應用程式,然後開啟瀏覽器的開發者工具,你應該會看到兩個額外的分頁:組件 和 效能(效率)評測器。 「組件」標籤以樹狀檢視格式顯示每個組件給你。透過它,你可以: @@ -29,6 +33,8 @@ React DevTools 可作為 Chrome、Edge 和 Firefox 的瀏覽器擴充套件使 另一方面,Profiler 分頁可幫助你記錄並分析組件效率,讓你能識別不必要的重新呈現、查看提交持續時間,以及你可以最佳化的項目。 +## 檢查組件、props 和 state + 這是一個簡單的應用程式,向你展示如何檢查組件及其擁有的任何 props 和 state。這與我們在先前關於 prop drilling 的課程中使用的程式碼類似: ```jsx @@ -73,6 +79,8 @@ const Grandchild = ({ greeting, response }) => { 要在組件中將資料記錄到主控台,請檢查相符的 DOM 元素並查看組件的原始碼。右上角的圖示可讓你執行這些操作。如果你選擇 `Grandchild` 組件並點擊 `Log the component data to the console` 按鈕,它將在主控台中記錄 props、state、掛鉤、節點和其他資料。 +## 偵錯 props 不匹配 + 你可能會在 React 中遇到的一個常見錯誤稱為 props 不匹配。 例如,假設你錯誤地將 `reply` 作為 prop 傳入 `Child` 組件,而不是 `response`: diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5f19a0f0b75343f1905.md b/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5f19a0f0b75343f1905.md index 1e4cb681b9c..77403c27180 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5f19a0f0b75343f1905.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-react-strategies-and-debugging/67d2f5f19a0f0b75343f1905.md @@ -11,6 +11,8 @@ React Server Components(RSCs)是一種改變 React 開發者處理方式的 讓我們來看看什麼是伺端組件、它們如何運作,以及促使伺端組件被引入的原因。 +## 什麼是 React 伺服器組件? + React Server Components 是專門在伺服器端呈現的 React 組件,伺服器僅將最終的 HTML 傳送到客戶端。這表示那些組件可以直接存取伺服器端資源,並大幅減少傳送到瀏覽器的 JavaScript 數量。 React 應用程式傳統上使用一種「客戶端組件」系統,該系統控制典型 React 應用程式中的所有事務,例如算繪、互動性和副作用。直到最近引入 React 伺服端組件之前,「客戶端組件」這個術語很少被使用。 @@ -23,6 +25,8 @@ React 應用程式傳統上使用一種「客戶端組件」系統,該系統 伺服端組件最初在 Next.js 中普及並且隨時可用。其他框架如 Remix 和 Gatsby 正在追趕,並且有一個名為 `vite-plugin-react-server` 的實驗性外掛程式,讓你可以建置伺服端組件。 +## 使用伺服器組件進行資料擷取 + 那麼伺服端組件如何運作? 展示 React Server Components 最佳方式之一是使用資料擷取。 @@ -55,6 +59,8 @@ export default Users; 因為 React Server Components 僅在伺服端執行,你可以直接從 API 取得資料並只算繪一次。此外,由於資料擷取發生在較接近原始碼的伺服端,你的應用程式效能可能會更好,尤其是對於網路連線較慢的人。 +## 為客戶端組件添加互動性 + 一個主要的陷阱是所有伺服端組件的程式碼都保留在伺服端,並不會被傳送到瀏覽器。這表示你無法對它們使用 React 掛鉤,且它們無法存取 Web API 或瀏覽器事件監聽器。那麼你該如何為它們添加互動性? 在 Next.js 的應用程式路由中,所有組件預設都是伺服端組件。如果你想為組件添加互動性,你需要使用 `"use client"` 指令將組件標記為客端組件。 @@ -117,6 +123,8 @@ const Users2 = () => { export default Users2; ``` +### 處理點擊事件 + 如果你想添加像點擊事件這樣的互動性,該組件也必須標記為客戶端組件: ```jsx diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-routing-react-frameworks-and-dependency-management-tools/67d1ab248317a5a29058a763.md b/curriculum/challenges/chinese-traditional/blocks/lecture-routing-react-frameworks-and-dependency-management-tools/67d1ab248317a5a29058a763.md index 3e64fbacfa3..ab3dc9e9421 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-routing-react-frameworks-and-dependency-management-tools/67d1ab248317a5a29058a763.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-routing-react-frameworks-and-dependency-management-tools/67d1ab248317a5a29058a763.md @@ -15,6 +15,8 @@ dashedName: what-is-dependency-management-and-how-does-it-work-with-libraries-li 要管理專案中的軟體依賴性,你需要使用軟體包管理工具。軟體包管理工具是用於安裝、更新和移除依賴性的工具。許多流行的程式設計語言,如 JavaScript、Python、Ruby 和 Java,都使用軟體包管理工具。 +## 使用 npm 安裝依賴 + 在之前的課程中,你曾簡要介紹過一個流行的軟體包管理工具,叫做 npm。 要使用 Vite 和 npm 創建一個新的 React 專案,你可以執行以下指令: @@ -25,14 +27,20 @@ npm create vite@latest my-react-app -- --template react 如你從之前的課程中回想,這將創建啟動新 React 應用程式所需的所有樣板程式碼。在你能啟動應用程式之前,你需要透過執行 `npm install` 或簡寫為 `npm i` 來安裝相依套件。 +## `package.json` 檔案 + 你可以在位於你的專案根目錄中的 `package.json` 檔案查看所有相依性。 `package.json` 檔案是在專案中包含關於你的專案的詮釋資料的關鍵設定檔案,包括其名稱、版本和相依性。它也定義了腳本、授權資訊以及其他有助於管理專案及其相依性的設定。 +## `node_modules` 資料夾 + 當你安裝相依套件時,`node_modules` 資料夾將會被添加到你的專案。 `node_modules` 資料夾是儲存你的專案所需所有軟體包和函式庫的地方。此資料夾包含 `package.json` 檔案中列出的相依性實際程式碼,包括你的專案直接相依性以及這些相依性的任何相依性。 +## 依賴 + React 專案所需的兩個核心依賴將是 `react` 和 `react-dom` 軟體包: ```json @@ -44,8 +52,12 @@ React 專案所需的兩個核心依賴將是 `react` 和 `react-dom` 軟體包 `package.json` 會列出你目前使用的那些軟體包版本。如果你需要在區域的更新任何軟體包,你可以執行 `npm update` 指令。或者你可以透過執行 `npm update -g` 指令來全域的更新所有軟體包。 +## `package-lock.json` 檔案 + 除了 `package.json` 檔案之外,你還會有一個 `package-lock.json` 檔案。這個檔案會鎖定你的專案正在使用的所有軟體包的確切版本。當你更新軟體包時,新的版本也會在鎖定檔案中更新。 +## 開發依賴 + `package.json` 檔案的另一個重要面向是開發相依性: ```json @@ -65,6 +77,8 @@ React 專案所需的兩個核心依賴將是 `react` 和 `react-dom` 軟體包 開發相依性是只用於開發而非生產環境的軟體包。舉例來說,像 Jest 這樣的測試函式庫就是一個例子。你會將 Jest 安裝為開發相依性,因為你只在本機測試你的專案時使用它,且在應用程式於生產環境執行時不需要它。 +## 選擇軟體包管理工具 + 在本課程的大部分時間裡,我們一直專注於 npm。但還有其他軟體包管理工具,例如 yarn 和 pnpm。那麼你應該為你的專案使用哪一個軟體包管理工具呢? 嗯,簡短的回答是視情況而定。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-searching-and-sorting-algorithms/68420c70e4bfe26d52b780dc.md b/curriculum/challenges/chinese-traditional/blocks/lecture-searching-and-sorting-algorithms/68420c70e4bfe26d52b780dc.md index 6aa5c86e97a..fb867f31a71 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-searching-and-sorting-algorithms/68420c70e4bfe26d52b780dc.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-searching-and-sorting-algorithms/68420c70e4bfe26d52b780dc.md @@ -9,6 +9,8 @@ dashedName: what-is-binary-search-and-how-does-it-differ-from-linear-search 在計算機科學中,搜尋一個項目列表是常見的情況。當談到搜尋時,你應該知道兩個關鍵的演算法:線性搜尋和二分搜尋法。 +## 什麼是線性搜尋? + 線性搜尋從列表的開頭開始,並迭代每個項目,直到找到它正在尋找的標的值。 如果找到標的值,則傳回它在列表中的索引。如果找不到標的值,則傳回 `-1`。我們傳回 `-1` 是因為它在大多數程式語言中不是有效的索引。 @@ -27,18 +29,24 @@ def linear_search(arr, target): 如果我們將標的值改為 `5`,函式會傳回 `-1`,因為 `5` 不在列表中。 +## 線性搜尋的時間與空間複雜度 + 雖然這是一個相對簡單的演算法,但它不是最高效的。如果你有一個大型的項目列表,線性搜尋可能需要很長時間才能找到標的值。 線性搜尋的時間複雜度是 `O(n)`,因為搜尋整個列表所需的時間會隨著列表大小線性增加。 線性搜尋的空間複雜度是 `O(1)`,因為它不需要任何額外空間來搜尋整個列表。 +## 什麼是二分搜尋法? + 二分搜尋法是一種用於搜尋大量條款的高效演算法。條件是列表必須以遞增順序排序。 二分搜尋法的運作方式是將列表對半分割,並檢查標的值是否在列表的中間。如果標的值在列表的中間,則傳回標的值的索引。否則,演算法會檢查標的值是在列表的左半部還是右半部。 它會持續將列表剩餘的部分一分為二,直到找到標的值。如果標的值不在列表中,則傳回 `-1`。 +## 實作二分搜尋法 + 以下是二分搜尋法的程式碼範例: ```python @@ -71,10 +79,14 @@ def binary_search(arr, target): 我們會持續重複這個處理程序,直到找到標的或確定標的不在列表中。 +## 二分搜尋法的時間與空間複雜度 + 二分搜尋法的時間複雜度是 `O(log n)`,因為搜尋列表所需的時間會隨著列表大小以對數方式成長。 二分搜尋法的空間複雜度是 `O(1)`,因為它在搜尋列表時不需要任何額外空間。 +## 結論 + 二分搜尋法和線性搜尋可以用於你在電腦科學中會遇到的各種問題。了解這兩種演算法之間的差異以及何時使用每一種非常重要。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-styling-lists-and-links/672b951b1bf78038b1a2a0e7.md b/curriculum/challenges/chinese-traditional/blocks/lecture-styling-lists-and-links/672b951b1bf78038b1a2a0e7.md index af9bea6f088..686a9a689e7 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-styling-lists-and-links/672b951b1bf78038b1a2a0e7.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-styling-lists-and-links/672b951b1bf78038b1a2a0e7.md @@ -19,6 +19,8 @@ dashedName: how-do-the-different-list-style-properties-work 每一個在定義列表外觀時扮演不同的角色。 +## `list-style-type` + `list-style-type` 屬性允許你定義列表中使用的項目符號或數字的型別。 對於無序列表,你可以從多種項目符號樣式中選擇,例如實心圓、空心圓或方塊。 @@ -43,6 +45,8 @@ dashedName: how-do-the-different-list-style-properties-work `list-style-type` 屬性是這三個中最常使用的,因為它直接影響你的列表中項目符號或編號樣式的外觀。 +## `list-style-position` + `list-style-position` 屬性控制項目符號或編號相對於列表項目內容的位置。你可以使用兩個值:`inside` 和 `outside`。 當你使用值 `outside` 時,項目符號或編號會出現在內容外側,這是預設行為。 @@ -72,6 +76,8 @@ dashedName: how-do-the-different-list-style-properties-work 當你想要控制列表內容的對齊方式時,`list-style-position` 屬性會很有用,特別是在單一列表項目中有多行文字的情況下。 +## `list-style-image` + `list-style-image` 屬性允許你將影像作為列表項目的項目符號。這對於為你的列表添加獨特的視覺風格非常有用。 以下是使用 `list-style-image` 的範例: @@ -102,6 +108,8 @@ dashedName: how-do-the-different-list-style-properties-work 使用 `list-style-image` 時,請確保你選擇的影像是小且適合你的網頁設計。如果影像太大或太複雜,會使列表較難閱讀。 +## `list-style` 簡寫屬性 + 你可以將三個屬性 – `list-style-type`、`list-style-position` 和 `list-style-image` – 組合成單一的 `list-style` 簡寫屬性。 簡寫中值的順序不重要,但三者都可以一起指定。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-abstraction/68c3bc80f67363a31791fe1c.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-abstraction/68c3bc80f67363a31791fe1c.md index e7ae2369594..5c1f159eeb7 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-abstraction/68c3bc80f67363a31791fe1c.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-abstraction/68c3bc80f67363a31791fe1c.md @@ -9,16 +9,22 @@ dashedName: what-is-abstraction-and-how-does-it-help-keep-complex-systems-organi 既然我們已經探討了封裝、繼承和多型,現在讓我們討論物件導向程式設計的下一個關鍵概念-抽象性。 +## 什麼是抽象性? + 抽象性是隱藏複雜實作細節並僅顯示物件或系統的必要特性的處理程序。將它視為專注於某物的功能,而非其運作方式。 抽象性不限於 Python。它是一個可以在許多支援物件導向程式設計的語言中實作的程式設計概念。 +## 抽象性的真實世界範例 + 為了說明抽象性,想像你正在開車。當你坐在駕駛座時,你會與方向盤、排檔桿以及油門和煞車踏板等重要零件互動。你不需要知道引擎如何運作、變速箱如何換檔,或煞車系統背後的物理原理,因為這些都是複雜的實作細節。 這就是抽象性的運作!它為你提供一個簡化的介面來與複雜系統互動。 以汽車為例,簡化的介面是方向盤、煞車和油門,而複雜的系統則是整輛汽車本身。 +## Python 中使用 `abc` 模組實現抽象性 + 至於 Python 如何實作抽象性,它是透過 `abc` 模組來完成的。 此模組提供 `ABC` 類別(代表「抽象的基礎類別」)和 `@abstractmethod` 裝飾器。 @@ -27,6 +33,8 @@ dashedName: what-is-abstraction-and-how-does-it-help-keep-complex-systems-organi 另一方面,抽象方法是在抽象基礎類別(ABC)中使用 `@abstractmethod` 裝飾器宣告的方法。它可能沒有實作或只有基本的預設實作。然而,任何子類別必須改寫它,才能被視為具體的且可實例化,即使提供了預設實作。 +## 抽象類別語法 + 以下是 Python 中抽象類別的基本語法: ```py @@ -49,6 +57,8 @@ class ConcreteClassTwo(AbstractClass): print('Implementation in ConcreteClassTwo') ``` +## 使用抽象基礎類別 + 這裡有一個基本範例: ```py @@ -94,6 +104,8 @@ for animal in animals: - 我們創建具體的類別 `Dog`、`Cat` 和 `Monkey`,它們必須改寫 `make_sound` 抽象的行為。 - 我們實例化具體的類別並呼叫它們的 `make_sound` 方法,以展示它們各自如何以自己的方式實作 `make_sound` 抽象的行為。 +## 抽象類別無法被實體化 + 請記住你無法創建 Animal 類別的實體。如果你嘗試這麼做,會發生以下情況: ```py @@ -113,6 +125,8 @@ bird = Bird() # without an implementation for abstract method 'make_sound' ``` +## 帶有實體屬性的抽象類別 + 這裡有另一個範例,這次是你可以傳遞給具體方法實體的實體屬性: ```py @@ -153,12 +167,14 @@ for toy in toys: # Rex says ROOOOAR! ``` -在此範例中:  +在此範例中: - 我們有一個抽象的基礎類別 `TalkingToy`,它定義了任何會說話玩具的藍圖。 - 子類別 `RobotToy`、`TeddyBearToy` 和 `DinosaurToy` 各自以自己的方式實作 `speak` 方法。 - 當我們創建這些子類別的實體並呼叫 `speak` 方法時,每個玩具都會以其獨特的方式發聲。 +## 抽象性如何保持複雜系統的組織性 + 總結來說,Python 中的抽象性透過提高可重複使用性來簡化複雜系統。 你已經看到如何從抽象的類別重複使用單一方法於多個子類別,同時強制每個子類別提供其特定行為。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-code-clarity/672d49d93b54b85faa4dbad7.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-code-clarity/672d49d93b54b85faa4dbad7.md index 13712ceb722..67093ba0901 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-code-clarity/672d49d93b54b85faa4dbad7.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-code-clarity/672d49d93b54b85faa4dbad7.md @@ -7,41 +7,74 @@ dashedName: what-is-the-role-of-semicolons # --description-- -在 JavaScript 和許多其他程式設計語言中,分號有助於劃分述語並提升程式碼可讀性。 +就像句號(`.`)可以標示英文句子的結尾,分號(`;`)也可以用來標示 JavaScript 中述語的結尾。然而,述語不一定等同於原始碼的行數。述語可以跨越多行,而一行中也可以包含多個述語。 -在 JavaScript 中,分號(`;`)用來顯示、指出述語的結尾。 +例如: -就像句號(`.`)標示英文句子的結尾,分號則表示可執行程式碼行的結尾。這讓 JavaScript 引擎能夠區分不同的指令。 +```js +let variableOne = 5; +let variableTwo = 10; +``` -例如: +在這段程式碼中,分號明確指出每個述語的結尾。JavaScript 也有自動分號插入(ASI),允許這些宣告在沒有明確分號的情況下仍然有效: + +```js +let variableOne = 5 +let variableTwo = 10 +``` + +在這個範例中,ASI 讓 JavaScript 將每個宣告視為獨立的述語,即使沒有分號。然而,ASI 並不是在每個換行處都插入分號。 + +例如,`return` 述語後的換行可能會導致意外行為: + +```js +function getValue() { + return + { + value: 42 + }; +} +``` + +這裡,ASI 在 `return` 後插入了分號,因此函式傳回 `undefined` 而不是物件。將物件寫在同一行可以避免這種行為: ```js -let variableOne = 5; // Declare a variable and assign a value -let variableTwo = 10; // Declare another variable and assign a value +function getValue() { + return { + value: 42 + }; +} ``` -在這段程式碼中,每行結尾的分號標示每個述語的結束。若沒有它們,JavaScript 引擎可能會難以判斷一個述語結束和另一個述語開始的位置。 +這說明了為什麼換行和述語邊界不一定相同。 -分號主要用於標示述語的結尾。這有助於 JavaScript 引擎理解各個指令的分隔,對於正確執行非常重要。 +當換行可能讓兩段程式碼被解讀為一個運算式時,分號也很有用。立即呼叫函式運算式(IIFE)是一種函式,定義後立即執行。創建 IIFE 的一種方法是將匿名函式(沒有名稱的函式)包在小括號中,並在結尾加上 `()` 來呼叫它。當前述述語沒有以分號結尾時,IIFE 可能會造成問題: ```js -let a = 1; // Statement ends here -let b = 2; // Another statement starts here +const message = "Hello" + +(function () { + console.log(message); +})() ``` -雖然 JavaScript 有自動分號插入(ASI)可以自動添加分號,但明確地包含它們可以提升程式碼的清晰度,並有助於防止因意外的 ASI 行為而產生的錯誤。 +這裡,JavaScript 沒有在字串宣告後插入分號,因為後面的 `(` 可以繼續初始化運算式。JavaScript 將初始化運算式解析為對字串 `"Hello"` 的呼叫,並將函式運算式當作引數。這在 IIFE 執行前就丟出 `TypeError`。加上分號則在 IIFE 前結束宣告: -分號用於許多程式設計語言,包括 C、C++ 和 Java。 +```js +const message = "Hello"; -分號標示述語或指令的結尾,幫助編譯器或直譯器正確解析程式碼。編譯器將高階程式設計語言的程式碼轉換成機器可讀的程式碼,進而產生可執行檔案。 +(function () { + console.log(message); +})() +``` -透過明確劃分述語,分號有助於程式碼的可讀性和維護性。分號有助於防止程式碼執行中的歧義,並確保述語正確終止。 +明確的分號讓變數宣告和 IIFE 成為獨立的述語。 -分號是 JavaScript 和許多其他程式語言的基本零件。 +分號在許多程式語言中都有使用,包括 C、C++ 和 Java。它們的具體規則因語言而異,但通常用來指出述語的結尾。 -它們標示述語的結尾、提升程式碼可讀性,並有助於避免與自動分號插入相關的錯誤。 +編譯器會將原始碼轉換成另一種形式,例如機器碼、位元組碼或中介表示法,這取決於語言和編譯器。編譯不一定會產生獨立的可執行檔。 -透過正確理解和使用分號,你可以撰寫更可靠且易於維護的程式碼。 +一致使用分號可以讓述語邊界更清楚,並使程式碼更容易閱讀和維護。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-code-clarity/672d49e65a1c855fe7bb3fdb.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-code-clarity/672d49e65a1c855fe7bb3fdb.md index 87979ea0765..fd7c3cc6317 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-code-clarity/672d49e65a1c855fe7bb3fdb.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-code-clarity/672d49e65a1c855fe7bb3fdb.md @@ -21,7 +21,7 @@ JavaScript 提供兩種方式為你的程式碼添加註解:單行註解和多 這種類型的註解非常適合用於簡短的說明或澄清。 -這裡是一個來自 freeCodeCamp 課程專案檔案的真實範例: +這裡是來自 freeCodeCamp 課程專案檔案的真實範例: ```js // This is to allow English to build without having to download the i18n files. @@ -41,7 +41,7 @@ const I18N_CURRICULUM_DIR = path.resolve( 1. 它有助於防止在未諮詢團隊的情況下進行不必要的更改或刪除,這可能導致錯誤或問題。 -另一種註解是多行註解。以下是基本語法: +另一種註解是多行註解。基本語法如下: ```js /* @@ -85,7 +85,7 @@ const price = 10; 在這種情況下,這裡不需要添加任何註解,因為程式碼本身已經很清楚。目標是提升可讀性,而不是用不必要的說明使程式碼變得混亂。 -如果你想在學習撰寫程式碼時,為你的個人專案添加註解,那是可以的。但一旦你開始與其他開發者合作處理真實世界的專案,就很重要不要為自我解釋的程式碼使用註解。 +如果你在學習程式時想為個人專案添加註解,這沒問題。但一旦開始與其他開發者合作真實專案,就很重要不要為自我解釋的程式碼使用註解。 同時,也很重要的是不要使用註解來解釋混亂、過於複雜或寫得不好的程式碼。在這些情況下,最好重構或更改你的程式碼,讓其他開發者能更好地理解發生了什麼。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-effects-and-referencing-values-in-react/67d1ec87b34cee1d9219f7e9.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-effects-and-referencing-values-in-react/67d1ec87b34cee1d9219f7e9.md index 57e83be1799..6203467d37e 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-effects-and-referencing-values-in-react/67d1ec87b34cee1d9219f7e9.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-effects-and-referencing-values-in-react/67d1ec87b34cee1d9219f7e9.md @@ -11,14 +11,18 @@ React 提供許多內建的掛鉤,讓你在專案中實作不同的功能。 但有時候,你需要添加一個內建掛鉤都無法幫助的功能。幸運的是,你可以在 React 中創建你自己的訂製掛鉤。 +## 訂製掛鉤的利益 + 訂製掛鉤並不像看起來那麼複雜。它們只是可重複使用的函式(程式),讓你能在多個組件之間共享邏輯。這表示可重複使用性是你想要建造自己掛鉤的另一個原因。 -使用訂製掛鉤,你可以將邏輯從任何使用它們的組件中抽離出來,例如資料擷取、狀態管理、切換、像是檢查使用者線上或離線狀態等副作用。 +使用訂製掛鉤,你可以將邏輯從任何使用它們的組件中抽離出來,例如資料擷取、狀態管理、切換、像是檢查使用者線上或離線狀態等副作用。 你接著可以匯入該掛鉤以在任何組件中使用,這樣你就能專注於這些組件內的呈現與展示。這表示重複次數更少、複製更少,也代表當你想進行任何更新時,需要修改的地方更少。 現在,讓我們來看看你如何製作你自己的訂製掛鉤。 +## 訂製掛鉤的命名 + 在 React 中,所有內建掛鉤都以字 `use` 開頭,所以你的訂製掛鉤也應該遵循相同的慣例。你的訂製掛鉤名稱也應該清楚地傳達它的功能。 所以,如果你的訂製掛鉤… @@ -29,6 +33,8 @@ React 提供許多內建的掛鉤,讓你在專案中實作不同的功能。 - 或者如果它實作了防彈跳,`useDebounce` 是一個不錯的名稱 +## 建立防彈跳掛鉤 + 假設你想要建置一個訂製掛鉤,為你的應用程式添加防彈跳功能。 防彈跳(Debouncing)是一種程式設計技巧,用來限制函式執行的頻率。它的運作方式是等待使用者停止執行某個動作達到指定的時間後,才執行該函式。例如,在搜尋框中,防彈跳不會在每次按鍵時都進行 API 呼叫,而是等待使用者停止輸入,例如 500 毫秒後才執行。 @@ -69,6 +75,8 @@ export { useDebounce }; 在這裡的 `useEffect` 掛鉤中,你使用 `setTimeout` 來設定 `debouncedValue`。然後你傳回一個清理函式,該函式會在 `value` 或 `delay` 改變,或組件卸載時使用 `clearTimeout` 清除先前的逾時。 +## 範例:使用防彈跳掛鉤 + 要使用這個掛鉤,我們已準備好一個 `footballers` 陣列,並搭配簡單的搜尋欄來篩選: ```js diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-functions-and-scope/67fe859f55cd33356e322fd3.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-functions-and-scope/67fe859f55cd33356e322fd3.md index 0d5dc027aba..435a7badfea 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-functions-and-scope/67fe859f55cd33356e322fd3.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-functions-and-scope/67fe859f55cd33356e322fd3.md @@ -7,6 +7,8 @@ dashedName: how-do-functions-work-in-python # --description-- +## 什麼是函式? + 函式是可重複使用的程式碼片段,當你呼叫它們時會執行。Python 提供內建函式,包括你在之前課程中使用過的 `print()`。 另一個有用的內建函式(程式)是 `input()`,它讓你提示使用者輸入: @@ -25,6 +27,8 @@ print(int(True)) # 1 print(int(False)) # 0 ``` +## 定義與呼叫函式 + 你也可以撰寫你自己的訂製函式(程式)。為此,你使用 `def` 關鍵字,接著是你想給函式的名稱、一對小括弧,然後是冒號。接著在新的一行,撰寫函式應該執行的程式碼。函式執行的程式碼也稱為函式的主體。 這是一個名為 `hello` 的訂製函式(程式)範例,它會將字串 `Hello World` 列印到終端機: @@ -42,6 +46,8 @@ hello() # Hello World 請注意 `print('Hello World')` 前的縮排。正如你可能從先前的課程中回想起來,Python 依賴縮排來判斷哪些述語群組屬於同一個區塊。這些述語群組稱為程式碼區塊。 +## 使用參數與引數 + 這裡有另一個簡單的函式(程式),會將兩個數字的總和列印到終端機: ```python @@ -67,6 +73,8 @@ calculate_sum() # TypeError: calculate_sum() missing 2 required positional arguments: 'a' and 'b' ``` +## 從函式傳回值 + 函式(程式)也使用特殊的 `return` 關鍵字來離開函式(程式)並傳回一個值。如果你沒有明確地使用 `return`,Python 預設會傳回 `None`。 `None` 是一個特殊的值,代表沒有值。它是 `NoneType` 型別中唯一的值。`None` 是不可變的且為假值,這表示它無法被改變,且在布林值的背景關係中會被評估為 `False`。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-how-http-dns-tcpip-work/69661d2fc36411aa9e25ea64.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-how-http-dns-tcpip-work/69661d2fc36411aa9e25ea64.md index 2da48ef482a..407ccc3fde6 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-how-http-dns-tcpip-work/69661d2fc36411aa9e25ea64.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-how-http-dns-tcpip-work/69661d2fc36411aa9e25ea64.md @@ -13,7 +13,7 @@ HTTP 回應碼是三位數字碼,網頁伺服器用來與客戶端溝通,讓 它們提供有關請求是否成功處理或在處理請求時是否發生錯誤的資訊。 -我們將在本講座中涵蓋一些最常見的項目。 +我們將在本課程中涵蓋一些最常見的回應碼。 ## 成功代碼 @@ -29,7 +29,7 @@ HTTP 回應碼是三位數字碼,網頁伺服器用來與客戶端溝通,讓 現在讓我們來談談**重新導向代碼**。 -當客戶端請求的資源已移動到不同位置或客戶端需要採取額外步驟以完成請求時,這些代碼會由伺服器傳回。 +當客戶端請求的資源已移動到不同位置,或客戶端需要採取額外步驟來完成請求時,伺服器會回傳這些代碼。 這些程式碼以數字 3 開頭。 @@ -37,15 +37,15 @@ HTTP 回應碼是三位數字碼,網頁伺服器用來與客戶端溝通,讓 程式碼 **302 Found** 顯示客戶端請求的資源已暫時移動到另一個位置。伺服器應在回應中提供新的 URL,客戶端應將使用者重新導向到此 URL。然而,原始 URL 未來可能仍可用,因為此變更是暫時的。這是回應碼 301 和 302 之間的主要差異。 -伺服器傳回 **304 Not Modified** 程式碼,以告訴客戶端所請求的資源自上次請求以來未被修改。若內容未改變,伺服器會傳送此程式碼以避免重複傳送已傳送的資料。這是一種效率優化技術。 +代碼 **304 Not Modified** 是伺服器回傳給客戶端,表示所請求的資源自上次請求後未被修改。伺服器傳送此代碼是為了避免重複傳送未變更的資料,這是一種效率優化技術。 ## 客戶端錯誤代碼 -現在我們將開始深入探討**錯誤代碼**。 +現在我們開始深入探討**錯誤代碼**。 -錯誤可能由客戶端和伺服端引起。我們將先討論客戶端錯誤代碼。 +錯誤可能由客戶端或伺服器引起。我們先談談客戶端錯誤代碼。 -當請求因客戶端產生的問題而無法完成時,會傳回客戶端錯誤代碼。 +4xx 回應表示客戶端似乎犯了錯誤。 這些錯誤代碼以數字 4 開頭。 @@ -53,19 +53,19 @@ HTTP 回應碼是三位數字碼,網頁伺服器用來與客戶端溝通,讓 **401 Unauthorized** 狀態碼與驗證有關。它顯示客戶端必須提供某些驗證憑證,才能存取所請求的資源。這些憑證可能包括使用者名稱和密碼。 -當客戶端未被授權存取所請求的資源時,會傳回 **403 Forbidden** 代碼。401 與 403 的差異在於,即使客戶端擁有有效的驗證憑證,403 表示該客戶端對其所請求的特定資源沒有必要的權限。 +**403 Forbidden** 代碼表示客戶端未被授權存取所請求的資源。401 與 403 的差別在於,403 表示即使客戶端擁有有效的驗證憑證,仍然沒有該資源所需的權限。 -當伺服器找不到資源時,會傳回 **404 Not Found** 代碼。可能是資源已被刪除,或是 URL 中有拼寫錯誤,導致伺服器無法找到該資源。伺服器也可能遇到暫時性問題,導致此錯誤代碼。 +**404 Not Found** 代碼表示伺服器找不到該資源。可能是資源已被刪除,或 URL 有錯字導致伺服器無法找到資源。404 回應並不表示該狀況是暫時還是永久的。 ## 伺服端錯誤代碼 -接下來,我們有**伺服器錯誤代碼**。當請求因伺服器端的問題無法處理時,這些代碼會由伺服器傳回。 +接著,我們來看**伺服器錯誤代碼**。當請求因伺服器端問題無法處理時,伺服器會回傳這些代碼。 -**500 Internal Server Error** 錯誤代碼顯示伺服端發生了意外錯誤。此錯誤可能由多種問題引起,範圍從設定問題到暫時性問題。 +**500 Internal Server Error** 代碼表示伺服器發生了意外錯誤。這種錯誤可能由各種問題引起,從設定問題到暫時性問題皆有可能。 當伺服器嘗試與另一台伺服器通訊但收到該伺服器的無效回應時,會傳回 **502 Bad Gateway** 錯誤代碼。此類錯誤有廣泛的可能原因。 -**503 Service Unavailable** 錯誤代碼顯示伺服器暫時無法控制代碼該請求,因此客戶端應該稍後再試。此錯誤的常見原因包括維護工作以及伺服器目前無法控制代碼的高流量請求。 +**503 Service Unavailable** 錯誤代碼表示伺服器暫時無法處理請求,客戶端應稍後再試。此錯誤常見原因包括維護作業和伺服器目前無法處理的大量請求。 HTTP 回應碼對於理解客戶端與網頁伺服器之間的通訊至關重要。透過理解這些碼,你可以排除故障並偵錯你的網頁應用程式。 @@ -133,7 +133,7 @@ HTTP 回應碼對於理解客戶端與網頁伺服器之間的通訊至關重要 --- -伺服端暫時無法使用。 +伺服器暫時無法使用。 ### --feedback-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68420be9af9d89620af7944a.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68420be9af9d89620af7944a.md index 3cd55f4b417..28f670210bf 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68420be9af9d89620af7944a.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68420be9af9d89620af7944a.md @@ -7,10 +7,14 @@ dashedName: what-is-object-oriented-programming-and-how-does-encapsulation-work # --description-- +## 什麼是物件導向程式設計? + 物件導向程式設計,也稱為 OOP,是一種程式設計風格,開發者將程式碼中的所有事物視為現實世界的物件。 類別就像是用來生成物件的藍圖。每一個由類別生成的物件都有定義資料的屬性和定義物件行為的函式。 +## 建立類別和物件 + 在之前的課程中,你學會了如何創建類別。這裡是語法的提醒: ```py @@ -41,6 +45,8 @@ print('Car 2 Brand:', car2.brand) # Car 2 Brand: Lambo print('Car 2 Color:', car2.color) # Car 2 Color: green ``` +## 什麼是封裝? + 物件導向程式設計有四個關鍵原則,幫助你有效地組織和管理程式碼。它們是封裝、繼承、多型和抽象性。 本課程的其餘部分將專注於封裝的運作方式。 @@ -49,6 +55,8 @@ print('Car 2 Color:', car2.color) # Car 2 Color: green 透過封裝,你可以將物件的內部狀態隱藏在一組簡單的公開方法和屬性背後,這些方法和屬性就像門一樣。在這些門的背後,是控制資料如何變更以及誰可以看到它的私有屬性和方法。 +## 使用單一底線前置式 + 假設你想追蹤錢包餘額。你想允許人們從錢包存入或提取金錢,但沒有人應該能夠直接竄改餘額。 在這種情況下,你可以將 `deposit()` 和 `withdraw()` 設為公開方法,並將餘額隱藏在 `_balance` 屬性下: @@ -69,6 +77,8 @@ class Wallet: 依慣例,為屬性和方法加上單一底線前置式表示它們是供內部使用的。沒有人應該從類別外部直接存取它們,因為這違反了封裝的原則,可能會導致錯誤。 +## 使用雙底線前置式 + 雖然單一底線前置式只是慣例,但使用雙底線前置式來標示屬性和方法,能有效防止它們被類別外部存取,使這些屬性和方法成為私有。 ```py @@ -119,6 +129,8 @@ acct_two.deposit(150) print(acct_two.get_balance()) # 572 ``` +## 定義私有方法 + 你也可以定義一個私有的 `__validate` 方法來檢查每筆存款或提款金額是否為正數: ```py @@ -159,6 +171,8 @@ acct_one.withdraw(58) # ValueError: Insufficient funds 在即將到來的課程中,你將學習更多關於以雙底線作為前置式的屬性如何運作。 +## 總結 + 總結來說,封裝會將內部資料鎖定在明確的公開方法背後。這就是你如何保護你的類別不被竄改,並將驗證集中在一個地方。你可以自由更新或擴充你的程式碼,因為你知道外部程式碼只會接觸你所公開的介面。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68c128cbd77e4ba9ed671937.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68c128cbd77e4ba9ed671937.md index 853c55acc1b..e463bbaa6e1 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68c128cbd77e4ba9ed671937.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-object-oriented-programming-and-encapsulation/68c128cbd77e4ba9ed671937.md @@ -7,8 +7,12 @@ dashedName: what-are-getters-and-setters # --description-- +## 什麼是 Getter 和 Setter? + 取值函式和設值函式是讓你控制類別屬性如何被存取和修改的方法。使用取值函式你可以取得一個值,使用設值函式你可以設定一個值。 +## 什麼是屬性? + 這些動作是透過所謂的屬性完成的。它們是連接取值函式和設值函式的橋樑,並允許存取資料。 屬性表現得像屬性,但在底層行為像方法。你可以將它們視為像方法一樣定義的資料,但運作方式像屬性。這表示你可以用點記法存取屬性,而不是使用小括弧。 @@ -21,10 +25,14 @@ dashedName: what-are-getters-and-setters 例如,你可能想要計算一個值或檢查一個新值是否有效,然後再儲存它。你可以使用類似屬性的方式來做到這點,而不是呼叫一個方法。 +## 使用 `@property` 裝飾器建立屬性 + 在 Python 中,裝飾器是一個函式(程式),用來修改其他函式(程式)或類別的功能,而不改變它們原本的 code。 雖然可以創建訂製的裝飾器,但這超出本課程的範圍。只要知道,為了創建一個屬性,你需要定義一個方法並在其上方放置 `@property` 裝飾器。這會將該方法轉換成屬性,因此它可以像屬性一樣被存取,同時內部會呼叫被裝飾的方法。 +## 建立取值函式 + 這就帶我們進入取值函式。以下是如何使用 `@property` 裝飾器來創建一個取值函式: ```py @@ -50,6 +58,8 @@ print(my_circle.area) # 28.26 注意我們在類別內使用 `_radius` 而不是 radius。底線是 Python 常見的慣例,用來表示該屬性是私有的。換句話說,它表示該屬性是供內部使用,不應該從類別外部直接存取。 +## 建立設值函式 + 為了創建半徑的設值函式,例如,你必須定義另一個同名的行為,並在其上方使用 `@.setter`: 在 `__init__` 中使用 `self.radius` 可確保在物件產生期間設值函式會被執行,因此會立即捕捉到無效的半徑值。 @@ -78,6 +88,8 @@ print('After modifying the radius:', my_circle.radius) # After modifying the rad 在這個範例中,半徑設值函式不僅設定圓的半徑,還執行一個驗證,確保半徑不是負數。 +## Python 如何呼叫取值函式和設值函式 + 一旦你定義了取值函式和設值函式,Python 就會在你使用一般屬性語法時自動在背後呼叫它們: ```py @@ -87,6 +99,8 @@ my_circle.radius = 4 # This will call the setter 請注意,在設值函式內,當指定新值時,不能使用與屬性相同的名稱。那是因為 `self.radius = value` 會在設值函式內部呼叫該設值函式,導致無限遞迴和 `RecursionError`。所以你必須始終使用帶有底線前置式的形式 `self._radius = value`。 +## 建立刪除函式 + 就像你可以透過 getter 控制屬性的存取方式,並透過 setter 控制屬性的修改方式,你也可以透過 deleter 控制屬性的刪除方式。 當你對一個屬性使用 del 述語時,deleter 會執行訂製邏輯。要創建一個 deleter,你需要使用 `@.deleter` 裝飾器: @@ -134,6 +148,8 @@ except AttributeError as e: print("Error:", e) # Error: 'Circle' object has no attribute '_radius' ``` +## 總結 + 重點是: - 取值函式讓你取得一個值,甚至即時計算一個值。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-recursion-and-the-call-stack-python/6a89c69c2abed81397a6c99e.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-recursion-and-the-call-stack-python/6a89c69c2abed81397a6c99e.md index 11e0624a7ec..111f2d76fc5 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-recursion-and-the-call-stack-python/6a89c69c2abed81397a6c99e.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-recursion-and-the-call-stack-python/6a89c69c2abed81397a6c99e.md @@ -7,6 +7,8 @@ dashedName: what-is-recursion-and-how-does-it-work # --description-- +## 什麼是遞迴? + 遞迴是一種函式呼叫自身的技巧。每次呼叫都處理原始問題的較小版本,直到達到停止遞迴的條件。這個停止條件稱為基底案例。 遞迴函式可以解決深度未知的問題,例如遍歷檔案樹。它們也能執行較簡單的任務,例如從指定數字倒數。 @@ -20,6 +22,8 @@ def recursive_countdown(number): recursive_countdown(5) ``` +## 新增基底條件 + 呼叫該函式會列印 `5`,但尚未開始倒數。在讓函式呼叫自身之前,你需要定義它的基底案例。若沒有可達的基底案例,函式會持續呼叫自身。Python 最終會停止呼叫並引發 `RecursionError`。 對於這個倒數,函式應該在 `number` 小於 `1` 時停止: @@ -35,6 +39,8 @@ recursive_countdown(5) `if` 述語是基底案例。當 `number` 小於 `1` 時,`return` 結束該次函式呼叫。 +## 新增遞迴案例 + 函式仍需要一個遞迴案例。遞迴案例會再次呼叫函式,並帶入一個使它朝向基底案例前進的引數。要倒數,呼叫 `recursive_countdown` 並傳入 `number - 1`: ```py @@ -49,6 +55,8 @@ recursive_countdown(5) 這會列印數字 `5`、`4`、`3`、`2` 和 `1`。 +## 改變執行順序 + 遞迴呼叫的位置會影響數字列印的順序。如果 `print()` 呼叫在遞迴呼叫之後,函式會以遞增順序列印數字: ```py @@ -63,8 +71,12 @@ recursive_countdown(5) 這會列印數字 `1`、`2`、`3`、`4` 和 `5`。要理解原因,你需要了解呼叫堆疊。 +## 什麼是堆疊? + 呼叫堆疊是 Python 用來追蹤作用中函式呼叫的後進先出資料結構。當函式被呼叫時,Python 會在堆疊頂端加入該呼叫的訊框。訊框包含函式的引數和區域變數等資訊。 +## 追蹤堆疊呼叫 + 考慮這個版本的倒數: ```py diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-routing-in-express-js/69a9184b42ae3947e4925016.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-routing-in-express-js/69a9184b42ae3947e4925016.md index a578c766ffb..3b2134c1fd9 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-routing-in-express-js/69a9184b42ae3947e4925016.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-routing-in-express-js/69a9184b42ae3947e4925016.md @@ -1,12 +1,14 @@ --- id: 69a9184b42ae3947e4925016 -title: express.Router 是如何運作的? +title: Express.Router 是如何運作的? challengeType: 19 dashedName: how-does-expressrouter-work --- # --description-- +## 什麼是 `express.Router()`? + 在 Express 中,`express.Router()` 是一個強大的功能,幫助你將路由組織成較小且模組化的部分。當你的應用程式規模變大時,這尤其有用。 你不需要將所有路由都定義在一個大型檔案中,而是可以使用路由器將它們拆分成多個檔案。這樣能讓你的程式碼更容易閱讀、維護和擴展。 @@ -17,6 +19,8 @@ dashedName: how-does-expressrouter-work 換句話說,路由器讓你能將相關的路由群組在一起,然後再整合到你的主應用程式中。 +## 使用路由器的利益 + 使用路由器有幾個好處: **關注點分離** @@ -29,6 +33,8 @@ dashedName: how-does-expressrouter-work **主檔案更乾淨** 你不需要在主 `app.js` 或 `server.js` 檔案中塞滿許多路由定義,可以將它們移到路由器中,讓主檔案專注於設定和初始化。 +## 範例:為 `/users` 路徑路由請求 + 讓我們看一個簡單範例,使用 `express.Router()` 定義 `/users` 路徑的路由。 首先,這是 `app.js` 檔案: @@ -74,6 +80,8 @@ router.get("/:id", (req, res) => { module.exports = router; ``` +## 範例如何運作 + 現在讓我們仔細看看整個運作流程。 在 `app.js` 中,我們匯入 `express`,並創建一個 Express 應用程式實體,並指定給名為 `app` 的變數。 @@ -90,6 +98,7 @@ module.exports = router; * `router.get("/:id")` → `GET /users/:id`:回應指定使用者 ID 的使用者詳細資料 +## 組織較大型的應用程式 使用 `express.Router()` 讓你的主檔案保持乾淨,專注於設定。所有與使用者相關的路由都集中在 `userRoutes.js`。 @@ -105,7 +114,7 @@ module.exports = router; ## --answers-- -創建 Express 應用程式的新實體。 +建立 Express 應用程式的新實體。 ### --feedback-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86e9f96f6bbcd0ed8c45.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86e9f96f6bbcd0ed8c45.md index 9dfc9796cd3..ddc6cdb6f31 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86e9f96f6bbcd0ed8c45.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86e9f96f6bbcd0ed8c45.md @@ -11,7 +11,7 @@ HTTPS 代表超文字傳輸安全協定。它是 HTTP 的安全版本。 正如你在之前幾堂課中學到的,HTTP 在你的瀏覽器和網站之間傳輸資料。標準的 HTTP 以純文字形式傳送這些資料,因此任何人都可以攔截這些純文字資料。 -因此,HTTPS 使用一種稱為傳輸層安全性(TLS)的密碼協定來保護這種資料傳輸。TLS 加密兩點之間的通訊通道。舊系統使用安全插口層(SSL),許多網頁主機平台至今仍在使用。 +因此,HTTPS 使用一種稱為 Transport Layer Security(TLS)的加密協定來保護這個資料傳輸。TLS 會加密兩點之間的通訊管道。TLS 取代了較舊的 Secure Sockets Layer(SSL)協定,儘管許多網站主機平台今天仍在設定中提及 SSL。 加密會將資料混淆成無法閱讀的程式碼,只有使用者的瀏覽器和網頁伺服器持有解密的金鑰。 @@ -39,7 +39,7 @@ HTTPS 網站所需的數位憑證的主要目的為何? --- -加快網頁載入速度。 +加快網頁載入時間。 ### --feedback-- @@ -55,7 +55,7 @@ HTTPS 網站所需的數位憑證的主要目的為何? --- -加密伺服器上儲存的所有檔案。 +加密伺服器上所有檔案。 ### --feedback-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86eac73558aaa2679c15.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86eac73558aaa2679c15.md index f8cac32b90a..dd28e4486ec 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86eac73558aaa2679c15.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-security-and-privacy-in-web-applications/6a3b86eac73558aaa2679c15.md @@ -7,6 +7,8 @@ dashedName: how-are-cookies-stored-and-what-are-the-security-and-privacy-implica # --description-- +## 什麼是 Cookies? + Cookies 是網站儲存在你裝置上的小型文字檔,用來記住關於你的某些資訊。 以下是接收和儲存 cookies 的流程: @@ -18,10 +20,14 @@ Cookies 是網站儲存在你裝置上的小型文字檔,用來記住關於你 這個流程讓網站能記住你的登入會話、購物車商品、偏好設定和其他重要資訊。 +## Cookie 儲存的安全風險 + 這種儲存方式帶來重大安全風險。如果駭客取得你裝置的實體存取權或利用惡意軟體讀取你的區域檔案,他們就能竊取你的會話 cookies。 有了被竊取的會話 cookie,攻擊者可以在完全不同的電腦上登入你的帳號,而不需要知道你的密碼。 +## 使用安全旗標的保護 + 為了保護使用者並防止 cookie 被竊取,開發者在設定 cookies 時會使用特定的安全旗標: `HttpOnly` 旗標阻止 JavaScript 讀取 cookie 檔案。這項限制防止攻擊者透過跨站腳本攻擊竊取你的會話語彙單元。 @@ -33,12 +39,16 @@ Cookies 是網站儲存在你裝置上的小型文字檔,用來記住關於你 - `SameSite=Strict` 阻止瀏覽器在任何跨站請求時傳送 cookie。 - `SameSite=Lax` 允許在安全的頂層導覽(例如點擊連結)時傳送 cookie,但阻擋跨站表單提交和 API 請求時傳送。 +## 第三方追蹤 + Cookies 也帶來巨大的隱私影響。第一方 cookies 只追蹤你在特定網站上的行為,但第三方 cookies 則會跨不同網站追蹤你。 廣告網路會在數千個熱門網站上放置這些 cookies。當你瀏覽網路時,該廣告網路會反覆讀取相同的第三方 cookie,建立你個人興趣、搜尋歷史和線上習慣的詳細評測。 這種隱形追蹤造成嚴重的隱私問題,因為它讓企業能在你不知情的情況下監控你的數位生活。 +## 法律與預設保護 + 因應這些威脅,像 GDPR 這樣的隱私法規要求網站顯示 cookie 同意橫幅,讓你知道網站如何使用它所設定的 cookies。這些法律賦予你拒絕追蹤 cookies 的合法權利。 此外,現代瀏覽器預設會阻擋第三方追蹤 cookies,為使用者提供自動化的隱私保護。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e910842f3322350bc8d93.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e910842f3322350bc8d93.md index 79c9490f5e6..6edc8e5ff99 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e910842f3322350bc8d93.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e910842f3322350bc8d93.md @@ -9,7 +9,7 @@ dashedName: what-is-the-terminal-and-how-does-it-differ-from-the-command-line 讓我們來了解終端機,以及它與命令列的不同之處。 -命令列是一種基本的文字輸入介面,允許使用者輸入「指令」,通常是以一連串字元的形式,並透過按下 Enter 鍵來提交或執行它們。你最常在終端機中看到命令列介面。 +命令列是一種基本的文字輸入介面,允許使用者輸入「命令」,通常以一連串字元的形式,並透過按下 Enter 鍵來提交或執行它們。你最常在終端機中看到命令列介面。 終端機是一種特殊的應用程式,提供命令列介面以執行超出基本讀寫操作的系統層級指令。你也可能聽過「終端機模擬器」,它們本質上是包裝基本終端機介面以提供額外特性或功能的應用程式。但在大多數一般用途下,你大概可以安全地將這些稱為「終端機」。 @@ -17,23 +17,21 @@ dashedName: what-is-the-terminal-and-how-does-it-differ-from-the-command-line 但是你如何在你的系統上存取 terminal? -好吧,如果你正在執行現代版本的 Windows,你很可能會有兩種不同的選項。Windows 預設提供兩個不同的 shell 應用程式:Powershell 和命令提示字元。 +如果你使用的是現代版本的 Windows,通常會有兩種不同的選擇。Windows 預設提供兩個不同的 shell 應用程式:PowerShell 和 Command Prompt。 -這兩個 shell 都附帶各自的終端機應用程式(名稱與各自的 shell 相同),所以你可以使用你的應用程式選單來啟動 Powershell 終端機或命令提示字元終端機。 +這兩個 shell 都有自己的終端機應用程式(名稱與各自的 shell 相同),所以你可以透過應用程式選單啟動 PowerShell 終端機或 Command Prompt 終端機。 -Windows 也提供一個相對較新且現代化的終端機模擬器,恰如其分地命名為 Microsoft Terminal。 +Windows 也提供一個相對較新且現代化的終端機模擬器,名稱恰當地叫做 Windows Terminal。 -你可以從 Windows Store 安裝此應用程式,然後像啟動你的 Powershell 或 Command Prompt 終端機一樣啟動它。Microsoft Terminal 的優點是它允許你從同一個應用程式存取 Powershell 和 Command Prompt shell,以及如果你已組態 Windows Subsystems for Linux,還能存取相應的 Linux shell。 +你可以從 Windows 商店安裝這個應用程式,然後像啟動 PowerShell 或 Command Prompt 終端機一樣啟動它。Windows Terminal 的優點是能讓你從同一個應用程式存取 PowerShell 和 Command Prompt shell,以及如果你已組態 Windows Subsystem for Linux,還能存取相應的 Linux shell。 -MacOS 提供一個恰如其名的終端機,名為 "Terminal"。你可以透過你的 spotlight 搜尋或應用程式啟動器來存取它。 - -MacOS 也支援第三方終端機模擬器,例如 iTerm 或 Ghostty。你可以從它們的首頁安裝這些應用程式。 +在 macOS 上,有一個恰當命名為「Terminal」的終端機。你可以透過 Spotlight 搜尋或應用程式啟動器存取它。也支援第三方終端機模擬器,例如 iTerm 或 Ghostty,你可以從它們的首頁安裝這些應用程式。 在 Linux 上,預設的終端機(以及你如何啟動它)高度依賴你使用的發行版和桌面環境。也有很多對第三方終端機模擬器的支援。例如,你可以在 Arch Linux 中設定 kitty,並且可以使用像 wofi 這樣的應用程式管理員來啟動它。 Linux 可說是擁有最多樣化的終端機應用程式可供選擇。這些大多數都可以透過你的發行版的軟體包管理員安裝。 -「終端機」、「shell」和「命令列」之間的區別有時看起來相當吹毛求疵。而且在大多數情況下,這些術語通常可以互換使用。但重要的是要知道它們有特定的意義,以及這些意義分別是什麼。 +「終端機」、「shell」和「命令列」之間的區別有時看起來相當吹毛求疵。大多數情況下,這些詞彙可以互換使用。但重要的是要知道它們有特定的意義,以及每個意義是什麼。 # --questions-- @@ -111,7 +109,7 @@ Linux 可說是擁有最多樣化的終端機應用程式可供選擇。這些 ## --text-- -在 Windows 上,Microsoft Terminal 相較於傳統選項,可提供什麼優勢? +在 Windows 上,Windows Terminal 相較於傳統選項有什麼優勢? ## --answers-- @@ -119,11 +117,11 @@ Linux 可說是擁有最多樣化的終端機應用程式可供選擇。這些 ### --feedback-- -考慮 Microsoft Terminal 提供哪些傳統 Windows 終端機沒有的功能。 +思考 Windows Terminal 提供了哪些傳統 Windows 終端機沒有的功能。 --- -它允許從同一個應用程式存取 Powershell 和 Command Prompt 外殼。 +它允許你從同一個應用程式存取 PowerShell 和 Command Prompt shell。 --- @@ -131,7 +129,7 @@ Linux 可說是擁有最多樣化的終端機應用程式可供選擇。這些 ### --feedback-- -考慮 Microsoft Terminal 提供哪些傳統 Windows 終端機沒有的功能。 +思考 Windows Terminal 提供了哪些傳統 Windows 終端機沒有的功能。 --- @@ -139,7 +137,7 @@ Linux 可說是擁有最多樣化的終端機應用程式可供選擇。這些 ### --feedback-- -考慮 Microsoft Terminal 提供哪些傳統 Windows 終端機沒有的功能。 +思考 Windows Terminal 提供了哪些傳統 Windows 終端機沒有的功能。 ## --video-solution-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e9437536d762823fefab3.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e9437536d762823fefab3.md index a193ebf4f48..6a0ad488f03 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e9437536d762823fefab3.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e9437536d762823fefab3.md @@ -11,20 +11,32 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- 終端機和命令列捷徑可以幫助你簡化工作流程並最大化你的生產力。對於 Linux 和 macOS,兩者皆可追溯至 Unix,許多這些捷徑將會相同。但對於 Windows,則會有一些差異。 +## 上方向鍵 和 下方向鍵 快捷鍵 + 第一個捷徑是 上箭頭 鍵。按下這個鍵可以讓你逐一往後瀏覽你的指令歷史。接著,下箭頭 鍵則可以用來往前瀏覽指令歷史。這兩個鍵讓你能快速瀏覽之前執行過的指令,找到你需要再次執行的指令。 -許多 shell 也會提供自動補全功能,根據你開始輸入的內容建議指令。你可以使用 Tab 鍵來補齊建議的剩餘部分,快速填滿命令列的完整語法。這些建議的產生方式會因 shell 而異。例如,在 zsh 中,這些建議是根據你最近的指令歷史;但在 PowerShell 中,則是根據可用的指令、變數和引數(且較少考慮最近使用的頻率)。 +## 使用 Tab 鍵自動完成 + +許多 shell 也會提供自動完成的功能,根據你開始輸入的內容建議命令。你可以使用 Tab 鍵來填入建議的剩餘部分,快速將完整語法填入命令列。建議內容取決於 shell、你正在輸入的命令,以及你的 shell 組態。舉例來說,當你輸入命令名稱時,Bash 和 zsh 會建議符合的命令;當你輸入引數時,它們通常會建議符合的檔案和目錄名稱。PowerShell 則可以完成命令、參數名稱、變數和檔案路徑。 + +## Control + L 快捷鍵 有時候指令會在終端機上產生大量輸出。這些額外的資訊可能會干擾或破壞你的工作流程。在 Linux 和 macOS 裝置上的 *nix 終端機中,你可以按 Control + L 來清除整個螢幕,並開始一個全新的乾淨提示字元。在 PowerShell 中,Control + L 也會預設清除螢幕,你也可以執行 `cls` 指令達到相同效果。 -如果你需要中斷指令以停止其執行,可以使用 Control + C 來終止該行程。這會結束指令並產生新的提示字元,讓你繼續處理其他工作。對 PowerShell 使用者來說,Control + C 也用於複製文字,且只有在沒有選取文字可複製時才會用來終止行程。 +## Control + C 快捷鍵 + +如果你需要中斷命令以停止其執行,可以按 Control + C。這會向前景中正在執行的命令發送中斷請求,通常會停止該命令並返回新的提示符,讓你繼續處理其他工作。有些程式會自行處理此請求,因此可能會要求你確認或繼續執行。對 PowerShell 使用者來說,Control + C 也用於複製文字,且只有在沒有選取文字可複製時才會中斷命令。 + +## *nix 系統終端機快捷鍵 接下來的幾個快速鍵僅在 *nix 基於終端機中可用,且沒有 PowerShell 替代方案。 -有時你可能需要多工處理,讓某個行程或指令在背景執行,同時你繼續處理其他工作。按下 Control + Z 會將目前行程放到背景任務,並回到命令列,讓你繼續工作。當你需要將焦點切回背景任務時,可以使用 `fg` 指令來恢復它。 +有時你可能需要多工處理,暫停一個命令以執行另一個。按下 Control + Z 會暫停前景中正在執行的命令,並返回命令列,讓你繼續工作。被暫停的命令是暫停狀態,並未執行。如果你想讓它繼續在背景執行,請使用 `bg` 命令;當你需要將它帶回前景時,使用 `fg` 命令。 最後,有些指令你可能需要連續執行兩次。你可以按 上箭頭 鍵往回瀏覽到先前執行的指令,也可以在命令列輸入兩個驚嘆號(`!!`)並按 Enter — 這會自動執行最後一次執行的指令。 +## CLI 快捷鍵參考 +
@@ -46,9 +58,9 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- - + - + @@ -58,12 +70,12 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- - + - + - + @@ -123,11 +135,11 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- ### --feedback-- -此捷徑允許你在一個處理程序執行時同時多工處理。 +此快捷鍵讓你暫停命令,稍後再回來繼續。 --- -它將目前的行程放到背景。 +它會暫停目前的前景行程。 --- @@ -135,7 +147,7 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- ### --feedback-- -此捷徑允許你在一個處理程序執行時同時多工處理。 +此快捷鍵讓你暫停命令,稍後再回來繼續。 --- @@ -143,7 +155,7 @@ dashedName: what-are-some-shortcuts-you-can-use-in-the-command-line-to-speed-up- ### --feedback-- -此捷徑允許你在一個處理程序執行時同時多工處理。 +此快捷鍵讓你暫停命令,稍後再回來繼續。 ## --video-solution-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e944b821130283dc83b2e.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e944b821130283dc83b2e.md index 093dce2e548..16562b2afb2 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e944b821130283dc83b2e.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e944b821130283dc83b2e.md @@ -9,14 +9,20 @@ dashedName: what-is-bash-and-what-are-some-bash-commands 讓我們來了解 Bash 及其一些基本指令。 +## 什麼是 Bash? + Bash 代表 Bourne Again SHell,可以說是在類 Unix 環境中你最常遇到的 shell。因此,了解如何操作這個 shell 並使用常見指令會非常有幫助。 +## 檔案系統導覽指令 + 第一個指令是 `pwd`,它會將目前的工作目錄列印到終端機。所謂「工作目錄」是指終端機目前指向的目錄,這對許多其他指令來說是非常重要的資訊。 你的終端機很可能指向錯誤的目錄。`cd` 指令允許你更改目錄。你可以指定以斜線(`/`)為前置式的絕對路徑、沒有前置式的相對路徑,並使用雙點(`..`)語法移動到父目錄。 下一個指令是 `ls`,它會列出你目前工作目錄的內容。這有助於查看你的目錄中是否存在某個檔案或資料夾。`ls` 指令也接受旗標來顯示隱藏檔案(`-a` 旗標)、檔案權限(`-l` 旗標)以及其他特性。你將在下一課中學習更多關於指令旗標的內容。你也可以使用 `less` 或 `cat` 來查看檔案的內容。 +## 檔案管理指令 + 如果目錄中不包含你需要的檔案或資料夾怎麼辦?有一些稱為 `mkdir` 和 `touch` 的指令可以讓你創建它們。`mkdir` 創建一個新的目錄或資料夾,而 `touch` 創建一個新的檔案。這兩個指令都接受你想要創建的檔案或資料夾名稱。例如,`touch readme.md` 創建一個名為 `readme.md` 的新的 Markdown 檔案。 也許你的新檔案不應該命名為 `readme.md`,而應該是 `readthis.md`。幸運的是,`mv` 指令允許你移動(或重新命名)檔案。它接受舊檔案名稱和新檔案名稱。 @@ -25,8 +31,12 @@ Bash 代表 Bourne Again SHell,可以說是在類 Unix 環境中你最常遇 `cp` 指令可用來將檔案或目錄複製到新位置。與 `mv` 指令不同,`cp` 指令不會移除原始檔案-而且若要複製目錄,你需要傳入 `-r` 旗標。 +## 在主控台輸出文字 + `echo` 指令可以被視為 Bash 中等同於 `console.log()` 或 `print()` 函式(程式)。`echo` 接受一個用引號包住的字串引數,並將其列印到終端機。這看起來在終端機執行只是為了在終端機中取得文字似乎很愚蠢,但你其實可以將 `echo` 串鏈到控制符號。`>` 符號允許你指定一個檔案名稱來創建或覆寫該檔案,並寫入新的字串,例如 `echo "Naomi was here." > readme.md`,而 `>>` 符號則會將內容附加到該檔案。 +## 其他 Bash 指令 + 還有許多 Bash 指令可供你使用,例如 `head`、`tail`、`chown` 和 `chmod`。在本課程中涵蓋所有指令是不可能的。但你可以使用 `man` 指令來查看幾乎任何指令的手冊或說明頁。 你很可能會記住你最常使用的指令。至於其他指令,你隨時都可以查看說明頁。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e947ae3ea7d2867c3d0e1.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e947ae3ea7d2867c3d0e1.md index c839d2183a7..55cfa994dd5 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e947ae3ea7d2867c3d0e1.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687e947ae3ea7d2867c3d0e1.md @@ -21,25 +21,31 @@ dashedName: what-are-some-command-options-and-flags 這些短選項的優點是你可以將多個旗標串鏈在一起。你可以使用 `ls -ahs` 一次性使用所有單個字母,而不是 `ls --all --human-readable --size`。 -某些選項可選方案需要傳遞一個值給它們。 +有些選項期望傳入一個值。你如何傳入該值取決於該選項是必須要值還是選用接受值。 -當使用長格式選項時,通常需要使用等號。在此語法中,值會直接與選項使用等號(`=`)符號連接。以下是修改 `ls` 行為以包含或排除顏色的範例: +當短格式選項需要值時,通常會用空格分隔該值。舉例來說,以下是設定 `ls` 結果中 `width` 的短格式選項: ```bash -ls --color=never +ls -w 50 ``` -使用短格式選項時,通常會用空格分隔值。例如,以下是設定 `ls` 結果中 `width` 的長格式和短格式選項: +當長格式選項需要值時,像 `ls` 這類 GNU 工具接受值放在等號(`=`)符號之後,或用空格分隔。這兩個指令都設定相同的寬度: ```bash -ls -w 50 +ls --width=50 ``` ```bash -ls --width=50 +ls --width 50 +``` + +有些長格式選項只選用接受值。對這些選項,值必須用等號(`=`)符號附加在選項後面。舉例來說,`ls` 的 `--color` 選項可以單獨使用,或帶有包含或排除顏色的值: + +```bash +ls --color=never ``` -請注意簡短形式使用 `-w 50`,而完整形式使用 `--width=50`。了解這個區別很重要,以避免將選項值誤傳為位置引數。 +如果你寫成 `ls --color never`,`ls` 會把 `never` 當作位置引數,也就是要列出的檔案名稱,而不是 `--color` 的值。這個區別很重要,避免誤把選項值當成位置引數傳入。 但如果你不確定,請記得你通常可以使用 `--help` 旗標來查看選項的預期語法! @@ -119,7 +125,7 @@ ls --width=50 ## --text-- -當使用需要值的長格式選項時,通常使用什麼語法? +當長格式選項只選用接受值時,像 `ls` 的 `--color`,你應該用什麼語法來傳入值? ## --answers-- @@ -127,7 +133,7 @@ ls --width=50 ### --feedback-- -請記住使用長格式選項設定 `width` 的範例。 +記住 `ls --color never` 中值會發生什麼事。 --- @@ -139,7 +145,7 @@ ls --width=50 ### --feedback-- -請記住使用長格式選項設定 `width` 的範例。 +記住關閉顏色的 `--color` 選項範例。 --- @@ -147,7 +153,7 @@ ls --width=50 ### --feedback-- -請記住使用長格式選項設定 `width` 的範例。 +記住關閉顏色的 `--color` 選項範例。 ## --video-solution-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687f0a1d5b7c4f21a9d8e123.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687f0a1d5b7c4f21a9d8e123.md index 462735b66cb..4aa74692cc2 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687f0a1d5b7c4f21a9d8e123.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-command-line-and-working-with-bash/687f0a1d5b7c4f21a9d8e123.md @@ -7,12 +7,16 @@ dashedName: how-do-you-configure-your-system-language-for-bash-and-postgresql-wo # --description-- +## 為什麼你的鍵盤配置很重要? + 讓我們來了解你的系統語言和鍵盤設定如何影響 Bash 和 PostgreSQL 工作坊。 許多程式設計工具期望命令使用標準英文鍵盤字元。在 Bash 和 PostgreSQL 工作坊中,這對於分號(`;`)、引號、斜線和其他特殊字元尤其重要。 如果你的作業系統或鍵盤配置使用非英文語言設定,有些字元可能會與預期不同,這可能導致輸入 SQL 命令或終端機命令時出現令人困惑的錯誤。 +## 切換到美式鍵盤配置 + 為了在進行這些工作坊時獲得最佳體驗,建議在完成課程期間暫時切換到英文(美國)鍵盤配置。當 Bash 或 PostgreSQL 的命令在輸入像 `;` 或 `\` 這類符號時產生意外字元或語法錯誤,這尤其有幫助。 GitHub Codespaces 使用你本地的鍵盤配置,因此在你自己的電腦上更改配置也會影響 Codespaces 中的輸入。 @@ -48,6 +52,8 @@ setxkbmap -query setxkbmap us ``` +## 測試你的鍵盤配置 + 切換配置後,在文字框或終端機中測試以下字元: ```md @@ -58,7 +64,9 @@ setxkbmap us 某些非英文配置將像 `'` 和 `"` 這類字元視為死鍵,意即它們會等待後續按鍵而非立即輸入。切換到 US 配置後,這些字元應該會立即輸入。如果字元仍無法立即出現,表示你的配置尚未完全切換。 -如果你使用非美式實體鍵盤配置,例如 AZERTY、QWERTZ 或區域性 QWERTY 變體,符號鍵可能位於不同的實體位置。在這種情況下,切換到 US 配置後,請使用作業系統的螢幕鍵盤或鍵盤檢視器來尋找像 `;`、`/`、`\`、`|`、`'` 和 `"` 這些鍵。 +## 使用非美式實體鍵盤 + +如果你使用非美式實體鍵盤配置,例如 AZERTY、QWERTZ 或區域性 QWERTY 變體,符號鍵可能位於不同的實體位置。這種情況下,切換到美式配置後,請使用你的作業系統的螢幕鍵盤或鍵盤檢視器來找到像是 ;、/、\\、|、' 和 " 這些鍵。 使用英文(美國)鍵盤配置有助於確保 Bash 和 PostgreSQL 命令在整個工作坊中完全符合預期行為。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67d2ff1996e4ae9e67170502.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67d2ff1996e4ae9e67170502.md index e5d329a9384..ba34e508340 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67d2ff1996e4ae9e67170502.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67d2ff1996e4ae9e67170502.md @@ -9,6 +9,8 @@ dashedName: what-is-unit-testing 當你設計你的應用程式時,你經常會有一系列負責單一任務的小函式(程式)。這被稱為「單一職責原則」。當你有一系列小函式時,最好測試這些函式以確保一切如預期運作。在本課程中,我們將探討如何使用流行的 Jest 測試框架來創建單元測試。 +## 要測試的函式 + 在此範例中,我們將創建一個負責傳回新格式化字串的函式(程式): ```js @@ -20,6 +22,8 @@ export function getFormattedWord(str) { 這個 `getFormattedWord` 函式有一個名為 `str` 的參數,並且會先檢查 `str` 是否為空。如果是,則傳回一個空字串。否則,會傳回一個新的字串,其中第一個字母已大寫。我們正在匯出這個函式,以便在測試檔案中使用它。 +## 撰寫你的第一個測試 + 在一個獨立的 `getFormattedWord.test.js` 檔案中,我們可以撰寫一些測試來驗證該函式是否如預期般運作。 在 `getFormattedWord.test.js` 檔案的頂部,我們需要先這樣匯入函式(程式): @@ -38,6 +42,8 @@ test('capitalizes the first letter of a word', () => { `expect` 函式用來測試一個值。它會與一個 matcher 結合,matcher 是一個函式,用來檢查該值是否如預期般運作。在這個例子中,matcher 是 `toBe()`。Jest 有各種 matcher 幫助你測試真值、字串、數字等等。 +## 執行你的測試 + 執行測試的一種方法是為你的 `package.json` 檔案添加 npm 腳本。以下是 Jest 框架的範例腳本: ```js @@ -59,6 +65,8 @@ Time: 0.103 s, estimated 1 s Ran all test suites. ``` +## 失敗測試的樣子 + 要查看失敗測試的樣子,我們可以故意將函式更新為以下內容來破壞測試: ```js @@ -97,6 +105,8 @@ Time: 0.121 s, estimated 1 s Ran all test suites. ``` +## 新增另一個測試 + 現在我們可以將我們的函式(程式)更新回原本的內容: ```js @@ -116,6 +126,8 @@ test("returns an empty string when no argument is provided", () => { 你可以添加其他測試來使事情更強固,但這前幾個測試是單元測試的良好入門。 +## 常見的測試框架 + 在測試 JavaScript 應用程式時,一些常見的測試框架包括 Jest、Mocha 和 Vitest。 單元測試很重要,因為它能幫助你在你的程式中捕捉更多錯誤,並確保一切如預期般運作。它也可以作為你的應用程式的一種文件形式,因為它旨在表述你的程式的預期行為。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67db30fedfa0b22a1a2a570c.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67db30fedfa0b22a1a2a570c.md index c510ed80a5f..79b146acb5e 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67db30fedfa0b22a1a2a570c.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67db30fedfa0b22a1a2a570c.md @@ -27,18 +27,32 @@ dashedName: what-is-the-software-development-life-cycle-and-how-does-it-relate-t 讓我們更詳細地仔細看看所有那些階段。 +## 規劃階段 + 在規劃階段,開發團隊會從利害關係人收集對擬議工作的需求。利害關係人是對產品或服務的成功有既得利益的人。利害關係人的範例可能是投資者、擁有者,甚至是其他員工。規劃階段還包括估算工作的成本以及建立工作的完成排程。 +## 設計階段 + 下一個階段是設計階段。在此階段,軟體團隊會拆解需求並決定最佳的解決方案方法。這包括決定可以使用哪些外部工具來協助進行,以及需要建立哪些內部工具來完成工作。 +## 實作階段 + 在設計階段之後,你有實作階段。這涉及軟體團隊將需求拆解成可管理的任務,然後彼此分配並建置完成。 +## 測試階段 + 一旦實作階段完成,軟體團隊便進入測試階段。這包括對新工作進行手動和自動測試。有時團隊會在整個開發階段中測試應用程式,以便發現並修正任何出現的問題。 +## 部署階段 + 下一個階段是部署階段。這是團隊將新變更部署到建置或測試環境的地方。這讓團隊能夠進一步測試應用程式並在變更進入生產環境之前修正任何問題。生產環境中的應用程式是終端用戶將會使用的應用程式。 +## 維護階段 + 最後階段是維護階段。這包括修正生產應用程式中客戶反映的任何問題。這也包括監控系統,以尋找軟體可能的改進。 +## 瀑布模型與敏捷模型 + 最後,業界中使用不同的軟體開發生命週期模型,例如 Waterfall 和 Agile。Waterfall 模型要求生命週期的每個階段必須在下一階段開始之前完成。相反地,Agile 模型則專注於透過將工作拆分為衝刺來進行反覆的開發,使團隊能夠快速進行變更並隨時間交付工作。 透過軟體開發生命週期,開發團隊和利害關係人可以在需求、成本估算和排程方面達成共識。這使得整體的協作和通訊更加高效。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67db31349f3ace2c5c803c33.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67db31349f3ace2c5c803c33.md index 397e0432679..e8a5fa6dcdd 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67db31349f3ace2c5c803c33.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-different-types-of-testing/67db31349f3ace2c5c803c33.md @@ -9,6 +9,8 @@ dashedName: what-are-bdd-and-tdd 在軟體開發中,你應該了解兩種測試方法。這些方法是 TDD(Test-Driven Development)和 BDD(Behavior-Driven Development)。 +## 測試驅動開發(TDD) + 讓我們先來看看 TDD。測試驅動開發是一種強調先撰寫測試,再建置應用程式特性的開發方法。 以下是 TDD 的典型處理程序: @@ -29,8 +31,12 @@ dashedName: what-are-bdd-and-tdd 雖然有些軟體團隊會選擇遵循 TDD 方法,但 TDD 在業界是一個具爭議性的話題。你會發現有許多文章和影片同時支持和反對 TDD。不論你對這種方法的看法如何,了解它仍然很重要,因為你可能會在實際情境中遇到它。 +## 行為驅動開發(BDD) + 第二種我們將探討的測試方法是行為驅動開發(BDD)。行為驅動開發是一種將一系列測試與商務目標對齊的方法。這些測試應該以技術人員和非技術人員都能理解的語言撰寫。 +### Gherkin 語言 + 在測試軟體應用程式中的特定行為時,BDD 通常使用 Gherkin 語言,該語言用於商務中描述行為和情境。Gherkin 語言在描述情境時使用 Given、When 和 Then 述語。 以下是一個範例: @@ -43,12 +49,16 @@ dashedName: what-are-bdd-and-tdd **然後** 部落格文章應該被存檔並以正確的標題、內容和時間戳記顯示在首頁。 +### 撰寫 BDD 場景 + 你首先要定義一個情境。範例情境包括使用者登入應用程式或在網站上下訂單。在此範例中,情境是使用者在網站上建立新的部落格文章。 在定義情境後,你應該從 Given 述語開始。這提供使用者在執行動作前的背景關係。When 述語用來表述使用者所採取的動作。 最後,Then 述語用來表述使用者先前採取動作所期望的結果。當你定義完所有情境後,你可以為每個情境撰寫測試。 +### 測試框架 + BDD 測試框架的範例包括 Cucumber、JBehave 和 SpecFlow。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-http-request-response-model/68dd97fbd18ede5ae983e342.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-http-request-response-model/68dd97fbd18ede5ae983e342.md index fd4a143ed71..a4f8ab73603 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-http-request-response-model/68dd97fbd18ede5ae983e342.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-http-request-response-model/68dd97fbd18ede5ae983e342.md @@ -33,11 +33,11 @@ HTTP 回應傳回的資產包括基於文字的資產、多媒體資產、字型 以下是這些常見資產及其內容型別的表格: -| Asset Type | Content-Type Header | +| 資產類型 | Content-Type 標頭 | | --- | --- | | HTML | text/html | | CSS | text/css | -| JavaScript | application/javascript | +| JavaScript | text/javascript | | JPEG | image/jpeg | | PNG | image/png | | GIF | image/gif | @@ -49,11 +49,11 @@ HTTP 回應傳回的資產包括基於文字的資產、多媒體資產、字型 | OTF | font/otf | | MP4 | video/mp4 | | WebM | video/webm | -| Ogg (Video) | video/ogg | +| Ogg (影片) | video/ogg | | MP3 | audio/mpeg | | AAC | audio/aac | | WAV | audio/wav | -| Ogg (Audio) | audio/ogg | +| Ogg (音訊) | audio/ogg | | JSON | application/json | | XML | application/xml | | PDF | application/pdf | diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-web-standards-model/69fc757399f4066e674a5161.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-web-standards-model/69fc757399f4066e674a5161.md index 2186db215b2..fea5a2a4c95 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-web-standards-model/69fc757399f4066e674a5161.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-the-web-standards-model/69fc757399f4066e674a5161.md @@ -7,29 +7,37 @@ dashedName: what-does-the-lifecycle-of-web-standards-features-look-like # --description-- +## 什麼是特性生命週期? + 在上一課,我們探討了建立網頁標準的流程:提案如何撰寫、審查,並最終定案。 網頁標準特性的生命週期相關,但更細緻。它追蹤一個特性從有人發現問題開始,一直到它在所有主要瀏覽器中發布(甚至最後可能被淘汰)。 把這個流程想成規則書,而生命週期則是你實際玩遊戲時發生的事情。 -1. ## 提案 - 每個特性都始於有人在意到一個問題並願意將其寫下。開發者、瀏覽器工程師或公司會在 GitHub 提出議題或說明,描述目前網路無法做到的事以及為何應該做到。在這個階段,想法還很模糊,問題多於答案。目標只是要確認是否有人也認同這個痛點。 +## 1. 提案 + +每個特性都始於有人在意並寫下的一個問題。開發者、瀏覽器工程師或公司會在 GitHub 提出議題或說明,描述目前網路無法做到的事以及為什麼應該做到。在這個階段,想法還很模糊,問題多於答案。目標只是想知道是否有人也認同這個痛點。 + +## 2. 孵育期 + +如果提案引起共鳴,它會進入公開討論和早期設計階段。會草擬出競爭方案、收集使用案例,社群會對這個想法進行壓力測試。許多提案會在這裡夭折,可能是因為問題太冷門,或沒有解法能滿足所有人。存活下來的提案會有更清晰的輪廓,並至少獲得部分瀏覽器廠商的興趣。 + +## 3. 規格 + +存活的提案會被寫成正式的規格。每個邊緣案例、錯誤狀況和與現有特性的互動都必須明確定義。這是好點子遇上現實的時刻。模糊的概念必須變成兩位獨立工程師都能讀懂並一模一樣實作的精確規則。 + +## 4. 互通性測試 -1. ## 孵育 - 如果提案引起共鳴,它會進入公開討論和早期設計階段。會草擬出競爭方案、收集使用案例,社群會對這個想法進行壓力測試。許多提案會在此階段夭折,可能是因為問題太過小眾,或沒有解法能滿足所有人。存活下來的提案會有更清晰的輪廓,並至少獲得部分瀏覽器廠商的關注。 +在特性被視為穩定之前,它必須在每個瀏覽器中表現一致。W3C Web Platform Tests 套件是驗證這點的主要工具。這是一套由 Chrome、Firefox、Safari 等瀏覽器共同執行的測試。若結果不一致,代表規格有歧義或有人有錯誤。這兩者都必須解決後,特性才能繼續推進。 -1. ## 規格 - 存活的提案會被寫成正式的規格。每個邊緣案例、錯誤狀況,以及與現有特性的互動都必須明確定義。這是好點子面對現實的時刻。模糊的概念必須變成兩位獨立工程師都能讀懂並完全相同實作的精確規則。 +## 5. 最終定案 -1. ## 互通性測試 - 在特性被視為穩定之前,它必須在每個瀏覽器中表現一致。W3C Web Platform Tests 套件是驗證這點的主要工具。這是一套由 Chrome、Firefox、Safari 等瀏覽器共同執行的測試集合。測試結果若有差異,代表規格不夠明確,或有人實作有錯誤。這兩者都必須解決,特性才能繼續推進。 +當多個獨立實作通過測試後,特性就會被最終定案。對 W3C 來說是推薦標準,對 TC39 是第 4 階段,對 WHATWG 是穩定的活文件標準。旗標會被移除,特性會正式推送給使用者。此時,它成為基礎網路平台的一部分,每個開發者都能永遠依賴它。 -1. ## 定案 - 一旦多個獨立實作通過測試,該特性就會被定案。對 W3C 來說是推薦標準,對 TC39 是第 4 階段,對 WHATWG 是穩定的活文件標準。旗標會被移除,特性會正式發佈給使用者。此時,它成為基礎網路平台的一部分,每個開發者都能永久依賴它。 +## 6. 棄用 -1. ## 棄用 - 並非每個標準都能隨時間保持良好。有些特性被更好的取代,有些則發現當初未察覺的安全或隱私問題。當特性需要被淘汰時,它會被正式標記為棄用,也就是仍被支援但建議開發者停止使用。最終它會從規格中移除。瀏覽器移除這些特性時非常謹慎且緩慢,因為網路的核心承諾是舊網頁能繼續運作。有些棄用特性會因向後相容義務而在瀏覽器中存在數十年。 +並非每個標準都能隨時間保持良好。有些特性被更好的取代,有些則發現當初沒有察覺的安全或隱私問題。當特性需要被淘汰時,它會被正式棄用,也就是仍然支援但標記為開發者應該停止使用。最終會從規格中移除。瀏覽器移除特性是緩慢且謹慎的,因為網路的核心承諾是舊網頁能繼續運作。有些棄用的特性會因為向後相容義務,在瀏覽器中存在數十年。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-variables-and-data-types/67fe8597975ea634042cad8f.md b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-variables-and-data-types/67fe8597975ea634042cad8f.md index 4859a3ce610..2db5230eb34 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-variables-and-data-types/67fe8597975ea634042cad8f.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-understanding-variables-and-data-types/67fe8597975ea634042cad8f.md @@ -7,6 +7,8 @@ dashedName: how-do-you-declare-variables-and-what-are-naming-conventions-to-name # --description-- +## 宣告變數 + 在 Python 中,變數就像帶有標籤的盒子,用來儲存和取用不同型別的資料。要創建變數,請先在左邊寫變數名稱,接著是指定運算子(`=`),然後在右邊寫你想儲存的值。以下是如何創建 `name` 和 `age` 變數的範例: ```python @@ -16,6 +18,8 @@ age = 25 在上述範例中,變數 `name` 儲存的值是 `'John Doe'`。這個值是一個字串,字串是一系列用來表述文字的字元。字串以單引號或雙引號書寫,例如 `'Hello'` 或 `"Hello"`。在未來的課程中,你將學習更多關於在 Python 中操作字串的方法。 +## 遵守命名規則 + 在 Python 中命名變數時,有一些重要規則你應該記住: - 變數名稱只能以字母或底線(`_`)開頭,不能以數字開頭。 @@ -31,6 +35,8 @@ age = 25 SyntaxError: invalid syntax ``` +## 遵守命名慣例 + 現在讓我們來看看 Python 中變數的一些常見命名慣例。 首先,變數名稱應該全部小寫,並用底線分隔字詞。這稱為蛇底式命名法(snake case): @@ -53,6 +59,8 @@ user_age = 30 x = 56 # What do you mean by x? ``` +## 撰寫註解 + 井字號符號(`#`)和其後的文字組成註解。註解讓你可以在程式碼中添加筆記和說明。 在 Python 中,註解以井字號符號(`#`)開始,語言會忽略該行中 `#` 符號後的所有內容: diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-what-is-css/672acc03c257524d6a5151e8.md b/curriculum/challenges/chinese-traditional/blocks/lecture-what-is-css/672acc03c257524d6a5151e8.md index 01ea7ba93a0..3af6fb2d8e8 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-what-is-css/672acc03c257524d6a5151e8.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-what-is-css/672acc03c257524d6a5151e8.md @@ -7,10 +7,14 @@ dashedName: how-do-width-and-height-work # --interactive-- +## 寬度和高度介紹 + 在 CSS 中,`width` 和 `height` 屬性用於控制網頁元素的尺寸。 這些屬性可以用不同的單位定義,例如像素(`px`)、百分比(`%`)、視窗單位(`vw`、`vh`)等。 +## `width` 和 `height` 屬性 + `width` 屬性指定元素的寬度。如果你沒有指定寬度,則預設值會設定為 `auto`。這讓瀏覽器根據元素的內容、父容器和顯示型別來決定元素的寬度。對於 `div` 元素,`width: auto` 會使其擴展以填滿父容器的整個寬度。 `height` 屬性指定元素的高度。同樣地,高度的預設值是 `auto`,這表示它會根據內部內容進行調整。 @@ -40,6 +44,8 @@ dashedName: how-do-width-and-height-work 像素是 CSS 中固定大小的測量單位,提供對尺寸的精確控制。 +## `min-width` 和 `min-height` 屬性 + `min-width` 屬性指定元素可以擁有的最小寬度。即使內部內容較小,元素也不會縮小到低於此值。 `min-height` 指定元素的最小高度。它確保元素不會比設定的值更矮。 @@ -73,6 +79,8 @@ dashedName: how-do-width-and-height-work 請記住,如果 `min-width` 或 `min-height` 大於 `width` 或 `height`,它們將會改寫較小的值。這確保元素不會變得過小,這對於維護一致且可用的設計非常重要。 +## `max-width` 和 `max-height` 屬性 + `max-width` 指定元素可以擴展到的最大寬度,即使有足夠的空間讓它更寬。 `max-height` 指定元素可以增長到的最大高度,無論內容大小為何。 @@ -104,6 +112,8 @@ dashedName: how-do-width-and-height-work 請記住,當 `max-width` 或 `max-height` 小於 `width` 或 `height` 時,它們具有優先權。這對於控制佈局中元素的最大尺寸非常重要。 +## 屬性優先 + CSS 優先使用 `min-width` 和 `min-height`,而非 `width` 和 `height`。如果值超過限制,`max-width` 和 `max-height` 會限制尺寸。 例如,如果你將 `width` 設定為 `600px` 且 `max-width` 設定為 `500px`,該元素的寬度將被限制在 `500px`。`max-width` 會改寫較寬的設定,使元素保持在指定的最大尺寸內。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-backgrounds-and-borders/672aa669960f6a596081fcad.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-backgrounds-and-borders/672aa669960f6a596081fcad.md index ea70e53b781..6a52597297b 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-backgrounds-and-borders/672aa669960f6a596081fcad.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-backgrounds-and-borders/672aa669960f6a596081fcad.md @@ -7,6 +7,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen # --interactive-- +## 背景屬性介紹 + 當在 CSS 中處理背景影像時,你有多個屬性可用來控制這些影像的顯示方式。 我們將專注的主要屬性是 `background-size`、`background-repeat`、`background-position` 和 `background-attachment`。 @@ -27,6 +29,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen 上述 CSS 為 `body` 元素設定了一個貓咪背景影像。 +## `background-size` 屬性 + 如果你想設定背景影像的大小,可以使用 `background-size` 屬性。 你可以使用 `contain` 將影像縮放到盡可能大而不裁切或拉伸。 @@ -65,6 +69,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen ::: +## `background-repeat` 屬性 + 在前面的範例中,你可能注意到背景影像會持續重複。 預設情況下,背景影像會在水平方向和垂直方向重複,以填滿整個元素。然而,你可以控制此行為。 @@ -122,6 +128,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen ::: +## `background-position` 屬性 + 要在螢幕上定位背景影像,可以使用 `background-position` 屬性。 `background-position` 屬性允許你設定背景影像在元素中的顯示位置。你可以使用關鍵字如 `top`、`bottom`、`left`、`right` 和 `center`,或是特定的像素或百分比數值。 @@ -146,6 +154,8 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen 這段 CSS 程式碼將背景影像水平置中並垂直置頂於元素。 +## `background-attachment` 屬性 + 最後,`background-attachment` 決定背景影像在頁面滾動時是隨內容一起滾動還是保持固定。 主要的值有 `scroll`(預設值),背景影像會隨內容捲動,以及 `fixed`,背景影像會固定在螢幕上的相同位置。 @@ -168,9 +178,11 @@ dashedName: how-to-work-with-background-image-size-repeat-position-and-attachmen 這段 CSS 程式碼設定背景影像在頁面捲動時保持固定位置。 +## `background` 簡寫屬性 + 如果你想將幾個屬性合併成一行,可以使用簡寫的 `background` 屬性來達成。 -這裡有一個範例: +以下是一個範例: :::interactive_editor diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-editors-and-ides/672d26269456511aa3db614d.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-editors-and-ides/672d26269456511aa3db614d.md index 44f886e218a..570ce335aa1 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-editors-and-ides/672d26269456511aa3db614d.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-editors-and-ides/672d26269456511aa3db614d.md @@ -7,8 +7,12 @@ dashedName: what-is-a-code-editor-and-ide # --description-- +## 什麼是程式碼編輯器和整合開發環境? + 你可能會以為這兩者是一樣的,但其實不完全相同。程式碼編輯器是任何允許你編輯程式碼檔案的應用程式。IDE,或稱整合開發環境,是一個完整的應用程式,讓你在編輯程式碼的同時,可以建置、執行和偵錯你的程式碼。 +## 探索熱門的整合開發環境 + 一些範例會有助於理解。 首先,讓我們來看看幾個流行的整合開發環境。Visual Studio 是微軟提供的一個整合開發環境,提供一套完整的工具,用於建置、偵錯及部署跨多個平台的應用程式。 @@ -17,6 +21,8 @@ dashedName: what-is-a-code-editor-and-ide Android Studio 是由 Google 開發的整合開發環境,專門用於建置、偵錯和測試 Android 應用程式。 +## 探索熱門的程式碼編輯器 + 這些只是一些整合開發環境的範例。現在,讓我們來看看幾個受歡迎的程式碼編輯器。 Visual Studio Code 是微軟推出的輕量級、開放原始碼程式碼編輯器,支援廣泛的程式設計語言,並透過擴充套件提供偵錯、語法凸顯標示和版本控制等功能。 @@ -27,6 +33,8 @@ Windows 使用者也可以使用 Notepad++,這是一款免費且開源的文 你可能已注意到,程式碼編輯器主要專注於檔案的文字內容,而 IDE 則提供各種工具來管理你的程式碼。 +## 探索雲端編輯器 + 這些範例都是你可以在你的電腦上執行的區域的程式,但也有你可以使用的雲端編輯器。 基於雲端的編輯器是一種線上工具,允許使用者直接透過網頁瀏覽器撰寫、編輯及管理程式碼或文字,無需在區域的電腦安裝軟體。 @@ -39,6 +47,8 @@ Replit 是一個線上平台,提供一個協作環境讓使用者能夠直接 StackBlitz 是另一個雲端編輯器。它直接在瀏覽器中執行,讓你在不需要任何區域設定的情況下建置、測試和分享網頁專案。 +## 選擇合適的編輯器 + 還有許多其他選項。有些選項,例如 Visual Studio Code,具有高度擴充性,能支援多種專案類型和程式語言。其他選項則可能專門針對少數程式語言或專案類型設計。 你使用的應用程式可能會因特定專案而異。你應該探索這些選項,以了解哪一個最適合你的需求。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-editors-and-ides/672d456f4ac35950b300e93f.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-editors-and-ides/672d456f4ac35950b300e93f.md index cfcf4888132..9a7b3d648ad 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-editors-and-ides/672d456f4ac35950b300e93f.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-editors-and-ides/672d456f4ac35950b300e93f.md @@ -7,8 +7,12 @@ dashedName: what-are-several-useful-keyboard-shortcuts-for-maximizing-productivi # --description-- +## 繼承自作業系統的快捷鍵 + 你可能已經熟悉一些基本的快捷鍵,這些快捷鍵是從你的作業系統繼承而來。像是 Ctrl + S(Windows/Linux)或 Cmd + S(macOS)用來存檔,Ctrl + C 或 Cmd + C 用來複製,還有 Ctrl + V 或 Cmd + V 用來貼上,這些在 VS Code 都適用。 +## 應用程式專屬快捷鍵 + 但有一些是應用程式專屬的,仍然可以提升你的生產力。值得注意的是,這些快捷鍵在不同作業系統上可能會有所不同。 例如,Shift + Alt + F 會對目前開啟的檔案執行你所組態的格式化工具(像是 JavaScript 專案中的 Prettier)。 @@ -21,8 +25,12 @@ dashedName: what-are-several-useful-keyboard-shortcuts-for-maximizing-productivi 還是你根本看不清楚程式碼?Ctrl + Plus(Windows/Linux)或 Cmd + Plus(macOS)會放大編輯器的縮放比例,而 Ctrl + Minus(Windows/Linux)或 Cmd + Minus(macOS)會縮小它。 +## 多行編輯快捷鍵 + VS Code 另一個有用的功能是多列編輯,讓你能一次修改多列。舉例來說,你可以用 Ctrl + Alt + Down 和 Ctrl + Alt + Up(Windows)、Shift + Alt + Down 和 Shift + Alt + Up(Linux)、或 Option + Cmd + Down 和 Option + Cmd + Up(macOS)來將游標延伸到連續的列。你也可以按住 Alt(Windows/Linux)或 Option(macOS)並點擊,在你需要的不同列上新增游標。游標放好後,你輸入或刪除的任何內容都會同時套用到所有這些位置,這在處理重複程式碼時能節省很多時間。 +## 指令調色盤與鍵盤快捷鍵參考 + 最後,如果你忘記任何這些快捷鍵,你隨時可以按 Ctrl + Shift + P(Windows/Linux)或 Cmd + Shift + P(macOS),這會開啟命令調色盤,讓你選擇你需要的任何指令。
命令列捷徑與輸入
Linux、macOS 和 PowerShell
完成建議(Tab 補全)完成建議(Tab 自動完成) TabLinux、macOS 和 PowerShell(建議來源依 shell 而異 — 例如 zsh 使用最近的指令歷史,而 PowerShell 使用可用的指令、變數和引數)Linux、macOS 和 PowerShell(建議內容取決於 shell、你正在輸入的命令,以及你的組態)
清除終端機
中斷正在執行的行程 Control + CLinux、macOS 和 PowerShell(在 PowerShell 中此組合鍵也用於複製文字,且只有在沒有選取文字時才會終止行程)Linux、macOS 和 PowerShell(在 PowerShell 中此快捷鍵也用於複製文字,且只有在沒有選取文字時才會中斷命令)
將行程移到背景暫停前景行程 Control + Z僅限 Linux 和 macOS,PowerShell 無對應功能僅限 Linux 和 macOS,PowerShell 無對應快捷鍵(使用 bg 讓它在背景繼續執行,或使用 fg 讓它回到前景)
重新執行先前的指令
diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-quality-and-execution-concepts/6732c6c72d3738614e1230a2.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-quality-and-execution-concepts/6732c6c72d3738614e1230a2.md index 782741f1398..8641943932f 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-quality-and-execution-concepts/6732c6c72d3738614e1230a2.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-quality-and-execution-concepts/6732c6c72d3738614e1230a2.md @@ -9,10 +9,14 @@ dashedName: what-are-linters-and-formatters-and-how-can-they-help-you-with-code- 在軟體開發的世界中,維護乾淨、一致且無錯誤的程式碼非常重要。這就是 linters 和 formatters 派上用場的地方。這些工具對開發者來說是必不可少的,以確保跨專案和團隊的程式碼品質與一致性。 -讓我們從 linter 開始。linter 是一種靜態程式碼分析工具,用來標示程式錯誤、漏洞、風格錯誤和可疑的構件。lint 這個詞來自一個檢查 C 語言原始碼的 Unix 工具。 +## 什麼是 Linter? + +讓我們從 linter 開始。linter 是一種靜態程式碼分析工具,用來標示程式錯誤、漏洞、風格錯誤和可疑的構件。lint 這個詞來自一個檢查 C 語言原始碼的 Unix 工具。 如今,大多數程式語言包括 JavaScript 都有對應的 linter。Linter 在多方面提供幫助。首先,它們能在執行期前捕捉潛在錯誤。例如,linter 可能會標示使用未定義的變數或函式呼叫時引數數量錯誤。它們也會強制執行程式碼標準和最佳實務。這可能包含關於縮排、分號使用或最大允許行長的規則。最後,當多位開發者共同開發同一個專案時,linter 有助於維護整個程式碼庫的一致性。 +## 使用 ESLint 進行程式碼檢查 + JavaScript 常用的程式碼檢查工具是 ESLint。以下是一個 ESLint 可能會標示的簡單範例: ```js @@ -23,9 +27,13 @@ function doSomething(x) { 在這段程式碼中,變數 `z` 未被宣告,因此 ESLint 會標記錯誤 `z` is not defined。此外,最後一個述語缺少分號,ESLint 也可能在程式碼編輯器中標記此問題。 -另一方面,格式化工具是自動將你的程式碼格式化以符合特定風格指南的工具。雖然語法檢查工具通常可以自動修正部分問題,但格式化工具是專門設計用來重寫你的程式碼以符合預定風格的。 +## 什麼是 Formatter? + +另一方面,格式化工具是自動將你的程式碼格式化以符合特定風格指南的工具。雖然語法檢查工具通常可以自動修正部分問題,但格式化工具是專門設計用來重寫你的程式碼以符合預定風格的。 -格式化工具確保整個專案或團隊的程式碼風格一致,無論個別開發者的偏好為何。它們也節省了原本用於手動格式化的時間和心力。最後,它們能透過消除關於程式碼風格的討論,使程式碼審查更高效。 +格式化工具確保整個專案或團隊的程式碼風格一致,無論個別開發者的偏好為何。它們也節省了原本用於手動格式化的時間和心力。最後,它們能透過消除關於程式碼風格的討論,使程式碼審查更高效。 + +## 使用 Prettier 格式化程式碼 JavaScript 常用的格式化工具是 Prettier。以下是 Prettier 可能格式化程式碼的範例。以下是格式化前的程式碼: @@ -45,10 +53,14 @@ function longFunction(argument1, argument2, argument3) { } ``` +## 整合 Linter 和 Formatter + Linter 和 formatter 都可以以多種方式整合到你的開發工作流程中。它們可以包含在你的建置處理程序中,或作為外掛程式添加到你的文字編輯器或 IDE 中,提供你編寫程式碼時的即時回授。一起使用 linter 和 formatter 可以大幅提升程式碼的品質和一致性。例如,你可以使用 ESLint 來捕捉潛在錯誤並強制執行特定的程式碼規範,然後使用 Prettier 來控制所有格式化任務。 許多開發團隊會將這些工具設定為專案組態的一部分,通常會搭配在允許提交程式碼之前執行 linter 和 formatter 的 pre-commit 掛鉤。這可確保儲存庫中的所有程式碼都符合團隊對品質和風格的標準。 +## 總結 + 總結來說,linters 和 formatters 是強大的工具,有助於維護程式碼品質、及早發現潛在錯誤,並確保程式碼庫的一致性。透過自動化這些程式碼審查的面向,它們讓開發者能更專注於解決問題,而非爭論程式碼風格。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-reviews-branching-deployment-and-ci-cd/688291b65db00473e1136725.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-reviews-branching-deployment-and-ci-cd/688291b65db00473e1136725.md index 59f037821ec..64120c429ec 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-reviews-branching-deployment-and-ci-cd/688291b65db00473e1136725.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-code-reviews-branching-deployment-and-ci-cd/688291b65db00473e1136725.md @@ -7,16 +7,22 @@ dashedName: what-is-ci-cd-and-how-does-ci-work-with-github-actions # --description-- +## 什麼是 CI/CD? + CI 代表持續整合,CD 代表持續交付或持續部署。這些處理程序讓你在確保變更可正常運作後,自動將變更部署到你的應用程式。 在 CI 管線中,你可能會對程式碼執行你的 linter 和測試。CI 管線通常會在 pull request 上執行,以確保所做的更動不會破壞應用程式,也會在 `main` 分支上執行,以確保它已準備好部署。 CD 管線也可能會在 pull requests 上執行,如果你設置了預覽環境,這樣你就可以即時查看變更。但你也會在你的 `main` 分支上執行它,以便在變更被接受並合併後持續部署。 +## 什麼是 GitHub Actions? + 但是這些實際上如何與 GitHub Actions 一起運作?首先,我們需要了解 GitHub Actions 究竟是什麼。GitHub Actions 提供臨時的 runner(可以想像成一台臨時的電腦),讓你能夠執行特定的指令。 動作是使用 YAML 檔案組態的。你可以有多個檔案來指定不同的動作以執行。例如,你可能有一個檔案用於你的 CI,另一個用於你的 CD。 +## GitHub Actions 設定檔範例 + 讓我們來看看一個基本的 CI 範例: ```yml @@ -61,6 +67,8 @@ jobs: run: pnpm run test ``` +## 設定檔的各個部分 + 這很多,所以我們來拆解。先看第一部分: ```yml @@ -121,10 +129,16 @@ on: 我們有一個 `Install Dependencies` 區塊,會安裝 npm 軟體包。我們的 `Lint Source Files` 區塊會執行 linter,`Verify Build` 區塊確保 TypeScript 程式碼可以編譯,而 `Run Tests` 區塊會執行單元測試。 +## GitHub Actions 的預設行為 + 關於 actions 重要的是,預設情況下,如果這些步驟中的一個失敗,剩下的步驟將會被跳過,整個執行將被標記為失敗。 +## GitHub Actions 設定檔的位置 + 你將 YAML 檔案放在哪裡才能執行這些動作?它們需要放在你的儲存庫中的 `.github/workflows` 目錄,GitHub 才能找到並使用它們。 +## 下一步 + 動作可以做很多額外的事情,我鼓勵你閱讀文件並探索像 freeCodeCamp 倉庫這類專案中現有的動作。但現在,你應該對 GitHub Actions 和 CI/CD 的基礎有相當的了解! # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-colors-in-css/672bc51370c789be459186b4.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-colors-in-css/672bc51370c789be459186b4.md index 08f2ab0fc04..4aedb85ab91 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-colors-in-css/672bc51370c789be459186b4.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-colors-in-css/672bc51370c789be459186b4.md @@ -7,9 +7,11 @@ dashedName: what-is-the-rgb-color-model # --interactive-- -在 CSS 中處理顏色時,了解 RGB 色彩模型是必須的。RGB 代表紅色、綠色和藍色——光的三原色。這三種顏色以不同強度組合,產生廣泛的顏色範圍。 +## RGB 色彩模型介紹 -RGB 色彩模型是一種加色模型,這表示顏色是透過以不同強度組合光線來創建的。 +在 CSS 中處理顏色時,了解 RGB 色彩模型是必須的。RGB 代表紅色、綠色和藍色——光的三原色。這三種顏色以不同強度組合,產生廣泛的顏色範圍。 + +RGB 色彩模型是一種加色模型,這表示顏色是透過以不同強度組合光線來創建的。 每種顏色的強度可以在 `0`(表示無光)到 `255`(表示全光)之間變化。透過混合不同層次的紅色、綠色和藍色,你可以產生螢幕上看到的任何顏色。 例如: @@ -17,6 +19,8 @@ RGB 色彩模型是一種加色模型,這表示顏色是透過以不同強度 - 白色由 `rgb(255, 255, 255)` 表現,這表示三種顏色的光強度皆為最大。 - 紅色由 `rgb(255, 0, 0)` 表述,紅色為全強度,綠色和藍色則為無強度。 +## CSS 中的 `rgb()` 函式 + 在 CSS 中,`rgb()` 函式允許你使用 RGB 色彩模型定義顏色。該函式接受三個數值,分別表述紅色、綠色和藍色光的強度。以下是基本語法: ```css @@ -44,6 +48,8 @@ p { 這段程式碼會將段落的文字顏色改為紅色,因為紅色值設定為 `255`,而綠色和藍色則設定為 `0`。 +## 使用 `rgba()` 函式控制透明度 + CSS 也提供了 `rgba()` 函式,該函式添加了第四個值 — alpha — 用來控制顏色的透明度。alpha 值的範圍是從 `0`(完全透通)到 `1`(完全不透明)。以下是使用 `rgba()` 的範例: :::interactive_editor @@ -63,6 +69,8 @@ div { 這段程式碼會將半透通的藍色背景套用到 `div` 元素,因為紅色和綠色值設定為 `0`,藍色值設定為 `255`,而 alpha 值設定為 `0.5`(50% 透明度)。 +## 為什麼要使用 RGB 色彩模型? + RGB 色彩模型對數位媒體特別有用,因為它直接對應到螢幕如何顯示顏色。顯示器和螢幕使用微小的紅色、綠色和藍色像素來產生你所看到的顏色。透過控制這些像素的強度,利用 RGB 值,你可以為你的網頁設計達成廣泛的色彩範圍。 此外,當處理動態設計時,RGB 模型是理想的選擇。例如,如果你想創建需要即時變化的動畫或色彩效果,RGB 函式的彈性允許你以程式方式修改顏色。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-flexbox/672bd658c0e190f674a5e057.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-flexbox/672bd658c0e190f674a5e057.md index 562c2d25f29..b109946579a 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-flexbox/672bd658c0e190f674a5e057.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-flexbox/672bd658c0e190f674a5e057.md @@ -586,6 +586,7 @@ div { #third-div { background-color: #4da3b2; align-self: stretch; + height: auto; } ``` diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bcc9c4a6dd6d7dd3e6357.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bcc9c4a6dd6d7dd3e6357.md index fe993da03a3..f4dfc38ad37 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bcc9c4a6dd6d7dd3e6357.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bcc9c4a6dd6d7dd3e6357.md @@ -9,27 +9,35 @@ dashedName: what-is-the-css-box-model CSS 盒模型是網頁開發的基本概念。它定義了 HTML 元素的結構和定位方式。如果你了解這個模型,你將能夠控制網站上元素的大小、間距和外觀。 -在 CSS 盒模型中,每個元素都被一個盒子包圍。這個盒子由四個部分組成:內容區域、內距、邊框和外距。 +在 CSS 盒模型中,每個元素都被一個盒子包圍。這個盒子由四個部分組成:內容區域、內距、邊框和外距。 內容區域是盒子最內層的零件。它是包含元素實際內容(例如文字或影像)的空間。 -內距是緊接在內容區域之後的區域。它是內容區域與元素邊框之間的空間。使用內距你可以在內容周圍添加空間以提升可讀性。你可以使用 `padding` 屬性為上、右、下、左內距設定不同的數值。 +![CSS 盒模型示意圖,顯示中央的橘色內容框,外圍被三層未標示的盒子邊框包圍](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-is-the-css-box-model-1.png) -這是一個使用 `padding` 簡寫屬性的範例,我們將上方內距設為十五 像素、右方內距設為五 像素、下方內距設為二 像素,以及左方內距設為八 像素: +內距是緊接在內容區域之後的區域。它是內容區域與元素邊框之間的空間。使用內距你可以在內容周圍添加空間以提升可讀性。你可以使用 `padding` 屬性為上、右、下、左內距設定不同的數值。 + +![CSS 盒模型示意圖,凸顯橘色內容區域包裹在藍色內距區域內,外圍被兩層未標示的盒子邊界包圍。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-is-the-css-box-model-2.png) + +這是一個使用 `padding` 簡寫屬性的範例,我們將上方內距設為十五 像素、右方內距設為五 像素、下方內距設為二 像素,以及左方內距設為八 像素: ```css padding: 15px 5px 2px 8px; ``` -邊框是 CSS 盒模型中元素的外緣或輪廓。它是元素的視覺邊界。你可以使用 `border` 屬性自訂邊框的樣式、寬度、顏色及其他屬性。以下是一個範例,我們將邊框設定為寬度為 5 像素、樣式為實線、顏色為藍色: +邊框是 CSS 盒模型中元素的外緣或輪廓。它是元素的視覺邊界。你可以使用 `border` 屬性自訂邊框的樣式、寬度、顏色和其他屬性。 + +![CSS 盒模型示意圖,凸顯橘色內容區域、藍色內距區域和深藍色邊框區域,外圍被一層未標示的盒子邊界包圍](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-is-the-css-box-model-3.png) + +這是一個範例,我們將邊框設定為寬度 5 像素、樣式為實線、顏色為藍色: ```css border: 5px solid blue; ``` -如果你省略值,將會使用該值的預設屬性。寬度的預設值是 `medium`,樣式的預設值是 `none`,顏色的預設值是目前的顏色。 +如果你省略值,將會使用該值的預設屬性。寬度的預設值是 `medium`,樣式的預設值是 `none`,顏色的預設值是目前的顏色。 -如果你想讓所有邊都完全相同,可以直接在簡寫的 `border` 屬性中設定這三個屬性。但如果你想為每個邊指定不同的樣式,可以使用 `border-width`、`border-style` 和 `border-color` 屬性。 +如果你想讓所有邊都完全相同,可以直接在簡寫的 `border` 屬性中設定這三個屬性。但如果你想為每個邊指定不同的樣式,可以使用 `border-width`、`border-style` 和 `border-color` 屬性。 ```css border-width: 2px 4px 7px 12px; @@ -39,9 +47,11 @@ border-color: blue red green black; 你可以為這些屬性中的每一個寫入最多 4 個值。它們將從上方開始,依順時針方向依序套用。如果你只寫入一個值,該值將套用到所有四個邊。 -最後,margin 是元素邊框外的空間。它決定元素與周圍其他元素之間的距離。你可以使用 `margin` 屬性為元素的上、右、下和左側設定不同的 margin 值。 +最後,margin 是元素邊框外的空間。它決定元素與周圍其他元素之間的距離。你可以使用 `margin` 屬性為元素的上、右、下和左側設定不同的 margin 值。 + +![CSS 盒模型示意圖,包含四個巢狀區域。由內而外依序為:橘色內容區域、藍色內距區域、深藍色邊框區域和灰色外距區域](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-is-the-css-box-model-4.png) -所以在這個範例中,上邊距是三 像素,右邊距是十二 像素,下邊距是九 像素,左邊距是七 像素: +所以在這個範例中,上邊距是三 像素,右邊距是十二 像素,下邊距是九 像素,左邊距是七 像素: ```css margin: 3px 12px 9px 7px; @@ -49,7 +59,7 @@ margin: 3px 12px 9px 7px; 這四個組件是計算元素總寬度和高度的必要條件。 -在接下來的幾堂課中,你將學習更多關於瀏覽器如何控制代碼以及你如何自訂它。CSS 盒模型是網頁開發的基本概念。 +在接下來的幾堂課中,你將學習更多關於瀏覽器如何控制代碼以及你如何自訂它。CSS 盒模型是網頁開發的基本概念。 了解這些組件如何互動並影響元素的尺寸,對於實作網頁設計至關重要。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bccebe1fc82d911c3f078.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bccebe1fc82d911c3f078.md index ef3caf3ab33..4b20b69afe6 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bccebe1fc82d911c3f078.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-css-transforms-overflow-and-filters/672bccebe1fc82d911c3f078.md @@ -9,6 +9,8 @@ dashedName: what-is-the-css-filter-property CSS 的 `filter` 屬性是一個強大的工具,允許你對網頁上的元素套用圖形效果。它特別適用於調整影像、背景,甚至文字的視覺呈現,而不會修改原始資產。 +## `filter` 語法 + `filter` 屬性可用於創建各種效果,例如模糊、色彩偏移和對比度調整。讓我們討論 `filter` 屬性如何運作並探索一些常見範例。filter 屬性的基本語法很簡單: ```css @@ -19,6 +21,8 @@ selector { 在這裡,`function` 表述你想要套用的特定濾鏡效果,而 `amount` 通常是決定效果強度的數值。現在讓我們來看看一些常見的濾鏡函式(程式)及其用途。 +## `blur` 函式 + :::interactive_editor ```html @@ -34,9 +38,11 @@ img { ::: -`blur` 函式會對元素套用高斯模糊,模糊的程度以像素為單位,並表述模糊的半徑。這條 CSS 規則會對頁面上的所有影像套用 2 像素的模糊。`blur` 效果可用於為你的設計創造深度或遮蔽影像的零件。 +`blur` 函式會對元素套用高斯模糊,模糊的程度以像素為單位,並表述模糊的半徑。這條 CSS 規則會對頁面上的所有影像套用 2 像素的模糊。`blur` 效果可用於為你的設計創造深度或遮蔽影像的零件。 -`brightness` 函式(程式)調整元素的亮度。值為 `0%` 時,元素將完全變黑,而超過 `100%` 的值會增加亮度。 +## `brightness` 函式 + +`brightness` 函式(程式)調整元素的亮度。值為 `0%` 時,元素將完全變黑,而超過 `100%` 的值會增加亮度。 :::interactive_editor @@ -55,6 +61,8 @@ img { 這條 CSS 規則將影像元素的亮度提高 `50%`。亮度調整可用於讓影像更突出或產生洗淡效果。 +## `grayscale` 函式 + `grayscale` 函式將元素轉換為灰階。數值以百分比定義,其中 `100%` 表示完全灰階,`0%` 則保持影像不變。 :::interactive_editor @@ -74,7 +82,9 @@ img { 此規則將把影像元素轉換為全灰階。`grayscale` 可用於創建復古風格或弱化頁面上的某些元素。 -`sepia` 函式(程式)會將元素套用棕褐色調。像灰階一樣,它使用百分比數值: +## `sepia` 函式 + +`sepia` 函式(程式)會將元素套用棕褐色調。像灰階一樣,它使用百分比數值: :::interactive_editor @@ -93,7 +103,9 @@ img { 此規則對影像元素套用 `80%` 的褐色調效果。褐色調效果非常適合營造復古或懷舊風格。 -`hue-rotate` 函式(程式)對元素套用色相旋轉。該數值以度數定義,並表述繞色彩圓的旋轉。 +## `hue-rotate` 函式 + +`hue-rotate` 函式(程式)對元素套用色相旋轉。該數值以度數定義,並表述繞色彩圓的旋轉。 :::interactive_editor @@ -112,7 +124,9 @@ img { 此規則將影像元素的色相旋轉 `90` 度。色相旋轉可用於創建迷幻效果或調整影像的整體色彩結構綱目。 -`filter` 屬性最強大的功能之一是能夠結合多個效果。你可以透過空格分隔,將多個濾鏡套用到同一個元素: +## 結合多重濾鏡 + +`filter` 屬性最強大的功能之一是能夠結合多個效果。你可以透過空格分隔,將多個濾鏡套用到同一個元素: :::interactive_editor @@ -131,7 +145,7 @@ img { 此規則對 image 元素套用增加的對比度、略微增加的亮度以及細微的棕褐色效果。 -透過組合濾鏡,你可以創建符合你設計需求的複雜且獨特的視覺效果。CSS filter 屬性是一個多功能工具,允許對網頁元素進行創意的視覺操作。 +透過組合濾鏡,你可以創建符合你設計需求的複雜且獨特的視覺效果。CSS filter 屬性是一個多功能工具,允許對網頁元素進行創意的視覺操作。 雖然我們已涵蓋一些最常見的濾鏡函式,但還有其他可用的,例如 `contrast`、`invert` 和 `saturate`。如同任何強大的功能一樣,謹慎使用濾鏡以增強你的設計,而不會讓你的使用者感到負擔或影響存取性,是非常重要的。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d1a99d10fd509c88faf3bf.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d1a99d10fd509c88faf3bf.md index 93464661101..e63f8c2ae14 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d1a99d10fd509c88faf3bf.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d1a99d10fd509c88faf3bf.md @@ -11,10 +11,14 @@ React 應用程式經常依賴外部 API 和資料庫來取得動態內容。要 讓我們來看看在 React 中資料擷取的運作方式以及你可用來擷取資料的不同選項。 +## 資料擷取選項 + React 對於你如何取得你的資料沒有特定看法,這表示在基本層次上,你可以使用所有現代瀏覽器都支援的內建 Fetch API。 你也可以使用 Axios 和 SWR。Axios 是基於 Promise 的 HTTP 請求函式庫,建立於 XMLHttpRequest 物件之上,而 SWR 是由 Vercel 團隊創建的用於資料擷取的 React 掛鉤。 +## 使用 Fetch API 進行資料擷取 + 讓我們從一個範例開始。你首先需要匯入 `useState` 和 `useEffect` 掛鉤: ```js @@ -31,6 +35,8 @@ const [error, setError] = useState(null); `loading` 變數將追蹤資料是否仍在被擷取。`data` 變數表述資料本身,而 `error` 變數將捕捉在資料擷取過程中可能發生的任何錯誤。 +### 在 `useEffect` 中擷取資料 + 由於資料擷取是副作用,最好在 `useEffect` 掛鉤內使用 Fetch API。 這裡有一個範例: @@ -50,7 +56,9 @@ useEffect(() => { }, []); ``` -這個 `useEffect` 使用 Fetch API 取得資料並設定所有狀態。  +這個 `useEffect` 使用 Fetch API 取得資料並設定所有狀態。 + +### 使用 `async`/`await` 你可以透過使用 `async`/`await` 取代 `.then()` 語法來讓事情變得更好。這表示你必須在 `useEffect` 裡面有一個獨立的函式,因為你不能在 `useEffect` 前置 `async` 關鍵字: @@ -77,6 +85,8 @@ useEffect(() => { }, []); ``` +### 完整組件 + 你接著就可以使用所有那些狀態來呈現來自 API 的資料。 以下是完整的程式碼: @@ -132,6 +142,8 @@ export default FetchPosts; 在使用者介面中,當資料正在被擷取時,你會在螢幕上看到 `Loading...`,然後會根據資料擷取是否成功顯示資料或錯誤。 +## 使用 Axios 進行資料擷取 + 記得我們也談過使用 Axios 和 SWR 進行資料擷取。讓我們來看看一個使用 Axios 的範例。 你首先需要從命令列安裝 Axios,如下所示: @@ -173,6 +185,8 @@ useEffect(() => { 你可能已經注意到這個範例中沒有 `await res.json()` 這一行。那是因為 Axios 會自動解析 JSON,所以不需要那行程式碼。 +## 使用 SWR 進行資料擷取 + 最後一個範例是使用 `useSWR` 掛鉤來擷取資料。 就像使用 Axios 一樣,你需要這樣安裝 SWR: @@ -235,6 +249,8 @@ const FetchTodos = () => { export default FetchTodos; ``` +## 建立 `useFetch` 掛鉤 + 正如你在先前關於訂製掛鉤的課程中學到的,資料擷取是一種你可以抽取到訂製掛鉤中的邏輯。因此,如果你在多個組件和頁面中擷取資料,最好創建一個 `useFetch` 掛鉤。 這是一個使用 SWR 進行資料擷取的 `useFetch` 掛鉤: diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d2f4ddb4a4306fdf5bbaee.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d2f4ddb4a4306fdf5bbaee.md index 882e67cff8b..ca0990fb14c 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d2f4ddb4a4306fdf5bbaee.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-fetching-and-memoization-in-react/67d2f4ddb4a4306fdf5bbaee.md @@ -15,6 +15,8 @@ dashedName: what-is-memoization-and-how-does-the-usememo-hook-work React 使用一種稱為記憶化的處理程序來解決這個問題,這種技術會將值和函式快取起來,以防止不必要的重新計算,讓你的應用程式更快且更具回應性。 +## 什麼是記憶化? + 根據定義,記憶化是一種優化技術,透過根據特定引數快取(記住)昂貴函式呼叫的結果。當再次提供相同引數時,會傳回快取的結果,而非重新計算函式。 備忘錄化的處理程序以此方式進行: @@ -27,7 +29,9 @@ React 使用一種稱為記憶化的處理程序來解決這個問題,這種 - 如果不存在,計算結果,將其儲存在快取中,然後傳回。 -為了提升開發者使用快取記憶的體驗,React 提供了三種工具-`React.memo`(或 `memo`)、`useMemo` 和 `useCallback`。  +## React 中的記憶化工具 + +為了提升開發者使用快取記憶的體驗,React 提供了三種工具-`React.memo`(或 `memo`)、`useMemo` 和 `useCallback`。 正如你可能猜到的,`useMemo` 和 `useCallback` 都是掛鉤,但 `React.memo` 是組件外覆,一種高階組件(HOC)。 @@ -37,6 +41,8 @@ React 使用一種稱為記憶化的處理程序來解決這個問題,這種 如果你想知道什麼是計算值和函式引用,計算值是指執行函式後的結果,而函式引用是指向函式的指標-記憶體中的函式物件。 +## `useMemo` 掛鉤語法 + 讓我們先看看如何使用 `useMemo` 掛鉤。以下是 `useMemo` 掛鉤的基本語法: ```js @@ -50,6 +56,8 @@ const memoizedValue = useMemo( 你可以看到所需的全部就是將 `useMemo` 掛鉤包裹在函式周圍。 +## 範例:`ExpensiveSquare` 組件 + 這個 `ExpensiveSquare` 組件將接收一個 `num` prop,並使用它來計算平方: ```jsx @@ -98,6 +106,8 @@ export default App; `useEffect` 中每秒執行一次的 `timer`,會讓 `calculateSquare` 函式在每次執行時都執行,即使你沒有增加 `num` 狀態變數。 +## 使用 `useMemo` 避免重複計算 + 為了解決這個問題,我們可以使用 `useMemo` 掛鉤,將函式呼叫包裹在其中,並指定 `num` 變數作為相依性: ```jsx diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-in-react/6734e3ceee2da4b0301719b7.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-in-react/6734e3ceee2da4b0301719b7.md index ea94a199c0b..c6e06bbfd60 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-in-react/6734e3ceee2da4b0301719b7.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-in-react/6734e3ceee2da4b0301719b7.md @@ -29,10 +29,14 @@ function Greeting() { } ``` -雖然這段程式碼可以正常執行並在螢幕上顯示 `Hi Jessica!` 的結果,但它並不是那麼靈活的組件。 +## 為什麼要使用 Props? + +雖然這段程式碼可以正常執行並在螢幕上顯示 `Hi Jessica!` 的結果,但它並不是那麼靈活的組件。 如果我們想顯示不同的名字,例如 Naomi、Tom 或 Oliver,該怎麼辦?這就是 React props 派上用場的地方。Props 是 properties 的縮寫,是父組件將資料傳遞給子組件的方式。Props 可以是任何型別:字串、數字、布林值、物件或陣列。 +## 傳遞 Props 給子組件 + 讓我們更新之前的範例,現在接受一個 `name` prop: ```jsx @@ -52,6 +56,8 @@ function Greeting(props) { 然後,在父層的 `App` 組件內,我們將值傳遞給 `name` 屬性,以便它可以傳遞給子層。結果在螢幕上將與之前相同,但現在我們已經創建了一個更靈活的組件。 +### 重複使用子組件 + 現在我們可以重複使用子組件多次,並且每次傳入不同的名稱: ```jsx @@ -67,6 +73,8 @@ function App() { } ``` +## 解構 Props + 你也可以選擇在 props 中使用物件解構,使其更易讀。以下是你如何重寫 `Greeting` 組件: ```jsx @@ -77,6 +85,8 @@ function Greeting({ name }) { 這段程式碼達成相同的結果,但更清楚組件預期接收哪些 props。 +## `children` Prop + React 也提供一個特殊的屬性叫做 `children`。你放在組件開啟和關閉頁籤之間的任何 JSX 都會作為 `children` 傳遞給該組件。 例如: @@ -105,7 +115,9 @@ function App() { 這個樣式經常用於組件複合,其中一個組件包裹其他 UI 元素。 -有時候,你可能需要傳遞很多屬性作為 props。與其一一傳遞,你可以先將它們轉換成物件,然後使用展開運算子(`...`)。 +## 使用展開運算子傳遞多個 Props + +有時候,你可能需要傳遞很多屬性作為 props。與其一一傳遞,你可以先將它們轉換成物件,然後使用展開運算子(`...`)。 這是一個名為 `DeveloperCard` 的新子組件範例: @@ -121,7 +133,7 @@ function DeveloperCard({ name, age, country }) { } ``` -這個 `DeveloperCard` 組件接受三個 props:`name`、`age` 和 `country`。 +這個 `DeveloperCard` 組件接受三個 props:`name`、`age` 和 `country`。 在父層的 `App` 組件中,我們可以使用展開語法將物件中的所有屬性作為獨立的 props 傳遞給子組件: diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-in-react/673500b41af8500191febedc.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-in-react/673500b41af8500191febedc.md index a79845b8f17..7a8a0aa7842 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-in-react/673500b41af8500191febedc.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-data-in-react/673500b41af8500191febedc.md @@ -9,6 +9,8 @@ dashedName: how-do-you-render-lists-in-react 在 React 網頁應用程式中,呈現列表是一項基本任務,用於向使用者顯示資料。在 React 中,`map` 方法用於將資料陣列轉換為可以在使用者介面中呈現的 JSX 元素陣列。 +## 使用 `map` 呈現列表 + 這是一個名為 `FruitList` 的組件範例,用來顯示水果列表: ```jsx @@ -24,10 +26,14 @@ function FruitList() { 在這個範例中,`map` 函式(程式)會迭代 `fruits` 陣列中的每個項目。對於每個水果,它會創建一個包含該水果名稱的新 `li` 元素。新創建的 `li` 元素陣列隨後會顯示在 `ul` 父標記內。 +## `key` 屬性 + 然而,在 React 中呈現列表時,切勿忘記為列表中的每個元素添加 `key` 屬性。key 必須始終是唯一的,它有助於 React 識別哪些項目已更改、被添加或被移除,這對於高效地呈現和更新列表至關重要。 如果你忘記了 key,React 會在主控台顯示警告,但不會丟出重大錯誤、致命錯誤。應用程式仍可能呈現並運作,但你可能會遇到細微的錯誤,特別是在列表變更時。這些錯誤可能很難偵錯,因為 UI 一開始看起來可能是正確的。 +### 使用索引作為 Key + 一個常見的錯誤是使用陣列索引作為鍵,像這樣: ```jsx @@ -36,10 +42,14 @@ function FruitList() { 雖然這樣可以消除警告,但通常被視為反樣式。使用索引作為鍵可能會在列表重新排序、排序或篩選時引發問題。React 使用鍵來追蹤元素。如果列表順序改變,React 可能會錯誤地重複使用組件狀態,或因為鍵(索引)保持不變,即使該索引的內容已更改,也無法高效地更新 DOM。 +### 使用穩定且唯一的識別符 + 最佳做法是為每個項目使用穩定且唯一的識別符。這通常是來自你的資料庫的 ID,例如 UUID 或資料庫 ID。 如果你的資料沒有唯一的 ID,你可以在資料被創建時產生一個(例如,使用 `crypto.randomUUID()` 或像 `uuid` 這樣的程式庫),或者使用保證唯一的欄位組合。然而,你應該避免在呈現時即時產生鍵(例如,`key={Math.random()}`),因為這會導致 React 在每次呈現時重新建立 DOM 元素並重置它們的狀態。 +### 為範例添加 Keys + 讓我們修改範例以包含鍵: ```jsx @@ -57,6 +67,8 @@ function FruitList() { 在這個重構的範例中,我們透過將水果名稱與其索引串接,為每個列表項目建立唯一的鍵。這確保每個列表項目都有獨特的鍵,有助於 React 高效地管理和更新列表,當項目被新增、移除或重新排序時。 +## 呈現物件列表 + React 也允許你呈現更複雜的結構。例如,你可能有一個表述使用者的物件陣列,每個物件都有多個你想要顯示的屬性: ```jsx diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac3c5d0e9fd31835ff772.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac3c5d0e9fd31835ff772.md index 9d062ea2664..23122bf4c90 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac3c5d0e9fd31835ff772.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac3c5d0e9fd31835ff772.md @@ -11,14 +11,26 @@ dashedName: how-to-create-move-and-delete-files-and-folders-using-explorer-finde 要在 Windows 使用 Explorer 創建檔案,你可以點擊左上角的「New」選項。這將顯示你可以創建的不同檔案型別的列表。 -你也可以在對應的應用程式中創建檔案。讓我們創建一個程式本文檔來向你展示這個處理程序。 +![Windows 檔案總管,左上角以橘色方框和箭頭標示「New」按鈕,freeCodeCamp 檔案資料夾中選取了「New Text Document」。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-1.png) + +你也可以在對應的應用程式中創建檔案。 + +![Windows 檔案總管顯示 Documents 裡的 freeCodeCamp 檔案資料夾,選取了「New Text Document」。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-2.png) + +讓我們創建一個文字檔來示範這個過程。 當你點擊「New」並選擇檔案型別時,你會在目前資料夾中看到一個具有預設名稱的新程式本文檔。你可以根據需要重新命名它。 +![一個文字文件圖示,檔名為 demo。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-3.png) + 建立資料夾的處理程序完全相同。點擊左上角的「New」按鈕,然後選擇「Folder」選項,或是在空白處按右鍵並前往「New」,接著選擇「Folder」選項。你會在目前位置看到一個新的空資料夾。 +![Windows 檔案總管顯示 freeCodeCamp 檔案資料夾中一個名為 New folder 的新資料夾。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-4.png) + ### 重新命名檔案和資料夾 +![Windows 檔案總管工具列,綠色方框標示「Rename」按鈕,顯示為字母 A 旁有文字游標。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-5.png) + 你可以選取檔案和資料夾,然後點擊上方的「重新命名」選項來重新命名。當檔案的現有名稱被標明時,你就可以開始輸入新的檔案名稱。按下 Enter 以確認變更。 或者,你也可以對檔案或資料夾按右鍵,選擇「重新命名」選項,或使用 F2 鍵盤快速鍵。輸入新名稱後按 Enter 以確認變更。 @@ -29,13 +41,21 @@ dashedName: how-to-create-move-and-delete-files-and-folders-using-explorer-finde 你也可以選擇該檔案或資料夾,然後在頂部選擇「剪下」選項。 +![Windows 檔案總管工具列,綠色方框標示「Cut」按鈕,圖示為剪刀。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-6.png) + 然後,前往目標資料夾,並點擊上方的「貼上」按鈕進行貼上。如果你先前複製或剪下了該檔案,這個按鈕將會被啟用。 +![Windows 檔案總管工具列,綠色方框標示「Paste」按鈕,圖示為剪貼簿。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-7.png) + 你也可以透過在空白處按右鍵,然後點擊貼上圖示來完成此操作。這將會將檔案或資料夾從其原始位置移除。 ### 刪除檔案和資料夾 -要刪除一個檔案或資料夾,請點擊它,然後點擊頂部的垃圾桶圖示。若你對它按右鍵,也會找到「刪除」選項。 +要刪除檔案或資料夾,點選它然後點擊上方的垃圾桶圖示。 + +![Windows 檔案總管工具列,綠色方框標示「Delete」按鈕,圖示為垃圾桶。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-8.png) + +如果你對檔案或資料夾按右鍵,也會看到「Delete」選項。 ## 在 macOS 上使用 Finder @@ -49,30 +69,58 @@ Finder 是 macOS 上的預設檔案管理員。 例如,要創建一個簡單的純文字程式本文檔,你可以打開 TextEdit 並存檔你的檔案。這個處理程序對任何類型的檔案都完全相同。 -有許多方法可以開啟 TextEdit。其中一種是前往 Launchpad。然後,搜尋一個你可以創建你感興趣的檔案類型的應用程式。在這個例子中,那就是「TextEdit」。點擊圖示以開啟該應用程式。 +開啟 TextEdit 有很多方法,其中一種是前往 Launchpad。 + +![macOS Launchpad 圖示,一個圓角方形,內含彩色應用程式圖塊的網格。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-9.png) + +接著搜尋你想要創建的檔案類型的應用程式。這裡是「TextEdit」。點擊圖示開啟應用程式。 + +![Launchpad 搜尋欄輸入 TextEdit,下面顯示 TextEdit 應用程式圖示。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-10.png) 一旦你進入應用程式,你應該會在 File 選單中看到一個存檔你的檔案的選項。此選單位於左上角,緊鄰 Apple 圖示旁邊。 +![TextEdit 開啟空白文件。綠色箭頭指向 macOS 功能表列,列出 TextEdit、File、Edit、Format、View、Window 和 Help。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-11.png) + 在其中一個 App 選單選項中,你應該會看到一個將檔案存檔的指令。這通常位於檔案選單下。 +![macOS 功能表列特寫,顯示蘋果標誌,接著是 TextEdit、File、Edit、Format、View、Window 和 Help。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-12.png) + 旁邊會顯示存檔的鍵盤快速鍵,macOS 通常是 Command + S。 +![TextEdit 的 File 功能表展開,標示 Save,右側顯示 Command + S 快捷鍵。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-13.png) + 當你第一次儲存檔案時,你應該會看到一個對話,在那裡你可以輸入檔案名稱並選擇位置。 通常,副檔名是由應用程式自動添加,但你可以在儲存檔案之前更改它。 -在存檔該檔案後,你可以點擊 Dock 中的 Finder 圖示來開啟 Finder。你應該會在你存檔的資料夾中看到你的新檔案。 +![TextEdit 儲存對話框,Save As 欄位顯示 Untitled.txt,有資料夾瀏覽器,底部有 Cancel 和 Save 按鈕。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-14.png) + +儲存檔案後,你可以點擊 Dock 上的 Finder 圖示來開啟 Finder。 + +![macOS Dock 中的 Finder 圖示,一個藍白相間的笑臉。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-15.png) + +你應該會在儲存檔案的資料夾中看到你的新檔案。 + +![Finder 視窗顯示 freeCodeCamp 檔案資料夾,裡面有一個檔案 demo.txt。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-16.png) ### 建立資料夾 要創建新資料夾,你應該前往你想要創建該新資料夾的位置,然後在空白處按右鍵。你會看到一個選項列表。第一個選項是「New Folder」。 +![Finder 在空白處開啟的右鍵選單,頂端標示 New Folder。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-17.png) + 如果你點擊它,就可以為你的新資料夾指定名稱。輸入名稱後按 Enter 以確認。 +![一個新的 Finder 資料夾,名為 untitled folder,名稱正被編輯中。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-18.png) + +![同一個資料夾改名為 freeCodeCamp。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-19.png) + ### 移動檔案和資料夾 在 Finder 中有多種方法可以移動檔案和資料夾。如果你需要將它們移動到列在 Finder「最愛」區段的資料夾,你只需拖放即可。 +![Finder 視窗中,demo.txt 被拖曳到 Favorites 側邊欄的 Documents,綠色箭頭指示。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-20.png) + 如果你需要將它移動到不同的資料夾,你有兩個選項。 你可以將目標資料夾以分頁方式開啟,然後將檔案或資料夾拖放到該分頁中。 @@ -83,10 +131,18 @@ Finder 是 macOS 上的預設檔案管理員。 要刪除一個檔案或資料夾,你可以對它按右鍵並選擇「移動到垃圾桶」。 +![demo.txt 的 Finder 右鍵選單,標示 Move to Trash。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-21.png) + +![freeCodeCamp 資料夾的 Finder 右鍵選單,標示 Move to Trash。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-22.png) + 你也可以將它們拖放到 Dock 上的垃圾桶圖示。這是等價的。 +![macOS Dock 中的垃圾桶圖示,裡面裝著揉皺的紙張。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-23.png) + 當檔案或資料夾在垃圾桶中時,你可以右鍵點擊它立即刪除,或者你可以清空垃圾桶以永久移除所有已刪除的檔案和資料夾。 +![Finder 垃圾桶視窗,demo.txt 的右鍵選單展開,列出 Open、Open With、Put Back、Delete Immediately 和 Empty Trash。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/how-to-create-move-and-delete-files-and-folders-using-explorer-finder-24.png) + ## 鍵盤快速鍵總結
diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac3f129efbf327742eb33.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac3f129efbf327742eb33.md index 14ab6e6a136..4a0eee0fb45 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac3f129efbf327742eb33.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac3f129efbf327742eb33.md @@ -13,10 +13,14 @@ dashedName: how-to-search-for-files-and-folders-on-your-computer 要從工作列搜尋,請輸入你正在尋找的檔案或資料夾名稱。你也可以搜尋關鍵字。你將會看到來自整個電腦和 OneDrive 的結果。 +Windows 11 taskbar with Start button, search bar, Task View, and Chrome icon + 如果你只想查看文件,可以點擊「Documents」標籤。你也有用於 apps 和 web results 的標籤。 另一個選擇是使用搜尋檔案總管。你會在檔案總管視窗的右上方找到它,那裡可以看到「搜尋文件」。 +Windows File Explorer with the Search Documents box highlighted on the top right + 你有三個選項,可定義搜尋的範圍: - 你可以從 Home 進行搜尋,以快速找到來自你的 PC 和雲端的檔案。 @@ -27,15 +31,37 @@ dashedName: how-to-search-for-files-and-folders-on-your-computer 這是你如何在 Windows 上搜尋檔案和資料夾。現在讓我們看看你如何在 macOS 上做到這一點。 -首先,你可以使用 Spotlight,這是一個幫助你在 Mac 上尋找檔案的工具。要開啟 Spotlight,請前往右上角的選單列並找到放大鏡圖示。如果你在選單列看不到此圖示,可以在控制元件中心設定中將它添加進去。 +首先,你可以使用 Spotlight,這是一個幫助你在 Mac 上尋找檔案的工具。要開啟 Spotlight,前往右上角的選單列,找到放大鏡圖示。 + +macOS menu bar featuring system icons including the magnifying glass Spotlight icon + +如果你在選單列看不到這個圖示,可以在控制中心設定中將它加入。 + +前往你的設定,篩選「控制中心」,點擊這個選項,然後向下捲動直到找到「Spotlight」選項。 + +macOS Control Center settings window showing Spotlight set to Show in Menu Bar + +你也可以使用鍵盤快速鍵開啟 Spotlight:Command + Spacebar。 -前往你的設定,篩選「控制中心」,點擊此選項,然後向下捲動直到找到「Spotlight」選項。你也可以使用鍵盤快速鍵開啟 Spotlight:Command + Spacebar。 +當你開啟 Spotlight 時,你會看到 Spotlight 搜尋列,可以透過輸入名稱來搜尋任何檔案或資料夾。 -當你開啟 Spotlight 時,你會看到 Spotlight 搜尋,在那裡你可以透過輸入名稱來搜尋任何檔案或資料夾。當你開始輸入時,你會看到依類別分組的結果,包括建議、資料夾、簡報、照片、文件和相關搜尋。 +macOS Spotlight Search bar open on screen + +當你開始輸入時,結果會依類別分組顯示,包括建議、資料夾、簡報、照片、文件和相關搜尋。 你也可以點擊「Show More」來展開特定類別。 -另一種搜尋你最近開啟過的檔案的方法是點擊 Dock 中的 Finder 圖示來開啟 Finder。然後,前往 Finder 側邊欄中的「最近使用」。在那裡,你會找到所有你最近查看過的檔案。 +macOS Spotlight Search displaying search results for freeCodeCamp + +另一種搜尋你最近開啟過檔案的方法是點擊 Dock 裡的 Finder 圖示來開啟 Finder。 + +macOS Dock featuring the blue Finder icon alongside Launchpad and Google Chrome icons + +接著,前往 Finder 側邊欄的「最近使用」。 + +macOS Finder sidebar with the Recents option highlighted under Favorites + +在那裡,你會找到所有你最近查看過的檔案。 這是你如何在 macOS 上搜尋檔案和資料夾的方法。使用這些搜尋工具,你可以最佳化你的工作流程,並且非常快速地找到你需要的檔案和資料夾。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac403a9ba7732b31c6480.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac403a9ba7732b31c6480.md index 61d4f352729..6e215a2a311 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac403a9ba7732b31c6480.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-file-systems/672ac403a9ba7732b31c6480.md @@ -63,6 +63,8 @@ WOFF 是一種現代字型格式,專為網頁開發用途設計。它代表「 它們通常以一種稱為 Markdown 的檔案格式撰寫。使用 Markdown,你可以創建具有標題、副標題、連結、圖片、列表等結構的文件。Markdown 檔案具有 `.md` 或 `.markdown` 擴充套件。 +![freeCodeCamp 的 README.md 檔案在 GitHub 上的算繪截圖,顯示標題、介紹段落,以及包含認證和貢獻等章節聯結的目錄。](https://cdn.freecodecamp.org/curriculum/lecture-transcripts/what-are-some-common-file-types-you-will-work-with-in-web-applications-1.png) + 你可以在這裡找到 freeCodeCamp GitHub 倉庫的 `README` 檔案:`https://github.com/freeCodeCamp/freeCodeCamp/blob/main/README.md` 你可以使用 Markdown 創建這個詳細的結構和格式。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-forms/672a4cd3d59756726657efb8.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-forms/672a4cd3d59756726657efb8.md index 63517e0d7e9..af289bfe8e2 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-forms/672a4cd3d59756726657efb8.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-forms/672a4cd3d59756726657efb8.md @@ -13,6 +13,8 @@ dashedName: what-are-the-different-types-of-buttons ``` +## `button` 型別 + 使用 `button` 元素的其他範例包括提交表單、顯示模態視窗,或切換側邊選單的開啟與關閉。`button` 元素有一個 `type` 屬性,用來控制按鈕被作用時的行為。`type` 屬性的第一個可能值是 `button` 型別。以下是使用 `button` 元素搭配 `button` 型別及文字為 `Show Alert` 的範例: ```html @@ -40,6 +42,8 @@ btn.addEventListener("click", () => alert("You clicked on the alert button")); ::: +## `submit` 和 `reset` 型別 + `type` 屬性的另一個可能值是 `submit` 值。以下是使用具有 `submit` 型別的 `button` 元素的範例。 :::interactive_editor @@ -73,6 +77,8 @@ btn.addEventListener("click", () => alert("You clicked on the alert button")); 在這個修改過的範例中,使用了 `label` 和 `input` 元素來收集使用者的電子郵件位址。當使用者點擊重設按鈕時,將會清除他們所有的輸入資料。重要的是要注意,重設按鈕通常不是最佳選擇,因為它們可能導致使用者不小心重設資料。此外,表單中多個按鈕可能會使使用者介面變得雜亂。 +## 使用 `input` 元素作為按鈕 + 在 HTML 中創建按鈕的另一種方式是使用 `input` 元素。`input` 元素也有一個 `type` 屬性,其可能的值包括 `submit`、`reset` 和 `button`。以下是使用 `input` 元素並將 `type` 設定為 `button` 的範例: :::interactive_editor @@ -97,6 +103,8 @@ document.addEventListener("DOMContentLoaded", () => { ::: +## `input` 與 `button`:主要差異 + `value` 屬性用於顯示按鈕文字。那麼,使用 `input` 和 `button` 元素有什麼差別呢?`input` 元素是空元素,這表示它們不能有子節點,例如文字,且只能有起始標籤。另一方面,`button` 元素提供更多彈性,因為你可以在其中嵌套文字、影像和圖示。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-forms/672a4ce6dab9eb735828b48b.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-forms/672a4ce6dab9eb735828b48b.md index 581ade1d80a..6843144d1c0 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-forms/672a4ce6dab9eb735828b48b.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-forms/672a4ce6dab9eb735828b48b.md @@ -9,12 +9,16 @@ dashedName: what-is-client-side-form-validation-in-html-forms 當使用者在你的網站上填寫表單時,重要的是他們必須以正確的格式填寫所有必要的資訊。HTML 表單控制元件,例如輸入欄位,具有許多內建的驗證功能,你可以用來檢查無效的資料。這將有助於確保使用者在資訊提交並由伺服端處理程序處理之前修正這些錯誤。 +## 客戶端與伺服端驗證 + 「client-side」一詞指的是發生在使用者的電腦或裝置上的所有事物,例如你直接互動的網站或應用程式的那部分。這包括版面配置、設計以及任何互動功能。 「server-side」一詞指的是在主機網站或應用程式的伺服器、電腦或系統上發生的所有事情。這包括處理資料、執行應用程式,以及處理來自使用者裝置的請求。 雖然客戶端驗證很重要,但你也需要伺服端驗證以增強安全性。惡意使用者可能會繞過客戶端檢查,因此強固的伺服端措施是必要的。你將在後續的模組中學習更多相關內容。現在,讓我們來看看一些客戶端表單驗證的範例。 +## `required` 屬性 + 一個常見的內建表單驗證範例是使用輸入欄位中的 `required` 屬性。`required` 屬性指定使用者必須填寫該部分的表單,才能提交。以下是使用 `required` 屬性於電子郵件輸入欄位的範例。 點擊 `Submit Form` 按鈕而未提供電子郵件位址,你將會看到一則訊息彈出,告訴你要填寫該欄位。 @@ -33,6 +37,8 @@ dashedName: what-is-client-side-form-validation-in-html-forms 每個瀏覽器都會有自己的一組樣式來顯示此警示訊息。 +## 內建的電子郵件驗證 + 使用電子郵件輸入的另一個優點是電子郵件輸入具有一些基本驗證,以確保電子郵件位址格式正確。例如,如果你輸入隨機字並點擊提交,瀏覽器會顯示警告,指出缺少 `@` 符號。 在電子郵件欄位中輸入 `abc`,然後點擊提交按鈕。你應該會看到一則訊息彈出,因為這不是有效的電子郵件位址。 @@ -51,6 +57,8 @@ dashedName: what-is-client-side-form-validation-in-html-forms 重要的是要注意,瀏覽器只會對標準電子郵件位址進行基本驗證。額外的驗證層由你來添加,你將在後續的模組中學習相關內容。 +## `minlength` 和 `maxlength` 屬性 + 電子郵件輸入的其他驗證方式是使用 `minlength` 和 `maxlength` 屬性。以下是使用額外驗證的範例。 在欄位中輸入 `b@m` 並點擊提交按鈕。你會看到一則訊息彈出,因為它未達到最低要求長度。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-generics-and-type-narrowing/67d301a5f536d1a9e5df1a8c.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-generics-and-type-narrowing/67d301a5f536d1a9e5df1a8c.md index 7f03c739246..19747f71f2a 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-generics-and-type-narrowing/67d301a5f536d1a9e5df1a8c.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-generics-and-type-narrowing/67d301a5f536d1a9e5df1a8c.md @@ -9,6 +9,8 @@ dashedName: what-is-type-narrowing-and-how-does-it-work 有時你會有一個廣泛型別的值,並且你需要將它縮小到更具體的型別。 例如,也許你需要確保一個物件符合你定義的介面。或者一個字串位於特定的值列表中。 有很多方法可以達成這個目的。 +## 以真值縮小型別 + 第一種是透過真值縮小範圍。請參考我們上一課的範例: ```js @@ -39,6 +41,8 @@ console.log(email.value); 使用這種方法,如果 `email` 是 falsy,我們會發出錯誤。`null` 是 falsy 值。發出錯誤會結束此程式碼的邏輯執行,這表示當我們到達 `console.log()` 呼叫時,TypeScript 知道 `email` 不可能是 `null`。 +## 選用串鏈 + 選用串鏈也是一種型別縮小,前提是在 `email` 值為 `null` 時,該屬性的存取不會發生。 ```js @@ -46,6 +50,8 @@ const email = document.querySelector("#email"); console.log(email?.value); ``` +## 使用 `typeof` 縮小型別 + 那其他型別呢?你也可以使用 `typeof` 運算子來縮小型別。讓我們來看一個我們已經顯示可能是字串或數字的變數範例: ```js @@ -64,6 +70,8 @@ if (typeof myVal === "number") { 因為我們使用了 `typeof` 關鍵字,TypeScript 現在知道 `myVal` 必須是數字,並且我們可以安全地對它進行算術運算。 +## 使用 `instanceof` 縮小型別 + 但是更複雜的物件類型呢?如果該物件恰好來自某個類別,你其實可以使用 `instanceof` 關鍵字來縮小型別。回到我們的 `querySelector()` 範例: ```js @@ -82,6 +90,8 @@ if (email instanceof HTMLInputElement) { 這種方法看起來可能和我們之前的方法相同,但 `instanceof` 是執行期驗證-這表示,如果我們以某種方式錯誤地取得 TypeScript 型別,我們的 JavaScript 程式碼仍會確認 `email` 是一個 `input` 元素。 +## 型別轉換與型別守衛 + 接下來,讓我們看一個範例,從 API 取得 `User` 物件並嘗試列印該資訊: ```js @@ -100,6 +110,8 @@ printAge(myUser); 我們嘗試將 `myUser` 傳入函式時會得到編譯器錯誤,因為即使我們知道 API 傳回正確的物件,TypeScript 並不知道。而且 `.json()` 方法不接受泛型型別。 +### 型別轉換 + 解決此問題的「簡單」方法是轉型該型別: ```js @@ -116,6 +128,8 @@ const myUser = await request.json() as User; printAge(myUser); ``` +### 撰寫型別守衛 + 但是每當你進行型別轉換時,實際上是在削弱 TypeScript 偵測潛在錯誤的能力。所以你可以寫一個型別守衛,而不是進行型別轉換: ```js diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-html-tools/672a511bb408ec81c592eb68.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-html-tools/672a511bb408ec81c592eb68.md index 1a72f178bf7..9d080c6aaa0 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-html-tools/672a511bb408ec81c592eb68.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-html-tools/672a511bb408ec81c592eb68.md @@ -39,10 +39,14 @@ DOM 代表文件物件模型。它是一種樹狀結構,表述頁面上的元 當你在 Google Chrome 中開啟開發者工具時,你會看到多個分頁。第一個分頁稱為 `Elements` 分頁。此分頁會顯示你所在頁面的 HTML 結構。 +Chrome developer tools with the Elements tab open, showing the page's HTML structure and an anchor element whose href is https://www.freecodecamp.org/larn/. + 第二個分頁稱為 `Console` 分頁。此分頁會顯示頁面上可能發生的任何錯誤。 在連結損壞的情況下,你可以檢查主控台以查看該損壞連結的錯誤訊息。持續顯示的常見損壞連結訊息是 404 錯誤。404 錯誤顯示該頁面未找到。 +Chrome developer tools with the Console tab open, showing a 404 Not Found error for https://www.freecodecamp.org/larn, along with other related 404 errors. + 這讓我們知道問題出在錨點元素中的 URL。當你檢查 `href` 值時,你會看到有一個拼寫錯誤。 目前主控台訊息顯示 `/larn` 對應 404,但正確的 URL 應該是 `/learn`。當聯結修正後,就會如預期般運作。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e38cdf93ee5a00c79676.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e38cdf93ee5a00c79676.md index 588d686376a..04f7a089acd 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e38cdf93ee5a00c79676.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e38cdf93ee5a00c79676.md @@ -9,6 +9,8 @@ dashedName: what-are-some-common-methods-used-for-lists 在上一課中,你已經被介紹了列表資料型別,並學會了如何存取列表中的元素以及列表切片。在本課中,你將繼續學習列表以及一些相關的常用方法,例如 `append()`、`pop()` 和 `sort()`。 +## 使用 `append()` 添加元素 + 我們將首先查看的行為是 `append()` 行為。這用於將一個項目添加到列表的末尾。以下是使用 `append()` 行為將數字 `6` 添加到數字列表的範例: ```py @@ -29,6 +31,8 @@ print(numbers) # [1, 2, 3, 4, 5, [6, 8, 10]] 注意整個 `even_numbers` 列表是巢狀在 `numbers` 列表內。 +## 使用 `extend()` 添加多個元素 + 但是如果你想將 `even_numbers` 列表中所有的個別數字添加到 `numbers` 列表的末尾,則你可以使用 `extend()` 方法。 `extend()` 方法類似於 `append()` 方法,但使用 `extend()` 你可以將多個元素從一個列表添加到另一個列表。以下是將數字 `6`、`8` 和 `10` 從一個列表添加到 `numbers` 列表末尾的範例: @@ -43,6 +47,8 @@ print(numbers) # [1, 2, 3, 4, 5, 6, 8, 10] 如你所見,巢狀列表已消失,現在只剩下一個數字列表。 +## 在特定索引插入元素 + 要在列表中的特定索引插入一個元素,你可以使用 `insert()` 方法。此方法接受兩個引數:你希望插入新條款的索引以及你想插入的條款。 以下是使用 `insert()` 方法的範例: @@ -56,6 +62,8 @@ print(numbers) # [1, 2, 2.5, 3, 4, 5] 以下程式碼會在 `numbers` 列表的索引 `2` 插入數字 `2.5`。 +## 從列表中移除元素 + 如果你想從列表中移除一個元素,你可以使用 `remove()` 方法。`remove()` 方法將要移除的元素值作為引數: ```py @@ -88,6 +96,8 @@ numbers = [1, 2, 3, 4, 5] numbers.pop() # The number 5 is returned ``` +## 清空列表 + 如果你需要清空列表,則可以像這樣使用 `clear()` 方法: ```py @@ -97,6 +107,8 @@ numbers.clear() print(numbers) # [] ``` +## 對列表進行排序 + 接下來我們將查看的行為是 `sort()` 方法。此方法用於就地排序元素。以下是一個就地排序隨機數字列表的範例: ```py @@ -120,6 +132,8 @@ print(sorted_numbers) # [1, 2, 19, 35, 41, 67] `sort()` 方法和 `sorted()` 函式都接受選用的 `key` 和 `reverse` 參數。當你在未來的課程中學習元組時,會進一步了解這些選用參數。你也會在未來的課程中學習更多像 `sorted()` 這樣的內建函式。 +## 反轉列表 + 接下來我們將查看的行為是 `reverse()` 方法。此方法會就地反轉元素的列表,如下所示: ```py @@ -129,6 +143,8 @@ numbers.reverse() print(numbers) # [1, 2, 3, 4, 5, 6] ``` +## 尋找元素的索引 + 我們將要看的最後一個方法是 `index` 方法。這用於尋找元素在列表中第一次出現的位置索引。以下是使用 `index` 方法在 `programming_languages` 列表中尋找語言 `'Java'` 的範例: ```py diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e3a99ba37f09b9d0059b.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e3a99ba37f09b9d0059b.md index 1c0df20fa7d..f94ebdb6265 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e3a99ba37f09b9d0059b.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e3a99ba37f09b9d0059b.md @@ -7,6 +7,8 @@ dashedName: what-are-tuples-and-how-do-they-work # --description-- +## 什麼是 Tuple? + 元組是 Python 的一種資料型別,用於創建有序的值序列。元組可以包含像這樣混合的資料型別: ```py @@ -28,6 +30,8 @@ TypeError: 'tuple' object does not support item assignment """ ``` +## 存取 Tuple 元素 + 要存取元組中的元素,你可以使用括號表示法和索引號碼: ```py @@ -55,6 +59,8 @@ IndexError: list index out of range """ ``` +## 使用 `tuple()` 建構式 + 另一種建立 tuple 的方式是使用 `tuple()` 建構式,如下所示: ```py @@ -62,7 +68,9 @@ developer = 'Jessica' tuple(developer) # ('J', 'e', 's', 's', 'i', 'c', 'a') ``` -對於 `tuple()` 建構式,你可以傳入不同的可迭代物件,例如字串、列表甚至其他元組。 +對於 `tuple()` 建構式,你可以傳入不同的可迭代物件,例如字串、列表甚至其他元組。 + +## 檢查元素是否在 Tuple 中 要檢查一個項目是否在一個 tuple 中,你可以像這樣使用 `in` 關鍵字: @@ -73,6 +81,8 @@ programming_languages = ('Python', 'Java', 'C++', 'Rust') 'JavaScript' in programming_languages # False ``` +## 從 Tuple 解包值 + 你也可以像對列表一樣從元組中解包項目: ```py @@ -98,6 +108,8 @@ print(rest) # [34, 'Rust Developer'] 這裡,`name` 的值是 `'Alice'`,而 `rest` 是一個由數字 `34` 和字串 `'Rust Developer'` 組成的列表。 +## 切片 Tuple + 就像對列表一樣,你可以對元組使用切片運算子來擷取其中的一部分。以下是一個將項目 `'pie'` 和 `'cookies'` 擷取到一個獨立元組的範例: ```py @@ -107,6 +119,8 @@ desserts[1:3] # ('pie', 'cookies') 請記住,第一個數字表述擷取的起始索引,而第二個數字表述結束索引。但請注意,結束索引的項目不包含在擷取的元組中。 +## 從 Tuple 移除元素 + 如果你需要從 tuple 中移除一個項目,這是不可能的,因為 tuple 是不可變的。所以這個範例會產生錯誤: ```py @@ -120,6 +134,8 @@ TypeError: "tuple" object doesn't support item deletion """ ``` +## 在 Tuple 和列表之間的選擇 + 那麼,什麼時候你會使用 tuple 而不是 列表? 如果你需要一個可以新增、移除和更新元素的動態群集,則你應該使用列表。如果你知道你正在處理一個固定且不可變的資料群集,則你應該使用元組。 @@ -221,7 +237,7 @@ del developer[1] ## --answers-- -第一個項目將被刪除。 +第一個項目將被刪除。 ### --feedback-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e4b003571c149bcda122.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e4b003571c149bcda122.md index 0d4d7a0b9c0..16670bc1330 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e4b003571c149bcda122.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e4b003571c149bcda122.md @@ -7,6 +7,8 @@ dashedName: what-are-the-enumerate-and-zip-functions-and-how-do-they-work # --description-- +## 追蹤 `for` 迴圈的索引 + 在之前的課程中,你學會了如何使用 `for` 迴圈,該迴圈用於重複執行一個區塊的程式碼指定次數。以下是一個使用 `for` 迴圈將 `languages` 列表中的每個語言列印到主控台的範例: ```py @@ -28,6 +30,8 @@ for language in languages: index += 1 ``` +## 使用 `enumerate()` 函式 + 雖然那樣可行,但更簡單的方法是使用 `enumerate()` 函式。`enumerate()` 函式會追蹤可迭代物件的索引並傳回一個列舉物件。 如果我們將 `languages` 列表傳遞給 `enumerate()` 函式,並使用 `list()` 函式將其傳回值轉換成列表,它看起來像這樣: @@ -79,6 +83,8 @@ Index 3 and language Russian Index 4 and language Chinese ``` +## 使用 `zip()` 函式 + 到目前為止,我們只在一個列表上進行迭代。但如果你需要平行迭代多個可迭代物件怎麼辦?你可以使用 `zip()` 函式(程式)來達成,它會將列表組合成元素的配對,並傳回一個包含元組的迭代器。 如果我們將 `developers` 和 `ids` 的列表傳遞給 `zip()` 函式,並使用 `list()` 函式將其傳回的值轉換成列表,結果如下: diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e4d62ae09d1661e4cf9b.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e4d62ae09d1661e4cf9b.md index 961205b6583..0f4a824e895 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e4d62ae09d1661e4cf9b.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/6839e4d62ae09d1661e4cf9b.md @@ -21,6 +21,8 @@ print(even_numbers) 此範例創建一個名為 `even_numbers` 的新空列表,並對介於 `0` 和 `20` 之間的數字序列進行迴圈。在迴圈內,有一個條件判斷目前的數字除以 `2` 後是否餘數為 `0`。這用來判斷該數字是否為偶數。如果條件為 `True`,則將目前的 `num` 附加到 `even_numbers` 列表的末尾。最後,我們將 `even_numbers` 列表列印到主控台。 +## 什麼是列表推導式? + 雖然這段程式碼可行,但有一種更簡潔的寫法是使用列表推導式。列表推導式允許你在一行中直接在方括號內結合迴圈和條件來創建新的列表。這使程式碼更短且通常更易讀。 這是先前使用方括號重構的範例: @@ -32,6 +34,8 @@ print(even_numbers) 在這個重構的範例中,`even_numbers` 列表是使用一行程式碼創建的。列表推導式迴圈遍歷從 `0` 到 `20` 的數字,並且只包含能被 `2` 整除的數字。這種方法更為簡潔,並且省略了額外的迴圈和條件區塊。 +## 在列表推導式中使用條件運算式 + 讓我們來看另一個範例,以便你能更好地理解 list 推導式的運作方式: ```py @@ -48,6 +52,8 @@ print(result) [(1, 'Odd'), (2, 'Even'), (3, 'Odd'), (4, 'Even'), (5, 'Odd')] ``` +## 使用 `filter()` 篩選列表 + 另一種從現有可迭代物件創建列表的方法是使用 `filter()` 函式。以下是一個只創建長度超過四個字元的字的新列表的範例: ```py @@ -62,6 +68,8 @@ print(long_words) # ['mountain', 'river', 'cloud'] `filter()` 函式用於從可迭代物件中選取符合特定條件的元素。`filter()` 函式接受一個函式和一個可迭代物件作為其引數。在此範例中,我們將 `is_long_word` 函式傳入 `filter()` 函式,以檢查目前的字數是否大於 `4`。所有字元數大於 `4` 的字都會被加入新的列表,並指定給 `long_words` 變數。 +## 使用 `map()` 轉換列表 + 除了 `filter()` 函式之外,還有一些在處理列表時很有用的函式。另一個需要注意的函式是 `map()`,它會接受一個可迭代物件並對其每個元素套用一個函式。以下是使用 `map()` 函式將攝氏溫度列表轉換為華氏溫度的範例: ```py @@ -76,6 +84,8 @@ print(fahrenheit) # [32.0, 50.0, 68.0, 86.0, 104.0] 就像 `filter()` 函式一樣,`map()` 接受一個函式和一個可迭代物件作為它的引數。`to_fahrenheit` 函式接收一個溫度並將其從攝氏轉換為華氏。 +## 使用 `sum()` 加總數值 + 我們將要看的最後一個函式是 `sum()` 函式。這個函式用來從可迭代物件(例如列表或元組)取得總和。以下是使用 `sum()` 函式的範例: ```py diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/683d6a3fe8c1060ffb1f9b78.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/683d6a3fe8c1060ffb1f9b78.md index fb1ac5eb7bc..a20d822d85f 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/683d6a3fe8c1060ffb1f9b78.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops-and-sequences/683d6a3fe8c1060ffb1f9b78.md @@ -9,6 +9,8 @@ dashedName: what-are-some-common-methods-for-tuples 在上一課中,你學會了如何使用 tuple 資料型別。在本課中,你將學習一些在操作 tuple 時會使用的常見方法。 +## `count()` 方法 + 我們將涵蓋的第一個方法是 `count()`。此方法用於判斷一個項目在 tuple 中出現了多少次。以下是一個範例,檢查字串 `Rust` 在名為 `programming_languages` 的 tuple 中出現了多少次: ```py @@ -36,6 +38,8 @@ TypeError: tuple.count() takes exactly one argument (0 given) """ ``` +## `index()` 方法 + 接下來我們將查看的行為是 `index()` 行為。此行為用於尋找特定項目在元組中的索引。以下是使用 `index()` 行為來尋找字串 `Java` 索引的範例: ```py @@ -74,6 +78,8 @@ programming_languages.index('Python', 2, 5) # 2 現在結果是索引 `2`,因為我們從索引 `2` 開始搜尋,並搜尋到但不包含索引 `5`。 +## `sorted()` 函式 + 另一個常用於元組的函式是 `sorted()` 函式。在之前的課程中,你已經學過用於列表的 `sort()` 方法。事實上,`sorted()` 函式可以用於任何可迭代物件,包括元組。 以下是使用 `sorted()` 函式(程式)建立新的數字列表的範例: @@ -106,6 +112,8 @@ print(sorted(programming_languages, reverse=True)) # ['Rust', 'Rust', 'Python', 'Python', 'Java', 'C++'] ``` +## 結論 + Tuple 是 Python 中常見的資料型別。了解如何操作它們,以及一些有用的方法和函式,將幫助你撰寫更高效的程式碼。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops/6732c05595ca7d422b9e55ff.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops/6732c05595ca7d422b9e55ff.md index e66df5c613c..80512cbfe4c 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops/6732c05595ca7d422b9e55ff.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-loops/6732c05595ca7d422b9e55ff.md @@ -7,10 +7,14 @@ dashedName: what-is-the-for-in-loop-and-when-should-you-use-it # --interactive-- +## 什麼是 `for...in` 迴圈? + 當你需要對物件的屬性進行迴圈時,`for...in` 迴圈是最佳選擇。此迴圈會迭代物件的所有可列舉屬性,包括繼承的屬性和非數字屬性。 繼承屬性是從物件的原型串鏈繼承而來的屬性。非數字屬性是指不是數字或無法轉換為數字的字串的屬性。 +## `for...in` 迴圈語法 + 以下是 `for...in` 迴圈的基本語法: ```js @@ -21,6 +25,8 @@ for (variable in object) { 範例中的變數表述正在被迴圈處理的物件的當前屬性。 +## 迴圈遍歷物件的屬性 + 讓我們來看幾個範例,這樣你就能更好地理解 `for...in` 迴圈的運作方式。 在這個第一個範例中,我們有一個 `fruit` 物件,並且我們想要對每個屬性進行迴圈,然後將值記錄到主控台。 @@ -47,6 +53,8 @@ for (const prop in fruit) { 記錄到主控台的結果將是 `apple`、`red` 和 `0.99`。 +## 迴圈遍歷巢狀物件 + 在這第二個範例中,我們有一個巢狀物件,並且我們想要對每個屬性進行迴圈,並將值記錄到主控台。 :::interactive_editor @@ -79,6 +87,8 @@ John { street: '123 Main St', city: 'Anytown', state: 'CA' } ``` +## 巢狀 `for...in` 迴圈 + 如果你想要對 `address` 物件的屬性進行迴圈,你可以在第一個 `for...in` 迴圈內巢狀另一個 for...in 迴圈。 :::interactive_editor @@ -133,6 +143,8 @@ for (const prop in person) { "CA" ``` +## 何時使用 `for...in` 迴圈 + 當你需要對物件的屬性進行迴圈時,`for...in` 迴圈非常有用。 不建議使用 `for...in` 迴圈來遍歷陣列的元素。相反地,請使用 `for...of` 迴圈或其他陣列方法,例如 `forEach`、`map`、`filter` 和 `reduce`,你將在未來的課程中學習這些方法。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-nano/688170ebc58d8d3b1ae493a2.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-nano/688170ebc58d8d3b1ae493a2.md index d7f698dbd75..27f1a0c739d 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-nano/688170ebc58d8d3b1ae493a2.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-nano/688170ebc58d8d3b1ae493a2.md @@ -7,16 +7,22 @@ dashedName: what-is-nano # --description-- +## 在終端機中編輯檔案 + 在終端機中工作時,標準文字編輯器並不總是可用,但有些程式是專門設計用來直接從終端機內編輯檔案的。 Linux 環境通常包含一個文字編輯器。Vi 或 Vim 通常是最常見的。Emacs 和 Nano 可能需要手動安裝,但幾乎每個發行版都能輕鬆取得。 Vim 的挑戰在於它有相當陡峭的學習曲線。如果你還不熟悉它,你甚至可能不知道如何關閉該應用程式!Emacs 可以說是稍微對使用者友善一些,但仍然有自己的一大本鍵盤快速鍵。 +## 什麼是 Nano? + Nano 明顯更精簡且更友善,特別是對於新手學習者。使用 Nano 可以更快速地開始並編輯一個檔案,且該應用程式甚至提供基本鍵盤快速鍵的螢幕說明。 然而,這樣的取捨是缺乏擴充性。與可以透過外掛程式擴充成完整開發環境的 Vim 或 Emacs 不同,Nano 相當簡潔。 +## 探索 Nano 介面 + 讓我們來看看 Nano 可以做什麼。要開啟一個檔案,你可以在終端機輸入 `nano `。 一旦開啟檔案,你會在螢幕頂端看到你正在執行的 Nano 版本以及你已開啟的檔案名稱。 @@ -32,6 +38,8 @@ Nano 明顯更精簡且更友善,特別是對於新手學習者。使用 Nano 以插入符號(`^`)開頭的快速鍵表示你需要按住 Ctrl 鍵並按下指定的字母。以 `M-` 開頭的快速鍵表示你需要按住「meta 鍵」,在大多數設定中應該是 Alt 鍵,然後按下該字母。 +## 儲存檔案 + 要在 Nano 中編輯檔案,你只需要知道幾個快速鍵指令。修改檔案後,你可以按 Ctrl + O 來「寫出」或存檔該檔案。輸入指令後,你會看到底部的選單變成這樣: ```bash @@ -42,6 +50,8 @@ File Name to write : 按 Enter 來存檔並回到編輯檔案,或按 Ctrl + C 取消並回到編輯檔案。 +## 離開 Nano + 在編輯器中,你可以按 Ctrl + X 離開 Nano 並回到終端機。如果你在嘗試離開時有未存檔的變更,底部選單會顯示這個: ```bash diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-node-core-modules/695cc6a5eefd305381ec90bc.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-node-core-modules/695cc6a5eefd305381ec90bc.md index b2c425ae1da..1852f215bab 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-node-core-modules/695cc6a5eefd305381ec90bc.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-node-core-modules/695cc6a5eefd305381ec90bc.md @@ -100,7 +100,7 @@ try { ## 使用 `writeFile()` 方法 -`writeFile()` 方法讓你寫入檔案。如果檔案不存在,它會在指定路徑創建該檔案。如果你提供相對路徑,檔案會相對於目前工作目錄被創建。 +`writeFile()` 方法讓你寫入檔案,會覆寫任何現有內容。如果檔案不存在,會在指定路徑創建它。如果你提供相對路徑,檔案會相對於目前工作目錄創建。 以下是如何使用 `writeFile()` 方法: @@ -265,7 +265,7 @@ Node `fs` 模組的主要用途是什麼? ## --text-- -Node fs 模組中哪個方法可以讓你將內容寫入檔案,若該檔案不存在則會建立它? +Node `fs` 模組中哪個方法讓你寫入檔案,覆寫任何現有內容,並在檔案不存在時創建它? ## --answers-- @@ -277,7 +277,7 @@ Node fs 模組中哪個方法可以讓你將內容寫入檔案,若該檔案不 ### --feedback-- -思考同時創建並寫入內容到 file 的 method。 +想想那個在寫入檔案時會覆寫任何現有內容的方法。 --- @@ -285,7 +285,7 @@ Node fs 模組中哪個方法可以讓你將內容寫入檔案,若該檔案不 ### --feedback-- -思考同時創建並寫入內容到 file 的 method。 +想想那個在寫入檔案時會覆寫任何現有內容的方法。 --- @@ -293,7 +293,7 @@ Node fs 模組中哪個方法可以讓你將內容寫入檔案,若該檔案不 ### --feedback-- -思考同時創建並寫入內容到 file 的 method。 +想想那個在寫入檔案時會覆寫任何現有內容的方法。 ## --video-solution-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-node-core-modules/695cc8f280fef0cc3bed02ca.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-node-core-modules/695cc8f280fef0cc3bed02ca.md index b73038ca6d5..e3aa35ab5d4 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-node-core-modules/695cc8f280fef0cc3bed02ca.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-node-core-modules/695cc8f280fef0cc3bed02ca.md @@ -61,7 +61,7 @@ console.log(path.extname(__filename)); // .js console.log(path.extname('text-files/text1.txt')); // .txt ``` -`join()` 方法會將你傳入的所有路徑段連接成一個乾淨且標準化的路徑。  +`join()` 方法會將你傳入的所有路徑段連接成一個乾淨且標準化的路徑。 如果你想合併不同資料夾中相關的檔案,以便一起處理,這可能會很有用: @@ -79,7 +79,7 @@ const wrongPath = path.join("/src//", "assets", "text-files"); console.log(wrongPath); // /src/assets/text-files ``` -`resolve()` 方法將一連串的路徑片段轉換成絕對路徑。它從你目前的工作目錄開始,並產生一個指向裝置上精確位置的完整路徑: +`resolve()` 方法會將一連串的路徑片段轉換成絕對路徑。它從右到左處理這些片段,直到構建出一個絕對路徑。如果到達開頭仍未構建出絕對路徑,則會使用目前的工作目錄: ```js const absolutePath = path.resolve("assets", "src", "text-files"); @@ -87,7 +87,7 @@ console.log(absolutePath); // /Users/user/Desktop/fCC/script-code/node/node-path/assets/src/text-files ``` -`join()` 和 `resolve()` 的差別在於 `join()` 會創建相對路徑,而 `resolve()` 則會傳回絕對路徑。 +與會連接並標準化路徑片段且可能傳回相對或絕對路徑的 `join()` 不同,`resolve()` 永遠傳回絕對路徑。 最後,還有 `parse()` 和 `format()` 方法。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8757080091969f07122.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8757080091969f07122.md index b059415c145..c156fca827b 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8757080091969f07122.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8757080091969f07122.md @@ -7,12 +7,18 @@ dashedName: what-is-sql-and-how-can-you-create-a-database-with-tables # --description-- +## 什麼是 SQL? + SQL 是結構化查詢語言的縮寫。它於 1970 年代開發,當時最初稱為結構化英文查詢語言(SEQUEL)。這個術語後來縮短為 SQL。 SQL 是用於在關聯式資料庫中儲存和管理資料的程式設計語言。 +## 關聯式資料庫的運作方式 + 如你在先前的課程中所學,關聯式資料庫將資料組織成表格。每個表格都有一組列和行,其中表述資料屬性及其關係。每列表現一筆記錄,而每行表現該記錄的特定屬性或欄。 +## 在關聯式資料庫中使用 SQL + 使用 SQL,你可以為你的關聯式資料庫添加、變更、刪除、尋找和擷取資料。它提供一整套用於查詢、篩選、排序和彙總資料的指令。 SQL 可以透過只查詢必要的資料來最佳化資料庫效率,並且可以輕鬆地與各種程式設計語言整合,讓你能夠直接從你的應用程式與資料庫互動。 @@ -23,6 +29,8 @@ SQL 可以透過只查詢必要的資料來最佳化資料庫效率,並且可 SQL 是基於指令,通常稱為 SQL 述語或 SQL 查詢。 +## 執行 SQL 指令 + 作為開發者,你將使用特定的 SQL 語言元素或關鍵字來撰寫這些述語。它們允許你對你的資料庫執行必要的操作。 在你可以輸入 SQL 指令之前,你需要開啟 psql shell,這樣你才能直接與 PostgreSQL 資料庫互動。在命令提示字元或終端機中,輸入: @@ -45,6 +53,8 @@ postgres=# 讓我們來看看你應該熟悉的一些最基本的 SQL 指令。你會注意到,依照慣例,SQL 指令以分號(`;`)結尾。 +## 建立並連接資料庫 + 首先,你可以使用此命令來創建名為 `my_database` 的資料庫: ```sql @@ -71,6 +81,8 @@ CREATE DATABASE my_database; my_database=# ``` +## 建立資料表 + 一旦你已經創建並連接到資料庫,你就可以使用 `CREATE TABLE` 關鍵字來創建資料表: ```sql @@ -90,6 +102,8 @@ CREATE TABLE products ( 這些是你應該知道以開始使用的幾個基本 SQL 指令。 +## SQL 的利益 + 使用 SQL,你可以輕鬆查詢、操作和分析資料,以做出明智的決策並解決現實世界的問題。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea899461e37199cf03cf9.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea899461e37199cf03cf9.md index d22e6fc4bd2..20f09069d94 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea899461e37199cf03cf9.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea899461e37199cf03cf9.md @@ -7,6 +7,8 @@ dashedName: what-are-the-basic-data-types-in-sql # --description-- +## 在 SQL 中建立資料表 + 要在 SQL 中定義資料表,你需要指定每個行的資料型別。 請記住,這是建立資料表的基本語法。每個行都有自己的資料型別。 @@ -20,6 +22,8 @@ CREATE TABLE table_name( ); ``` +## SQL 中的資料型別類別 + 作為開發者,你的目標是盡可能準確地選擇這些資料型別。 SQL 中有六種常見的資料型別類別: @@ -33,6 +37,8 @@ SQL 中有六種常見的資料型別類別: 在本課程中,我們將涵蓋一些在 PostgreSQL 中最廣泛使用的型別。資料型別會因資料庫管理系統而異,但通常相當相似。所以你需要查看文件中的完整列表。 +## 數值型別 + 我們將從數值開始。 首先,我們有 `INTEGER` 資料型別: @@ -65,6 +71,8 @@ id INT AUTO_INCREMENT 你可以看到不同的資料庫管理系統可能有不同的方法來實現你資料庫中完全相同的功能。 +## 字串資料型別 + 這些是最常用的數值資料型別,但有時你可能需要表述文字或字元序列。 為此,你有 `VARCHAR` 資料型別。此資料型別用於可變字串長度。你可以在小括弧內設定最大字元長度: @@ -81,6 +89,8 @@ name VARCHAR(50) name TEXT ``` +## 日期與時間 + 除了數字和字串之外,儲存日期和時間也是很常見的。 例如,如果你創建一個資料表來儲存事件,你可能需要以特定格式儲存每個事件的日期。為此,你有 `DATE` 資料型別: @@ -105,6 +115,8 @@ event_timestamp TIMESTAMP event_timestamp TIMESTAMP WITH TIME ZONE ``` +## `BOOLEAN` 型別 + 最後,如果你需要儲存布林值 `TRUE` 或 `FALSE`,你可以使用 `BOOLEAN` 資料型別: ```sql diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8e0cab41019dc8a728a.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8e0cab41019dc8a728a.md index 39cb0d301fb..cd8588163d2 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8e0cab41019dc8a728a.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8e0cab41019dc8a728a.md @@ -9,6 +9,8 @@ dashedName: what-are-the-different-types-of-relationships-in-a-relational-databa 正如你在之前的課程中學到的,關聯式資料庫將資料儲存在由列和行組成的表格中。 +## 主要的關聯類型 + 「關聯式資料庫」中的「關聯」部分來自於不同資料表中的記錄可以有不同型別的關係。 有五種主要的關係型別: @@ -19,18 +21,24 @@ dashedName: what-are-the-different-types-of-relationships-in-a-relational-databa - 多對多 - 以及自我取用關係(也稱為遞迴關係)。 +## 一對一關聯 + 當第一個資料表中的每個記錄最多只能與第二個資料表中的一個記錄相關,反之亦然,兩個資料表即具有**一對一**關係。 例如,假設一家公司只為每位員工指定一輛車輛。 在這種情況下,資料庫可能有一個 `employees` 表格和一個 `vehicles` 表格,其中每個員工記錄對應資料庫中唯一的一個車輛記錄。 +## 一對多與多對一關聯 + 相反地,**一對多** 關係發生在一個資料表中的一筆記錄可以與另一個資料表中的一筆或多筆記錄相關聯。 例如,如果我們有一個 `customers` 資料表和一個 `orders` 資料表,每個客戶可以關聯到一個或多個訂單,但每個訂單只能關聯到一個客戶。 這與**多對一**關係相同,但從相反的角度來看。一個或多個訂單可以關聯到一個客戶。 +## 多對多關聯 + **多對多** 關係發生在一個資料表中的記錄可以與另一個資料表中的多個記錄相關,反之亦然。 例如,讓我們分析一個圖書館的資料庫。為了簡化起見,假設這個資料庫只有兩個資料表:`books` 和 `authors`。 @@ -55,6 +63,8 @@ dashedName: what-are-the-different-types-of-relationships-in-a-relational-databa 使用連接表可以更輕鬆地查詢資料、避免重複,並簡化資料庫結構。它們對於實作多對多關係非常有幫助。 +## 自我參考關聯 + 最後,我們會發現**自我參照**關係,當一個資料表的記錄可以與同一資料表上的其他記錄相關聯時,就會發生這種情況。這也稱為遞迴關係。 理解這些關係對於設計和模式化複雜且高效的關聯式資料庫至關重要。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8eba2a8b119f2ad9f8c.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8eba2a8b119f2ad9f8c.md index 7a06c24c6cf..532e5290bf7 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8eba2a8b119f2ad9f8c.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-relational-databases/687ea8eba2a8b119f2ad9f8c.md @@ -7,8 +7,12 @@ dashedName: what-are-the-different-ways-to-join-tables # --description-- +## 為什麼 SQL 的 `JOIN` 很重要 + 即使關聯式資料庫將資料組織成獨立的表格,SQL 的 `JOIN` 操作仍允許你從表格中結合相關資訊以查詢資料。 +## `JOIN` 操作的不同變體 + `JOIN` 操作有幾種變體,包括: - `INNER JOIN` @@ -18,6 +22,8 @@ dashedName: what-are-the-different-ways-to-join-tables - `SELF JOIN` - `CROSS JOIN` +## `INNER JOIN` 操作 + 讓我們從 `INNER JOIN` 開始。 `INNER JOIN` 會篩選結果,只包含你指定的連接行中兩個資料表的值相等的列。基本上,它會給你資料的交集。 @@ -79,6 +85,8 @@ product_id | product_name | category | price | origin | sale_id | produc 連接表格正如其名。它將兩個或多個表格合併成一個,這就是為什麼我們會看到來自兩個表格的所有行,包括兩次出現的 `product_id`。 +## `FULL OUTER JOIN` 操作 + `FULL OUTER JOIN` 傳回兩個資料表中的所有列。 如果在指定的行中找到匹配,資料將會被合併,並且你會取得每個匹配記錄的所有行。 @@ -113,6 +121,8 @@ product_id | product_name | category | price | origin | sale_id | produc 但是 `'T-Shirt'` 有空的(`NULL`)行,因為在 `sales` 表中找不到匹配(此產品未售出)。 +## `LEFT OUTER JOIN` 操作 + `LEFT OUTER JOIN` 用於取得左表的所有記錄,以及左表每一列對應的右表匹配資訊。 如果找不到匹配,右側表格的行將以 `NULL` 值填充。 @@ -143,6 +153,8 @@ product_id | product_name | category | price | origin | sale_id | produc 在這種情況下,它與 `FULL OUTER JOIN` 相同,因為它包含第一個資料表 `products` 的所有列。 +## `RIGHT OUTER JOIN` 操作 + `RIGHT OUTER JOIN` 非常相似,但現在我們會取得右表的所有記錄,以及右表每一列對應的左表匹配資訊。 如果沒有匹配,左側表格的行將以 `NULL` 值填充。 @@ -176,10 +188,16 @@ product_id | product_name | category | price | origin | sale_id | produc 這些是最常用的 `JOIN` 操作,但還有另外兩種你應該知道的。 +## `SELF JOIN` 操作 + `SELF JOIN` 允許你將資料表與其自身連接。你可以將它視為連接同一資料表的兩個副本。這對於比較同一資料表中的不同列非常有幫助。 +## `CROSS JOIN` 操作 + `CROSS JOIN`,也稱為笛卡爾連接,會將第一個資料表的每一列與第二個資料表的每一列連接。因此,它會產生所有可能的列組合。這個操作不需要任何條件來連接資料表。 +## 為什麼要使用 `JOIN` 操作 + 這些 `JOIN` 操作是使用 SQL 的基礎。透過選擇正確的 JOIN,你可以盡可能高效地查詢你需要的資料。 # --questions-- diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-sql/68817041f57ce139bef36541.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-sql/68817041f57ce139bef36541.md index 8fed1d482ee..daebb1a5e7e 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-sql/68817041f57ce139bef36541.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-sql/68817041f57ce139bef36541.md @@ -7,12 +7,16 @@ dashedName: what-is-sql-injection-and-what-are-some-ways-to-prevent-it # --description-- +## 什麼是 SQL 注入? + SQL 注入是一種網路安全漏洞,攻擊者會更改或利用網頁應用程式對資料庫所發出的查詢。舉例來說,攻擊者可以將惡意的 SQL 程式碼插入查詢中,以在後端執行該惡意程式碼。 當你讓使用者透過登入表單、搜尋欄或 URL 參數輸入資料,然後使用該使用者輸入的字串插值或串接來產生最終的 SQL 指令時,就可能發生這種情況。 根據攻擊者的目標,惡意的 SQL 程式碼可能會對你的資料庫和網頁應用程式造成重大干擾,例如繞過身份驗證、竊取資料庫中的資料,或修改或刪除資料庫記錄。因此,你應該非常重視這項威脅。 +## 利用 SQL 注入繞過身份驗證 + 例如,假設你的網頁應用程式使用像這樣的 SQL 查詢來驗證使用者,直接嵌入使用者輸入的使用者名稱和密碼: ```sql @@ -35,6 +39,8 @@ WHERE username = " " OR TRUE 根據資料庫的實作,這可能會傳回第一個使用者或資料庫中任何使用者的資料,並允許攻擊者在沒有有效憑證的情況下登入。 +## 預防 SQL 注入 + 那麼你要如何防止這種情況?有兩種主要方法可以防止 SQL 注入: - 不要使用字串串接來撰寫動態查詢。 @@ -44,6 +50,8 @@ WHERE username = " " OR TRUE 另一個重要的技術是輸入驗證。這在所有情況下都建議作為次要的安全措施,但對於與資料表名稱、行名稱和排序順序相關的 SQL 查詢部分尤其重要。如果可能,建議直接在你的程式碼中指定資料表名稱和行名稱,而非來自使用者輸入。 +## 限制資料庫權限 + 即使採取所有預防措施後,你仍遭受 SQL 注入攻擊,也可以透過限制每個資料庫帳號的權限來將其對資料庫的影響降到最低。為每個資料庫使用者只授予其工作所需的權限,且不多給。如果一個帳號只需要從資料庫讀取資料,就只授予讀取存取權。作為預防措施,絕不要為你的應用程式帳號指定管理員權限。這樣做非常危險,因為攻擊者可能會取得完整存取權和對資料庫的完全控制。 SQL 注入是一種非常常見的攻擊,作為開發者的你應該在你的網頁應用程式的實作中注意並防範。透過這些技術,你可以保護你的資料庫並確保你的使用者資料安全。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-sql/6881705cd9860639e98d639d.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-sql/6881705cd9860639e98d639d.md index 3c3a52ef8f8..8529bfdb6df 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-sql/6881705cd9860639e98d639d.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-sql/6881705cd9860639e98d639d.md @@ -9,10 +9,14 @@ dashedName: what-is-the-n-plus-1-problem N+1 問題是資料庫驅動應用程式中常見的效率瓶頸。如果你曾經在使用應用程式時遇到非常長的載入時間,很可能與 N+1 問題有關。當為了取得你請求的資料而連續執行許多小查詢時,就會發生這個問題。 +## 為什麼要避免依序執行查詢 + 但是為什麼你會連續執行多個查詢?你可能會這麼做是為了查詢一個記錄列表以及關於那些記錄的額外資訊。你會先執行初始查詢以取得記錄列表,然後對每一筆記錄執行額外查詢,以取得關於它們的額外資訊。 即使你直覺上認為執行許多小且簡單的查詢會比執行一個大型且複雜的查詢更高效,通常情況並非如此。你執行的查詢越多,整個處理程序所需的時間就越長,因為你需要將每個查詢傳送到伺服器、在資料庫中尋找資料,然後接收伺服器針對該查詢所傳送的資料。這可能對你的應用程式造成非常顯著的效率、性能影響。 +## N+1 問題的實務範例 + 為了向你展示一個實際的範例,假設你正在開發一個外送服務的應用程式,並且你執行一個查詢以取得資料庫中前 50 筆訂單。首先,你會從 `orders` 資料表取得這些訂單的列表,如下所示: ```sql @@ -48,6 +52,8 @@ for (const order of orders) { 這種方法看起來可能簡單且直覺,但你可能會驚訝地發現這正是你不應該做的。你應該避免在迴圈中進行查詢,因為執行多次小型查詢會比執行一次較大的查詢以取得所有資料花費更多時間。 +## 減少查詢次數 + 你應該嘗試使用 SQL 提供給你的工具,以盡可能減少查詢次數。在這種情況下,我們可以使用 `JOIN` 操作來連接 `orders` 和 `customers` 資料表。 ```sql diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1a3fea729e274dc33d04d.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1a3fea729e274dc33d04d.md index 483a872d8c1..a709e259cd9 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1a3fea729e274dc33d04d.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1a3fea729e274dc33d04d.md @@ -15,6 +15,8 @@ React 提供了一種強大且一致的方式來控制代碼事件,透過其 讓我們來看看 event 在 React 中的運作方式,這樣你就可以開始在你的專案中使用它們。 +## React 事件與 HTML 事件的不同 + 在 React 中,事件處理常式的運作方式與原生的瀏覽器事件類似,但有一些調整。 React 使用駝峰式大小寫,例如 `onClick` 和 `onSubmit`,而不是使用小寫的事件屬性名稱如 `onclick` 和 `onsubmit`。 @@ -23,6 +25,8 @@ React 使用駝峰式大小寫,例如 `onClick` 和 `onSubmit`,而不是使 事件處理常式函式作為 prop 傳遞給元素,而像 `onClick` 或 `onSubmit` 這樣的事件型別則在 JSX 中用作屬性。 +## 撰寫事件處理常式 + 這裡是如何在一般 HTML 中處理 click 事件的提醒: ```html @@ -45,6 +49,8 @@ function handleClick() { 在 React 中,事件處理常式函式通常以前置式 `handle` 開頭,以顯示它們負責控制事件,例如 `handleClick` 或 `handleSubmit`。 +## 合成事件物件 + 當使用者操作觸發一個事件時,React 會將一個 Synthetic Event 物件傳遞給你的處理常式。這個物件的行為非常類似於原生的 JavaScript 事件物件,提供像是 `type`、`target` 和 `currentTarget` 等屬性。 你可以將 `event` 作為參數傳遞給處理常式函式,並將它記錄到主控台以查看其結構: @@ -55,6 +61,8 @@ function handleClick(event) { } ``` +## 防止預設行為與事件冒泡 + 為了防止像瀏覽器重新整理這類的預設行為,例如在 `onSubmit` 事件期間,你可以呼叫 `preventDefault()` 方法: ```jsx @@ -71,6 +79,8 @@ function handleSubmit(event) { 你也可以透過呼叫 `event.stopPropagation()` 來阻止事件向父元素冒泡。 +## 傳遞資料給事件處理常式 + 有時候,在控制刪除和編輯等特殊功能時,你可能想要將額外的資料傳遞給事件處理常式。你可以透過將處理常式包裝在行內箭頭函式中來做到這一點: ```jsx @@ -81,7 +91,7 @@ function handleDelete(id) { ; ``` -在 React 中使用行內事件處理常式是可以的,因為 React 高效地管理重新呈現並避免效率問題。 +在 React 中使用行內事件處理常式是可以的,因為 React 高效地管理重新呈現並避免效率問題。 在純 JavaScript 中,行內事件處理常式會在每次呈現時建立新的函式,因為沒有虛擬 DOM 來最佳化處理程序,這可能導致效率問題。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eaf77f510e15dfed7c14.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eaf77f510e15dfed7c14.md index ddcfdadb70c..4e3a24a98d0 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eaf77f510e15dfed7c14.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eaf77f510e15dfed7c14.md @@ -15,7 +15,9 @@ State 表現你 React 組件中的動態資料,例如來自使用者輸入的 每當狀態改變時,React 會重新算繪組件而不重新載入頁面,以反映這些變化在人機介面中。這種反應性使你的應用程式具有互動性。 -`useState` 掛鉤是一個讓你在函式(程式)組件中宣告狀態變數的函式。  +## `useState` 掛鉤 + +`useState` 掛鉤是一個讓你在函式(程式)組件中宣告狀態變數的函式。 在掛鉤出現之前,你只能在類別組件中使用狀態。但自從 React 16.8 引入掛鉤後,你可以透過使用 `useState` 掛鉤在函式組件中使用狀態。 @@ -31,6 +33,8 @@ import { useState } from "react"; import React from "react"; ``` +## 宣告狀態變數 + 以下是你在匯入 `useState` 時如何宣告狀態變數的方法: ```js @@ -49,10 +53,14 @@ const [stateVariable, setStateFunction] = React.useState(initialValue); - `setStateFunction`(設值函式)會更新狀態變數 - `initialValue` 設定初始狀態 +## 狀態範圍與掛鉤規則 + 請注意,React 組件中的狀態是私有的,並且隔離於每個組件實體。這表示,如果你算繪同一個組件兩次,一個組件的狀態不會影響另一個組件。這也表示,如果你想在組件之間共享狀態,則需要將狀態提升到共同的父組件,並作為 props 傳遞下去。 另一件事是掛鉤必須在組件的頂層呼叫,就在 `return` 關鍵字之前,以保持狀態和效果在各次呈現中一致。這表示你不能在迴圈、條件或巢狀函式中使用狀態。 +## 範例:計數器組件 + 以下是在 `Counter` 組件中使用 `useState` 掛鉤管理狀態的範例: ```jsx @@ -81,6 +89,8 @@ export default Counter; 在上述程式碼中,我們從 React 匯入了 `useState` 掛鉤。在 `Counter` 組件中,`count` 表現目前的狀態,而 `setCount` 是負責更新狀態的設定函式(程式)。目前的狀態值是 `0`。`return` 述語包含計數值和兩個按鈕,用於將計數減少和增加 `1`。 +## 管理多個狀態變數 + 你可以透過多次呼叫 `useState` 掛鉤來管理多個狀態。當你有不相關的狀態變數時,這點尤其重要: ```jsx diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eb6929e68117faa6717f.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eb6929e68117faa6717f.md index 9bc4c1a1cb4..63401b70fec 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eb6929e68117faa6717f.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-state-and-responding-to-events-in-react/67d1eb6929e68117faa6717f.md @@ -13,6 +13,8 @@ React 會將你所有的 JavaScript、JSX 和 CSS 程式碼整合,判斷它應 呈現處理程序包含三個階段:觸發、呈現和提交。讓我們更詳細地看看這些階段。 +## 觸發階段 + 當 React 偵測到某些東西已改變且使用者介面可能需要更新時,會發生觸發階段。這種變化通常是由於 state 或 props 的更新。 例如,注意到該是晚餐時間可以觸發你進入廚房開始烹飪。 @@ -37,6 +39,8 @@ function Counter() { export default Counter; ``` +## 呈現階段 + 一旦觸發發生,React 就會進入呈現階段。在這裡,React 會重新評估你的組件並計算要呈現的內容。 為此,React 使用「真實」DOM 的輕量複本。這稱為虛擬 DOM。透過虛擬 DOM,React 可以快速檢查組件中需要變更的部分。 @@ -45,6 +49,8 @@ export default Counter; 對於 `Counter` 組件,呈現階段是 React 使用新的 `count` 值再次執行函式的時刻。React 根據更新後的 `count` 值重新計算組件中 `

{count}

` 這部分應該呈現的樣子,但你不會在螢幕上看到任何變化,直到下一個階段-提交。 +## 提交階段 + 提交階段是 React 從虛擬 DOM 取得準備好的變更並將它們套用到真實 DOM 的階段。換句話說,這是你在螢幕上看到最終結果的階段。 為了達成這個目的,React 會比較虛擬 DOM 與實際 DOM,識別出只需要更新的零件,並將這些變更套用到真實 DOM,以更新使用者介面。 diff --git a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673369067f824d33a90a0534.md b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673369067f824d33a90a0534.md index 4cc0df72da0..94c8dd05190 100644 --- a/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673369067f824d33a90a0534.md +++ b/curriculum/challenges/chinese-traditional/blocks/lecture-working-with-the-dom-click-events-and-web-apis/673369067f824d33a90a0534.md @@ -1,12 +1,14 @@ --- id: 673369067f824d33a90a0534 -title: addEventListener 方法如何運作? +title: AddEventListener 方法如何運作? challengeType: 19 dashedName: how-does-the-addeventlistener-method-work --- # --interactive-- +## 什麼是 `addEventListener()` 方法? + 當使用者點擊按鈕或表單發生變更時,這稱為事件。在你的程式中,你需要有一種方式來監聽這些事件並對其做出回應。 `addEventListener()` 方法用於監聽事件。它接受兩個引數:你想監聽的事件以及事件發生時會被呼叫的函式。 @@ -21,7 +23,7 @@ element.addEventListener("event", listener); 監聽器是一個物件,當事件發生時會接收通知。大多數情況下,這會是你定義用來控制代碼該事件的函式。 -這裡有一個範例: +以下是一個範例: ```js element.addEventListener("click", () => { @@ -29,6 +31,8 @@ element.addEventListener("click", () => { }); ``` +## 傳遞函式引用 + 你也可以選擇傳入像這樣的函式引用: ```js @@ -41,10 +45,14 @@ element.addEventListener("click", handleClick); 有時你可能想要創建一個獨立的函式(程式)來控制該事件。這可以讓你的程式碼更容易閱讀和維護。 +## 使用 `EventListener` 介面 + 監聽器引數也可以是 `null`,或者可以是使用 `EventListener` 介面的物件。`EventListener` 介面定義了一個名為 `handleEvent()` 的單一方法。每當你監聽的事件發生時,這個方法會自動被呼叫。使用這個介面可以讓同一個物件在需要時控制多個事件。 大多數時間,你不需要使用這個介面,而是可以傳入一個在事件發生時會被呼叫的函式。 +## 監聽 `click` 事件 + 現在,讓我們來看一個範例,以更好地理解這是如何運作的: 在此範例中,我們有一個 id 為 `btn` 的 `button` 元素: @@ -78,9 +86,11 @@ btn.addEventListener("click", () => alert("You clicked the button")); You clicked the button ``` +## 監聽 `input` 事件 + 你可以監聽的另一種事件是 `"input"` 事件。當輸入元素的值改變時,會觸發此事件。 -這裡有一個範例: +以下是一個範例: ```html @@ -107,6 +117,8 @@ input.addEventListener("input", () => { ::: +## 監聽其他事件 + 你可以使用 `addEventListener()` 方法監聽更多的事件。一些常見的事件包括 `mouseover`、`mouseout`、`keydown`、`keyup` 和 `submit`。 在未來的課程中,我們將涵蓋更多事件以及如何使用 `addEventListener()` 方法來監聽它們。 diff --git a/curriculum/challenges/chinese-traditional/blocks/quiz-css-typography/66ed9010f45ce3ece4053eb8.md b/curriculum/challenges/chinese-traditional/blocks/quiz-css-typography/66ed9010f45ce3ece4053eb8.md index 5507e5b4d7e..81d537ddd4d 100644 --- a/curriculum/challenges/chinese-traditional/blocks/quiz-css-typography/66ed9010f45ce3ece4053eb8.md +++ b/curriculum/challenges/chinese-traditional/blocks/quiz-css-typography/66ed9010f45ce3ece4053eb8.md @@ -873,7 +873,7 @@ body { #### --text-- -以下哪一項可用來存取外部字型? +下列哪一項可用來匯入包含字型定義的外部樣式表? #### --distractors-- diff --git a/curriculum/challenges/chinese-traditional/blocks/quiz-python-installation/69fd84e01123960e15bb8455.md b/curriculum/challenges/chinese-traditional/blocks/quiz-python-installation/69fd84e01123960e15bb8455.md index fc021015f07..0e18281f951 100644 --- a/curriculum/challenges/chinese-traditional/blocks/quiz-python-installation/69fd84e01123960e15bb8455.md +++ b/curriculum/challenges/chinese-traditional/blocks/quiz-python-installation/69fd84e01123960e15bb8455.md @@ -29,7 +29,7 @@ dashedName: quiz-python-installation --- -從 pip 管理器下載 +從 pip 軟體包管理器 #### --answer-- @@ -87,7 +87,7 @@ IDE 是什麼縮寫? #### --distractors-- -JetBrains、CLion、WindSurf +JetBrains, CLion, Windsurf --- @@ -95,7 +95,7 @@ Photoshop、Illustrator、Figma --- -Clang、Pip、Deno +Clang, pip, Deno #### --answer-- @@ -187,7 +187,7 @@ Python 正在安裝套件。 #### --answer-- -Python 正在等待使用者輸入文字。 +Python 正在等待你輸入指令。 ### --question-- @@ -219,11 +219,11 @@ REPL 是什麼縮寫? #### --distractors-- -它會持續列印 `"Hello, world!"`,直到使用者停止。 +它會持續迴圈列印 `Hello, world!`,直到使用者停止它。 --- -它會建立一個檔案並在終端機列印 `"Hello, world!"`。 +它會建立一個檔案並在終端機列印 `Hello, world!`。 --- @@ -231,4 +231,4 @@ REPL 是什麼縮寫? #### --answer-- -它會在終端機列印 `"Hello, world!"`。 +它會在終端機列印 `Hello, world!`。 diff --git a/curriculum/challenges/chinese-traditional/blocks/review-back-end-development-and-apis/6a439658bfbe59fcf4b221c7.md b/curriculum/challenges/chinese-traditional/blocks/review-back-end-development-and-apis/6a439658bfbe59fcf4b221c7.md index 0c4323d2619..d6d3fad5363 100644 --- a/curriculum/challenges/chinese-traditional/blocks/review-back-end-development-and-apis/6a439658bfbe59fcf4b221c7.md +++ b/curriculum/challenges/chinese-traditional/blocks/review-back-end-development-and-apis/6a439658bfbe59fcf4b221c7.md @@ -342,7 +342,7 @@ Content-Length: 105 - **HTML**: `text/html` - **CSS**: `text/css` -- **JavaScript**: `application/javascript` +- **JavaScript**: `text/javascript` - **JSON**: `application/json` - **PNG/JPEG/WebP**: `image/png`, `image/jpeg`, `image/webp` - **MP4/MP3**: `video/mp4`, `audio/mpeg` diff --git a/curriculum/challenges/chinese-traditional/blocks/review-graphs-and-trees-js/698c302951ac746466349fd9.md b/curriculum/challenges/chinese-traditional/blocks/review-graphs-and-trees-js/698c302951ac746466349fd9.md index c173c0e9ff5..9d4374b1a70 100644 --- a/curriculum/challenges/chinese-traditional/blocks/review-graphs-and-trees-js/698c302951ac746466349fd9.md +++ b/curriculum/challenges/chinese-traditional/blocks/review-graphs-and-trees-js/698c302951ac746466349fd9.md @@ -1,106 +1,155 @@ --- id: 698c302951ac746466349fd9 -title: 複習圖形與樹狀結構 +title: 圖形與樹狀結構複習 challengeType: 31 dashedName: review-graphs-and-trees-js --- # --description-- -## 圖表總覽 - -圖是一組由邊(連接)連接的節點(頂點)。每個節點可以連接到多個其他節點,形成一個網路。不同型別的圖包括: - -- 有向:邊具有方向性(從一個節點到另一個節點),通常以直線和箭頭表述。 -- 無向:邊沒有方向,以簡單線條表述。 -- 頂點標籤:每個節點都與一個標籤或識別字相關。 -- 循環:包含循環(從同一節點開始並結束的路徑)。 -- 非循環(DAG):不包含循環。 -- 邊的標籤:每條邊都有一個標籤,通常繪製在對應邊的旁邊。 -- 加權:邊具有相關的權重(數值),可用於執行算術操作。 -- 不連通:包含兩個或以上未被任何邊連接的節點。 - -圖形用於各種應用,例如地圖、網路、推薦系統、相依性決議程序。 - -## 圖形遍歷 - -這涉及到造訪圖中的所有節點。兩個主要的演算法是: - -- **廣度優先搜尋 (BFS)** - - 使用佇列。 - - 逐層探索。 - - 尋找無權重圖中的最短路徑。 - -- **深度優先搜尋 (DFS)** - - 使用堆疊(或遞迴)。 - - 在回溯之前完全探索一個分支。 - - 對於循環檢測和路徑尋找非常有用。 - -## 圖形表述 - -圖形可以用兩種主要方式表述: - -- **鄰接列表** - - 每個節點都有一個鄰居的列表。 - - 對稀疏圖而言空間高效。 - - 易於對鄰居進行迭代。 - -- **鄰接矩陣** - - 一個二維陣列,其中列和行表述節點。 - - 對大型圖形而言空間密集。 - - 快速檢查兩個節點之間是否存在邊。 +## 圖形概述 + +圖形是一組由邊(連接)連結的節點(頂點)。每個節點可連接多個其他節點,形成網路。圖形類型包括: + +- **有向圖**:邊有方向(從一個節點指向另一個節點),通常用直線和箭頭表示。 +- **無向圖**:邊沒有方向,用簡單的線條表示。 +- **節點標籤**:每個節點都會有一個標籤或識別符。 +- **有環圖**:包含環路(起點和終點相同的路徑)。 +- **有向無環圖(DAG)**:一種沒有環路的有向圖。 +- **邊標籤**:每條邊都有標籤,通常標示在邊的旁邊。 +- **加權圖**:邊帶有權重(數值),可用來進行算術運算。 +- **非連通圖**:包含兩個或以上不相連的節點群組(組件)。兩個節點即使沒有直接邊相連,也可能存在路徑相通。 + +圖形被用於各種應用,例如地圖、網路、推薦系統和相依性決議。 + +## 圖形巡訪 + +涉及拜訪圖中所有節點。兩種主要演算法: + +- **廣度優先搜尋(BFS)**:先拜訪所有鄰近節點,再移動到圖的下一層。 + - **佇列**:使用佇列(先進先出)。起始節點標記為已拜訪並加入佇列。當佇列不空時,從佇列中取出目前節點,將其所有未拜訪的鄰居標記為已拜訪並加入佇列。 + - **最短路徑**:在無權重圖中尋找最短路徑。 + - **記憶體**:需要在記憶體中存放佇列,對於同一層有大量節點的圖,空間需求可能相當大。 + - **連通組件**:也可用於尋找連通的圖組件,從每個尚未拜訪的節點開始新的搜尋。 + - **狀態空間搜尋**:使用佇列追蹤不同狀態以生成括號組合。每個狀態以陣列表示,包含目前生成的字串、已使用的開括號數量和已使用的閉括號數量。只有當已使用的開括號數小於配對數時,才能加入開括號。只有在保持平衡(已使用開括號數多於閉括號數)時,才能加入閉括號。 + +- **深度優先搜尋(DFS)**:沿著每個分支盡可能深入,然後回溯。 + - **堆疊**:使用堆疊(後進先出)或遞迴。起始節點標記為已拜訪並加入堆疊。當堆疊不空時,彈出目前節點,將其所有未拜訪的鄰居標記為已拜訪並加入堆疊。 + - **記憶體**:需要在記憶體中存放堆疊(或使用遞迴時的函式呼叫堆疊),對於路徑很長的圖,空間需求可能增加。 + - **使用情境**:適用於偵測環路、尋找路徑和尋找連通組件。 + - **限制**:不一定能保證在無權重圖中找到兩節點間的最短路徑。 + +## 圖形表示法 + +圖形主要有兩種表示方式: + +- **鄰接列表**:每個節點有一個鄰居列表。 + - **實作**:可用陣列表示,每個索引代表一個節點,該索引處的陣列包含其鄰居。也可用物件(或 `Map`)表示,每個鍵代表節點,對應的值(陣列)包含其鄰居。 + - **空間**:對於稀疏圖空間高效,空間複雜度為 `O(V + E)`,其中 `V` 是節點數,`E` 是邊數。 + - **鄰居**:易於迭代鄰居,因為只需存取節點相關的列表。 + - **邊查找**:判斷兩節點間是否有邊不如鄰接矩陣高效,通常需 `O(deg(v))` 時間,其中 `deg(v)` 是該節點的鄰居數,最壞情況可達 `O(V)`。 + - **適用情境**:通常是現實場景中較常用的選擇,因為稀疏圖較普遍。 + +- **鄰接矩陣**:一個二維陣列,列和行代表節點。 + - **數值**:若圖無權重,值為 `1` 表示節點間有邊,值為 `0` 表示無邊。若有權重,值代表連接節點的邊的權重。 + - **自環**:對角線上的值表示節點是否有自環(連接自身的邊)。 + - **空間**:對大型圖空間需求大,為二次方空間 `O(V²)`,其中 `V` 是節點數。 + - **邊查找**:判斷兩節點間是否有邊非常快,為常數時間 `O(1)`。 + - **鄰居**:尋找節點鄰居效率低,因需遍歷整行或整列,最壞情況為 `O(V)`。 + - **適用情境**:適合邊數多的密集圖,對稀疏圖效率不佳。 + +## 最短路徑演算法 + +- **最短路徑演算法**:計算加權圖中節點間的最短路徑,並回傳距離和路徑。 + - **鄰接矩陣**:每個值代表兩節點間邊的權重(距離)。 + - **缺失邊**:值為 `INF`(`Infinity`)表示沒有直接邊。 + - **距離**:一個陣列,追蹤從起始節點到其他節點的最短已知距離。初始時,所有節點距離假設為無限遠,起始節點到自身距離為 `0`。 + - **路徑**:一個列表,每個項目是節點索引陣列,代表到達該節點的路徑。 + - **已拜訪**:一個陣列,追蹤已處理的節點,避免重複拜訪。 + - **最近未拜訪節點**:主迴圈對每個節點執行一次,每次選擇最近的未拜訪節點。 + - **邊鬆弛**:對每個有實際邊且未拜訪的鄰居,檢查是否能透過目前節點更有效率地到達。若新距離較短,更新距離和路徑。 + - **無法抵達節點**:當找不到有效節點時,剩餘節點皆無法抵達,迴圈提前結束。 + - **選用目標**:`targetNode` 參數為選填。若未提供,函式會計算從 `startNode` 到所有其他節點的最短路徑。 ## 樹 -樹是一種特殊型別的圖,具有無環且連通的特性。主要屬性包括: +樹是特殊的圖,無環且連通。主要特性: + +- **無環**:樹沒有迴圈或環路(起點和終點相同的路徑)。 +- **連通**:每個節點都能從其他節點抵達。 -- 它們沒有迴圈或循環(起點和終點節點相同的路徑)。 -- 它們必須是連通的(每個節點都可以從其他每個節點到達)。 +### 樹的術語 -### 常見的樹型別 +- **根節點**:樹的最頂端節點,是唯一沒有父節點的節點。 +- **父節點**:直接連接到下方其他節點的節點。 +- **子節點**:直接連接到上方節點的節點。 +- **葉節點**:沒有子節點的節點。 +- **深度**:從根節點到該節點的路徑長度。 +- **高度**:從該節點到葉節點的路徑長度。樹的高度即為根節點的高度。 +- **度數**:每個節點擁有的子節點數量。 +- **子樹**:樹的一部分,本身也是一棵樹。 +- **平衡樹**:任一節點的左右子樹高度相近,確保操作維持高效。 -最常見的樹的型別有: +### 常見的樹型 -- 二元樹 - - 每個節點最多有兩個子節點,分別是左子節點和右子節點。 +最常見的樹型有: -- 二元搜尋樹(BST) - - 一個二元樹,其中每個左子節點都小於其父節點,每個右子節點都大於其父節點。 +- **二元樹**:每個節點最多有兩個子節點,分別是左子節點和右子節點。 +- **二元搜尋樹(BST)**:一種二元樹,對每個節點,其左子樹所有值均小於該節點值,右子樹所有值均大於該節點值。左右子樹本身也必須是二元搜尋樹。 -## 嘗試 +- **自我平衡樹**:包含額外內部邏輯,當插入或刪除造成不平衡時會重新平衡樹。常見例子有 AVL 樹、紅黑樹和 B 樹。 -也稱為前置式樹,用於儲存字串集合,其中每個節點表現一個字元。 +- **AVL 樹**:一種自我平衡的二元搜尋樹,任一節點的左右子樹高度最多相差 1。 -共用的前置式只儲存一次,使它們在自動完成和拼字檢查等任務中高效。 +- **紅黑樹**:一種自我平衡的二元搜尋樹,每個節點有紅色或黑色標記。 -搜尋和插入操作的時間複雜度為 O(L),其中 L 是字串的長度。 +- **B 樹**:一種自我平衡樹,每個節點可有多個鍵值和超過兩個子節點。 -## 優先權佇列 +## 字首樹(Trie) -優先權佇列是一種抽象的資料型別,其中每個元素都有一個優先權。 +- **Trie 樹**:又稱前綴樹,用於儲存字串集合,每個節點代表一個字元。 +- **根節點**:根節點不代表特定字元,可視為代表空字串。 +- **前綴**:從根節點往下巡訪時,到達某節點的路徑定義了一個特定前綴。 +- **字尾標記**:代表完整字串的節點會被標記為字尾。 +- **共用前綴**:多個字串共用相同前綴時,路徑會重疊,前綴只儲存一次,使 Trie 在自動完成和拼字檢查等任務中高效。 +- **插入**:只需為 Trie 中尚不存在的字元創建新節點。 +- **時間複雜度**:搜尋和插入操作為 `O(L)`,其中 `L` 是字串長度。 +- **記憶體**:若字串集合中有許多獨特字元,Trie 可能效率不佳,因需為每個獨特字元存放節點。 -佇列和堆疊只考慮插入的順序,而優先權佇列則考慮元素的優先權。 +## 優先佇列 -標準佇列遵循 FIFO(先進先出),堆疊遵循 LIFO(後進先出)。然而,在優先權佇列中,具有較高優先權的元素會在較低優先權的元素之前被處理,無論它們的插入順序為何。 +- **優先佇列**:一種抽象資料型態,每個元素有優先權。 +- **佇列和堆疊**:佇列和堆疊只考慮插入順序,優先佇列則考慮元素優先權。標準佇列遵循 FIFO(先進先出),堆疊遵循 LIFO(後進先出)。 +- **移除順序**:通常優先移除優先權最高的元素,但有些實作也可能先移除優先權最低的元素。 +- **平手處理**:若需同優先權元素依插入順序移除,可加入唯一計數器以打破平手。 +- **應用**:尋找兩地間最短路徑、作業系統排程、交通模擬、資料壓縮和網路管理。 -## 堆積 +## 堆積(Heap) -它是一種專門的基於樹的資料結構,具有一個非常特定的屬性,稱為堆積屬性。 +堆積是一種特殊的樹狀資料結構,具有稱為堆積性質的特定屬性。 -堆積屬性決定父節點與子節點之間的關係。有兩種堆積型別: +堆積性質決定父節點與子節點的關係。有兩種堆積: -- 最大堆積 - - 每個父節點的值大於或相等於其子節點的值。 - - 最大元素位於根節點。 +- **最大堆積**:每個父節點的值大於或等於其子節點的值,且最大元素位於根節點。 -- 最小堆積 - - 每個父節點的值小於或相等於其子節點的值。 - - 最小的元素位於根節點。 +- **最小堆積**:每個父節點的值小於或等於其子節點的值,且最小元素位於根節點。 JavaScript 沒有內建的堆積模組,但你可以使用陣列實作一個最小堆積。 +- **陣列儲存**:堆積通常以陣列實作,以有效存取父節點和子節點。若堆積維持完整二元樹結構,陣列實作只需根據索引進行簡單數學運算即可找到元素位置。 +- **索引**:對於索引為 `i` 的節點,父節點位於 `Math.floor((i - 1) / 2)`,左子節點位於 `2 * i + 1`,右子節點位於 `2 * i + 2`。 +- **窺視(Peek)**:取得最小或最大值(視堆積類型而定)而不移除。 +- **推入(Push)**:將元素加入適當位置以維持堆積性質。新元素加入陣列末端,然後向上移動,與父節點交換位置,直到堆積性質被維持(冒泡上升)。 +- **彈出(Pop)**:移除優先權最高的元素(此處為最小值)。陣列最後一個元素取代根節點,然後向下移動,與較小的子節點交換位置,直到堆積性質被維持(冒泡下降)。 +- **推入彈出(PushPop)**:將推入和彈出合併為一次呼叫。比起分別呼叫更高效,尤其在堆積很大時,因只需執行一次重新排序操作。 +- **堆化(Heapify)**:將現有陣列轉換成堆積。 +- **比較回呼**:JavaScript 陣列不會自動逐元素比較排序,需傳入比較函式給堆積,先比較優先權,例如 `new MinHeap((a, b) => a[0] - b[0])`,其中元素以 `[priority, element]` 儲存。數值越小代表優先權越高。 +- **穩定平手打破**:在每個項目中加入遞增的插入計數器作為第二元素,如 `[priority, counter, element]`。先比較優先權,若相等再比較計數器:`new MinHeap((a, b) => (a[0] - b[0]) || (a[1] - b[1]))`。 +- **時間複雜度**:插入和取出最小或最大值為 `O(log n)`,窺視為 `O(1)`,堆化為 `O(n)`,搜尋或刪除任意元素為 `O(n)`。 +- **空間複雜度**:`O(n)`,其中 `n` 是堆積中元素數量。 + # --assignment-- -檢視 Graphs 和 Trees 主題與概念。 +複習圖形和樹的主題與概念。 diff --git a/curriculum/challenges/chinese-traditional/blocks/review-graphs-and-trees/67f39e06b8a11b2de9ccd361.md b/curriculum/challenges/chinese-traditional/blocks/review-graphs-and-trees/67f39e06b8a11b2de9ccd361.md index bc6dca15bf7..e7900f4cbea 100644 --- a/curriculum/challenges/chinese-traditional/blocks/review-graphs-and-trees/67f39e06b8a11b2de9ccd361.md +++ b/curriculum/challenges/chinese-traditional/blocks/review-graphs-and-trees/67f39e06b8a11b2de9ccd361.md @@ -7,96 +7,96 @@ dashedName: review-graph-and-trees # --description-- -## 圖表總覽 +## 圖形概述 -圖是一組由邊(連接)連接的節點(頂點)。每個節點可以連接到多個其他節點,形成一個網路。不同型別的圖包括: +圖形是一組由邊(連接)連結的節點(頂點)。每個節點可連接多個其他節點,形成網路。圖形類型包括: -- 有向:邊具有方向性(從一個節點到另一個節點),通常以直線和箭頭表述。 -- 無向:邊沒有方向,以簡單線條表述。 -- 頂點:每個節點都與一個標籤或識別符號相關。 -- 循環:包含循環(從同一節點開始並結束的路徑)。 -- 非循環(DAG):不包含循環。 -- 邊的標籤:每條邊都有一個標籤,通常繪製在對應邊的旁邊。 -- 加權:邊具有相關的權重(數值),可用於執行算術操作。 -- 不連通:包含兩個或以上未被任何邊連接的節點。 +- 有向圖:邊有方向(從一節點到另一節點),通常以直線和箭頭表示。 +- 無向圖:邊無方向,以簡單線條表示。 +- 頂點:每個節點有標籤或識別符。 +- 有環圖:包含環路(起點和終點相同的路徑)。 +- 無環圖(DAG):不包含環路。 +- 邊標籤圖:每條邊有標籤,通常畫在對應邊旁。 +- 加權圖:邊有權重(數值),可用於算術運算。 +- 不連通圖:包含兩個或以上未被邊連接的節點。 -圖形用於各種應用,例如地圖、網路、推薦系統、相依性決議程序。 +圖形用於地圖、網路、推薦系統、相依性解析等多種應用。 -## 圖形遍歷 +## 圖形巡訪 -這涉及到造訪圖中的所有節點。兩個主要的演算法是: +涉及拜訪圖中所有節點。兩種主要演算法: -- **廣度優先搜尋 (BFS)** +- **廣度優先搜尋(BFS)** - 使用佇列。 - - 逐層探索。 - - 尋找無權重圖中的最短路徑。 + - 按層級探索。 + - 找出無權重圖的最短路徑。 -- **深度優先搜尋 (DFS)** +- **深度優先搜尋(DFS)** - 使用堆疊(或遞迴)。 - - 在回溯之前完全探索一個分支。 - - 對於循環檢測和路徑尋找非常有用。 + - 完全探索一條分支後回溯。 + - 用於環路偵測和路徑尋找。 -## 圖形表述 +## 圖形表示法 -圖形可以用兩種主要方式表述: +圖形主要有兩種表示方式: - **鄰接列表** - - 每個節點都有一個鄰居的列表。 - - 對稀疏圖而言空間高效。 - - 易於對鄰居進行迭代。 + - 每個節點有鄰居列表。 + - 對稀疏圖空間效率高。 + - 易於巡訪鄰居。 - **鄰接矩陣** - - 一個二維陣列,其中列和行表述節點。 - - 對大型圖形而言空間密集。 - - 快速檢查兩個節點之間是否存在邊。 + - 二維陣列,行列代表節點。 + - 對大型圖空間需求大。 + - 快速檢查兩節點間是否有邊。 ## 樹 -樹是一種特殊型別的圖,具有無環且連通的特性。主要屬性包括: +樹是特殊的圖,無環且連通。主要特性: -- 它們沒有迴圈或循環(起點和終點節點相同的路徑)。 -- 它們必須是連通的(每個節點都可以從其他每個節點到達)。 +- 無迴圈或環路(起點和終點相同的路徑)。 +- 必須連通(每個節點可從其他節點抵達)。 -### 常見的樹型別 +### 常見樹型 -最常見的樹的型別有: +最常見的樹型有: - 二元樹 - - 每個節點最多有兩個子節點,分別是左子節點和右子節點。 + - 每個節點最多有兩個子節點,分別為左子節點和右子節點。 - 二元搜尋樹(BST) - - 一個二元樹,其中每個左子節點都小於其父節點,每個右子節點都大於其父節點。 + - 一種二元樹,左子節點值小於父節點,右子節點值大於父節點。 -## 嘗試 +## 字首樹(Trie) -也稱為前置式樹,用於儲存字串集合,其中每個節點表現一個字元。 +又稱前綴樹,用於儲存字串集合,每個節點代表一個字元。 -共用的前置式只儲存一次,使它們在自動完成和拼字檢查等任務中高效。 +共用的字首只儲存一次,對自動完成和拼字檢查等任務效率高。 -搜尋和插入操作的時間複雜度為 O(L),其中 L 是字串的長度。 +搜尋和插入操作的時間複雜度為 O(L),L 為字串長度。 -## 優先權佇列 +## 優先佇列 -優先權佇列是一種抽象的資料型別,其中每個元素都有一個優先權。 +優先佇列是一種抽象資料型態,每個元素有優先權。 -佇列和堆疊只考慮插入的順序,而優先權佇列則考慮元素的優先權。 +佇列和堆疊只考慮插入順序,優先佇列則依元素優先權服務。 -標準佇列遵循 FIFO(先進先出),堆疊遵循 LIFO(後進先出)。然而,在優先權佇列中,具有較高優先權的元素會在較低優先權的元素之前被處理,無論它們的插入順序為何。 +標準佇列遵循 FIFO(先進先出),堆疊遵循 LIFO(後進先出)。優先佇列中,優先權高的元素先被處理,無視插入順序。 -## 堆積 +## 堆積(Heap) -它是一種專門的基於樹的資料結構,具有一個非常特定的屬性,稱為堆積屬性。 +特殊的樹狀資料結構,具備堆積性質。 -堆積屬性決定父節點與子節點之間的關係。有兩種堆積型別: +堆積性質決定父節點與子節點的關係。有兩種堆積: -- 最大堆積 - - 每個父節點的值大於或相等於其子節點的值。 +- 最大堆積(Max-Heap) + - 每個父節點的值大於或等於子節點值。 - 最大元素位於根節點。 -- 最小堆積 - - 每個父節點的值小於或相等於其子節點的值。 - - 最小的元素位於根節點。 +- 最小堆積(Min-Heap) + - 每個父節點的值小於或等於子節點值。 + - 最小元素位於根節點。 ### Python `heapq` 模組範例 diff --git a/curriculum/challenges/chinese-traditional/blocks/review-http-and-the-web-standards-model/6a02da945706a3ddc2e44348.md b/curriculum/challenges/chinese-traditional/blocks/review-http-and-the-web-standards-model/6a02da945706a3ddc2e44348.md index 27afc03aa63..296a6408aa3 100644 --- a/curriculum/challenges/chinese-traditional/blocks/review-http-and-the-web-standards-model/6a02da945706a3ddc2e44348.md +++ b/curriculum/challenges/chinese-traditional/blocks/review-http-and-the-web-standards-model/6a02da945706a3ddc2e44348.md @@ -150,11 +150,11 @@ Connection: keep-alive `Content-Type` 標頭告訴瀏覽器如何處理回應中的資源。 -| 資源 | Content-Type | +| 資產 | Content-Type | | --- | --- | | HTML | `text/html` | | CSS | `text/css` | -| JavaScript | `application/javascript` | +| JavaScript | `text/javascript` | | JSON | `application/json` | | XML | `application/xml` | | JPEG | `image/jpeg` | diff --git a/curriculum/challenges/chinese-traditional/blocks/review-python-basics/67f39b40deaec81a3e40e0c5.md b/curriculum/challenges/chinese-traditional/blocks/review-python-basics/67f39b40deaec81a3e40e0c5.md index ac0bd9e14b3..c88ce3c289a 100644 --- a/curriculum/challenges/chinese-traditional/blocks/review-python-basics/67f39b40deaec81a3e40e0c5.md +++ b/curriculum/challenges/chinese-traditional/blocks/review-python-basics/67f39b40deaec81a3e40e0c5.md @@ -9,8 +9,8 @@ dashedName: review-python-basics ## 什麼是 Python? -- **介紹**:Python 是一種通用程式設計語言,以簡潔和易用著稱。Python 被廣泛應用於資料科學與機器學習、網頁開發、腳本與自動化、嵌入式系統與物聯網等多個領域。 -- **常見應用場景**:Python 用於資料科學、機器學習、網頁開發、資安、自動化以及像 Raspberry Pi 和支援 MicroPython 的微型電腦。 +- **介紹**:Python 是一種通用程式設計語言,以簡單易用著稱。 +- **常見應用**:Python 用於資料科學、機器學習、網頁開發、資安、嵌入式系統與物聯網、腳本編寫、自動化,以及像 Raspberry Pi 和相容 MicroPython 的微型電腦。 ## 變數 @@ -23,16 +23,18 @@ age = 25 - **變數命名規則**:變數命名應遵守以下規則: - - 變數名稱只能以字母或底線(_)開頭,不能以數字開頭。 - - 變數名稱只能包含英數字元(a-z、A-Z、0-9)和底線(_)。 - - 變數名稱區分大小寫 — `age`、`Age` 和 `AGE` 都被視為獨立的名稱。 - - 變數名稱不能是 Python 的保留關鍵字之一,例如 `if`、`class` 或 `def`。 - - 多字的變數名稱以底線分隔。例如 `snake_case`。 + - 變數名稱只能以字母或底線(`_`)開頭,不能以數字開頭。 + - 變數名稱只能包含字母數字字元(`a-z`、`A-Z`、`0-9`)和底線(`_`)。 + - 變數名稱區分大小寫:`age`、`Age` 和 `AGE` 都被視為不同。 + - 變數名稱不能是 Python 的保留關鍵字,例如 `if`、`class` 或 `def`。 + - 多字變數名稱使用底線分隔,如 `snake_case`。 + - 變數名稱應該描述其用途,如 `user_age`。 + - 當單字母變數名稱無法傳達意義時,應避免使用。 ## 註解 -- **單行註解**:用於在程式碼中留下簡短的備註。 +- **單行註解**:這種類型的註解用於程式碼中的簡短備註。 ```py # This is a single line comment @@ -57,7 +59,7 @@ print('Hello world!') # Hello world! ## Python 常見資料型別 - **介紹**:Python 是動態型別語言,這表示你不需要宣告變數的資料型別。Python 會根據指定給變數的值來判斷型別。 -- **整數**:沒有小數的整數: +- **整數**:沒有小數點的整數: ```py my_integer_var = 10 @@ -327,7 +329,7 @@ result = 'abcabc'.translate(trans_table) print(result) # 123123 ``` -## 整數與浮點數常用運算 +## 整數與浮點數的常用運算 - **基本數學運算**:Python 可對整數和浮點數做加、減、乘、除等基本運算: @@ -402,7 +404,7 @@ num = 4 print(float(num)) # 4.0 ``` -- **`int()` 函式(程式)**:你可以使用此函式(程式)將浮點數轉換為整數。 +- **`int()` 函式**:用來將浮點數轉成整數: ```py num = 4.0 @@ -550,7 +552,7 @@ print(int(False)) # 0 Python 有額外的範圍規則。現在先專注於區域範圍和全域範圍。 -- **區域範圍**:在函式內建立的變數只能在該函式內使用。函式的參數也是區域變數。 +- **區域作用域**:在函式內建立的變數只能在該函式內使用。函式的參數也是區域變數。 ```py def my_func(): @@ -558,7 +560,7 @@ def my_func(): print(num) ``` -- **全域範圍**:在函式外建立的變數可以在函式內外使用。 +- **全域作用域**:在函式外建立的變數可以在函式內外使用。 ```py tax = 0.70 diff --git a/curriculum/challenges/chinese-traditional/blocks/rosetta-code-challenges/598eea87e5cf4b116c3ff81a.md b/curriculum/challenges/chinese-traditional/blocks/rosetta-code-challenges/598eea87e5cf4b116c3ff81a.md index b4aaa2fc06d..bf0313590b4 100644 --- a/curriculum/challenges/chinese-traditional/blocks/rosetta-code-challenges/598eea87e5cf4b116c3ff81a.md +++ b/curriculum/challenges/chinese-traditional/blocks/rosetta-code-challenges/598eea87e5cf4b116c3ff81a.md @@ -24,15 +24,15 @@ dashedName: factors-of-a-mersenne-number 將指數 23 轉換成二進位,你會得到 10111。從 square = 1 開始,反覆平方它。 -移除指數的最高位元,如果是 1,則將 `square` 乘以指數的底數(2),然後計算 square 取模 47。 +移除指數的最高位元,如果是 1,則將 `square` 乘以指數的底數(2),然後計算 square mod 47。 將上一步的取模結果用作下一步中 `square` 的初始值: -
Remove   Optional
-square        top bit  multiply by 2  mod 47
+
移除   選用
+square        最高位元  乘以 2  mod 47
 ------------  -------  -------------  ------
 1*1 = 1       1  0111  1*2 = 2           2
-2*2 = 4       0   111     no             4
+2*2 = 4       0   111     否             4
 4*4 = 16      1    11  16*2 = 32        32
 32*32 = 1024  1     1  1024*2 = 2048    27
 27*27 = 729   1        729*2 = 1458      1
diff --git a/curriculum/challenges/chinese-traditional/blocks/rosetta-code-challenges/599d1566a02b571412643b84.md b/curriculum/challenges/chinese-traditional/blocks/rosetta-code-challenges/599d1566a02b571412643b84.md
index 66eb835dbab..a18e70013b3 100644
--- a/curriculum/challenges/chinese-traditional/blocks/rosetta-code-challenges/599d1566a02b571412643b84.md
+++ b/curriculum/challenges/chinese-traditional/blocks/rosetta-code-challenges/599d1566a02b571412643b84.md
@@ -13,11 +13,11 @@ dashedName: ethiopian-multiplication
 **方法:**
 
 
    -
  1. Take two numbers to be multiplied and write them down at the top of two columns
  2. -
  3. In the left-hand column repeatedly halve the last number, discarding any remainders, and write the result below the last in the same column, until you write a value of 1
  4. -
  5. In the right-hand column repeatedly double the last number and write the result below. stop when you add a result in the same row as where the left hand column shows 1
  6. -
  7. Examine the table produced and discard any row where the value in the left column is even
  8. -
  9. Sum the values in the right-hand column that remain to produce the result of multiplying the original two numbers together
  10. +
  11. 取兩個要相乘的數字,並將它們寫在兩個行的頂端
  12. +
  13. 在左邊的行中,反覆將最後一個數字除以二並捨去餘數,將結果寫在同一行的上一個數字下方,直到寫出值為 1
  14. +
  15. 在右邊的行中,反覆將最後一個數字加倍並寫在下方。當你在左邊行顯示 1 的同一列加入結果時停止
  16. +
  17. 檢查產生的表格,捨棄左邊行中值為偶數的任何列
  18. +
  19. 將右邊行中剩下的值相加,得到原本兩個數字相乘的結果
**例如:** `17 × 34` @@ -74,9 +74,9 @@ dashedName: ethiopian-multiplication 任務是定義三個具名的函式(程式)/方法/程序/常式:
    -
  1. one to halve an integer,
  2. -
  3. one to double an integer, and
  4. -
  5. one to state if an integer is even
  6. +
  7. 一個用來將整數除以二的函式,
  8. +
  9. 一個用來將整數加倍的函式,和
  10. +
  11. 一個用來判斷整數是否為偶數的函式
使用這些函式(程式)來創建一個執行埃塞俄比亞乘法的函式(程式)。 diff --git a/curriculum/challenges/chinese-traditional/blocks/top-learn-css-foundations/63ee35450d8d4841c3a70920.md b/curriculum/challenges/chinese-traditional/blocks/top-learn-css-foundations/63ee35450d8d4841c3a70920.md index 73f91b95d7f..fadc31253b1 100644 --- a/curriculum/challenges/chinese-traditional/blocks/top-learn-css-foundations/63ee35450d8d4841c3a70920.md +++ b/curriculum/challenges/chinese-traditional/blocks/top-learn-css-foundations/63ee35450d8d4841c3a70920.md @@ -7,13 +7,13 @@ dashedName: css-foundations-lesson-g # --description-- -內部 CSS(或內嵌 CSS)是指將 CSS 直接加入 HTML 檔案中,而不是建立一個完全獨立的檔案。使用內部方法時,你會將所有規則放在一對開啟和關閉的 `