From a1b40fecb94da7314a08fd05a574f6f94e76aab1 Mon Sep 17 00:00:00 2001 From: freeCodeCamp's Camper Bot Date: Thu, 11 Jul 2024 22:11:30 -0500 Subject: [PATCH] chore(i18n,learn): processed translations (#55488) --- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../614396f7ae83f20ea6f9f4b3.md | 12 +- .../5f331e55dfab7a896e53c3a1.md | 4 +- .../5f3477cb2e27333b1ab2b955.md | 4 +- .../5f3ef6e01f288a026d709587.md | 10 +- .../5f46e8284aae155c83015dee.md | 8 +- .../5d822fd413a79914d39e98fb.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- .../662a6bc12cde72c32fb526f0.md | 30 ++ .../662bd456896f16d9bd03f1a6.md | 47 +++ .../662bd552e1c1d2db1b88ba47.md | 40 +++ .../662bd8260da84bdd5feae419.md | 48 +++ .../662bdd364bf2cde1487922a9.md | 44 +++ .../662bde88dc84f1e249801b1a.md | 52 +++ .../662f6d7c92381a3049e4c987.md | 57 +++ .../662f96576ef178927de87975.md | 88 +++++ .../662fa2e2cf27c09f21f4f5d0.md | 52 +++ .../662fbcef5f05e1b84f541a0c.md | 83 +++++ .../662fc3eba556a6bf800d48c1.md | 87 +++++ .../6639f947d3a1818c9322c64a.md | 74 ++++ .../6639fdcc701833a54c364211.md | 94 +++++ .../663a22ba7420c4d2f7fd2aec.md | 96 +++++ .../663a2dd1901cbeecc28748bd.md | 83 +++++ .../663a32735b317af9812eb0d7.md | 106 ++++++ .../663b7fefd437bd984e091cbf.md | 116 ++++++ .../663b83a28943e6aa6275a514.md | 97 +++++ .../663b93aee129b3c4cc07d0db.md | 110 ++++++ .../663b95d65caeb3ca04c5fef4.md | 82 +++++ .../663c981b9b06922e13a97fe9.md | 84 +++++ .../663c9f31306353460da54542.md | 86 +++++ .../664c670069bae45fd060c25d.md | 66 ++++ .../664cb04a16fe6938708967ef.md | 87 +++++ .../664e4a590b52ba8d2adff19f.md | 116 ++++++ .../664e4e1b6c35a99cbba49e84.md | 105 ++++++ .../664ee8037f4bbe3c0944c35e.md | 110 ++++++ .../664eec7f38234443b42c206f.md | 105 ++++++ .../664eef158d792a509e8d708a.md | 114 ++++++ .../664ef4623946e65e18d59764.md | 124 +++++++ .../664f0389424a6f7aa15fd3e5.md | 114 ++++++ .../664f4559c17d2138ae680566.md | 111 ++++++ .../6650583d9d9a194714da47f0.md | 111 ++++++ .../6650633eaeccf266fee14ba6.md | 109 ++++++ .../6650e11fa60e222e691bb283.md | 110 ++++++ .../6650e27cf34f2335a9bbbd08.md | 110 ++++++ .../6650e88cc500673ec881c9ca.md | 126 +++++++ .../6650eb84e248684c2f57555c.md | 115 ++++++ .../6650f037c017aa6855a608e3.md | 118 +++++++ .../665460392acb7e91db2afad1.md | 126 +++++++ .../665467883dded0a1dad983b2.md | 121 +++++++ .../66558720bbe6e038315b7f81.md | 121 +++++++ .../665621ef85db565d26632761.md | 126 +++++++ .../66562f71937f877c66123bbe.md | 152 ++++++++ .../665ee783d35cb68875c626d4.md | 89 +++++ .../66759e32b88fb5459b1e0234.md | 56 +++ .../6675a38a8b535e4ff3274520.md | 73 ++++ .../6675aaf418b41157f6ccd692.md | 62 ++++ .../667938f754145d165c25725d.md | 153 ++++++++ .../66793a552f357b17006a8726.md | 138 ++++++++ .../66793c5b4bdacc17c40ff8e7.md | 150 ++++++++ .../66793d1e1581681871635ac6.md | 149 ++++++++ .../66794346ddfa141cbe70093a.md | 139 ++++++++ .../667944fed1f6b61da3406bd8.md | 164 +++++++++ .../66799278873fd2570217bffa.md | 165 +++++++++ .../6679934707d5fe577f898efd.md | 170 +++++++++ .../66799ba07c5fd58a61a604d3.md | 159 +++++++++ .../66799c1a0204668cef35555d.md | 157 +++++++++ .../6679bf00da92e5c0db0ffdc3.md | 164 +++++++++ .../6679bfe40a6d77c6a3c17e06.md | 150 ++++++++ .../667a7ce2a9925416e7b4781b.md | 197 +++++++++++ .../667a860c3b61f61b7a18930c.md | 168 +++++++++ .../667a8d7a735cf221729570ff.md | 225 ++++++++++++ .../667a965d5a4b5825ffb2e1d8.md | 196 +++++++++++ .../667a9c91a87bb453a355b63d.md | 173 +++++++++ .../667aa056f1240f58fb9a2c17.md | 331 ++++++++++++++++++ .../667e623208053643ca9d3c6e.md | 116 ++++++ .../6601a8fb2e993b55912f9e9f.md | 6 +- .../6601ad0fe415985a5c83f3cc.md | 2 +- .../63c620161fc2b49ac340ffc4.md | 2 +- 776 files changed, 84742 insertions(+), 75 deletions(-) create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f0389424a6f7aa15fd3e5.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664f4559c17d2138ae680566.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650583d9d9a194714da47f0.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650633eaeccf266fee14ba6.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e11fa60e222e691bb283.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e27cf34f2335a9bbbd08.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650e88cc500673ec881c9ca.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650eb84e248684c2f57555c.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6650f037c017aa6855a608e3.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665460392acb7e91db2afad1.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665467883dded0a1dad983b2.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md create mode 100644 curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index 9653de9b32d..2d90aaf6ba7 100644 --- a/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -In this project, you will build a set of football team cards and learn about nested objects, object destructuring, default parameters, event listeners, and switch statements. All of the HTML and CSS for this project has been provided for you. +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. All of the HTML and CSS for this project has been provided for you. Start by accessing the `id` called `"team"` from the HTML document and storing it in a `const` variable called `teamName`. diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index ec6a5bab818..d068698240e 100644 --- a/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -在這個項目中,你將構建一組足球隊卡片,並瞭解嵌套對象、對象解構、默認參數、事件監聽器和 switch 語句。 該項目的所有 HTML 和 CSS 均已爲你提供。 +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. 該項目的所有 HTML 和 CSS 均已爲你提供。 首先從 HTML 文檔訪問名爲 `"team"` 的 `id`,並將其存儲在名爲 `teamName` 的 `const` 變量中。 diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index 6f521913b3f..2f6f9146eb1 100644 --- a/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -在这个项目中,你将构建一组足球队卡片,并了解嵌套对象、对象解构、默认参数、事件监听器和 switch 语句。 该项目的所有 HTML 和 CSS 均已为你提供。 +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. 该项目的所有 HTML 和 CSS 均已为你提供。 首先从 HTML 文档访问名为 `"team"` 的 `id`,并将其存储在名为 `teamName` 的 `const` 变量中。 diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/espanol/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index 3961668df2c..27e0780a049 100644 --- a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -In this project, you will build a set of football team cards and learn about nested objects, object destructuring, default parameters, event listeners, and switch statements. All of the HTML and CSS for this project has been provided for you. +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. All of the HTML and CSS for this project has been provided for you. Start by accessing the `id` called `"team"` from the HTML document and storing it in a `const` variable called `teamName`. diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/german/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/german/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/german/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/german/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/german/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index ed25f72285a..6c4dd0e3543 100644 --- a/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -In this project, you will build a set of football team cards and learn about nested objects, object destructuring, default parameters, event listeners, and switch statements. Das gesamte HTML und CSS für dieses Projekt wurde für dich bereitgestellt. +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. Das gesamte HTML und CSS für dieses Projekt wurde für dich bereitgestellt. Start by accessing the `id` called `"team"` from the HTML document and storing it in a `const` variable called `teamName`. diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/italian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/italian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index 6ca282812f8..d84288bbfad 100644 --- a/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -In questo progetto creerai un set di figurine di una squadra di calcio e imparerai a usare oggetti annidati, destrutturazione di oggetti, parametri predefiniti, event listener e istruzioni switch. Tutto l'HTML e il CSS per questo progetto ti è già stato fornito. +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. Tutto l'HTML e il CSS per questo progetto ti è già stato fornito. Start by accessing the `id` called `"team"` from the HTML document and storing it in a `const` variable called `teamName`. diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/japanese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index 87cfc58dcc7..e03e90f75fe 100644 --- a/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -In this project, you will build a set of football team cards and learn about nested objects, object destructuring, default parameters, event listeners, and switch statements. All of the HTML and CSS for this project has been provided for you. +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. All of the HTML and CSS for this project has been provided for you. Start by accessing the `id` called `"team"` from the HTML document and storing it in a `const` variable called `teamName`. diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/korean/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/korean/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/korean/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/korean/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index 87cfc58dcc7..e03e90f75fe 100644 --- a/curriculum/challenges/korean/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/korean/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -In this project, you will build a set of football team cards and learn about nested objects, object destructuring, default parameters, event listeners, and switch statements. All of the HTML and CSS for this project has been provided for you. +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. All of the HTML and CSS for this project has been provided for you. Start by accessing the `id` called `"team"` from the HTML document and storing it in a `const` variable called `teamName`. diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/portuguese/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md index 6bb56599282..90e16da853f 100644 --- a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md +++ b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md @@ -9,7 +9,7 @@ dashedName: step-26 Dentro do segundo elemento `section`, adicione dois elementos `div` com uma classe `question-block`. -Then, within each `div.question-block` element, add one `h3` element with text of incrementing numbers, starting at `1`, and one `fieldset` element with a class of `question`. +Agora, dentro de cada `div.question-block`, adicione um elemento `h3` com texto de números sendo incrementados, começando em `1`, e um elemento `fieldset` com uma classe de `question`. # --hints-- @@ -31,19 +31,19 @@ Você deve dar ao segundo novo elemento `div` uma classe de `question-block`. assert.equal(document.querySelectorAll('section:nth-of-type(2) > div')?.[1]?.className, 'question-block'); ``` -You should nest one `h3` element within each `div.question-block` element. +Você deve colocar um elemento `h3` dentro de cada elemento `div.question-block`. ```js assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > h3')?.length, 2); ``` -You should give the first `h3` element text of `1`. +Você deve dar ao primeiro texto do elemento `h3` o valor de `1`. ```js assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > h3')?.[0]?.textContent, '1'); ``` -You should give the second `h3` element text of `2`. +Você deve dar ao segundo texto do elemento `h3` o valor de `2`. ```js assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > h3')?.[1]?.textContent, '2'); @@ -55,13 +55,13 @@ Você deve colocar um elemento `fieldset` dentro de cada elemento `div.question- assert.equal(document.querySelectorAll('section:nth-of-type(2) > div.question-block > fieldset')?.length, 2); ``` -You should place the first `fieldset` element after the first `h3` element. +Você deve posicionar o primeiro elemento `fieldset` depois do primeiro elemento `h3`. ```js assert.exists(document.querySelector('section:nth-of-type(2) > div.question-block > h3 + fieldset')); ``` -You should place the second `fieldset` element after the second `h3` element. +Você deve posicionar o segundo elemento `fieldset` depois do segundo elemento `h3`. ```js assert.exists(document.querySelector('section:nth-of-type(2) > div.question-block:nth-of-type(2) > h3 + fieldset')); diff --git a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f331e55dfab7a896e53c3a1.md b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f331e55dfab7a896e53c3a1.md index 52396832adc..6c2fd8b4e88 100644 --- a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f331e55dfab7a896e53c3a1.md +++ b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f331e55dfab7a896e53c3a1.md @@ -9,7 +9,7 @@ dashedName: step-3 O `title` é um dos vários elementos que fornecem informações extras que não são visíveis na página da web, mas ele é útil para mecanismos de busca ou até mesmo em como a página é exibida. -Inside the `head` element, nest a `meta` element with an attribute named `charset` set to the value `utf-8` to tell the browser how to encode characters for the page. +Dentro do elemento `head`, adicione um elemento `meta` com um atributo chamado `charset` definido para o valor `utf-8` para dizer ao navegador como codificar caracteres para a página. # --hints-- @@ -19,7 +19,7 @@ Você deve criar uma tag `meta`. assert.match(code, //is); ``` -The `meta` element is a void element, it should not have an end tag ``. +O elemento `meta` deve ser um elemento nulo, sem uma tag final ``. ```js assert.notMatch(code, /<\/meta>/i); diff --git a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb2e27333b1ab2b955.md b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb2e27333b1ab2b955.md index 1eb68cac14c..52c9bf939e1 100644 --- a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb2e27333b1ab2b955.md +++ b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3477cb2e27333b1ab2b955.md @@ -18,7 +18,7 @@ const link = document.querySelector('link'); assert.isNotNull(link); ``` -The `link` element is a void element, it should not have an end tag ``. +O elemento `link` deve ser um elemento nulo, sem uma tag final ``. ```js assert.notMatch(code, /<\/link>/i); @@ -31,7 +31,7 @@ const headElementCount = document.querySelectorAll('head')?.length; assert.strictEqual(headElementCount, 1); ``` -You should have one `link` element. +Você deve ter um elemento `link`. ```js const linkElementCount = document.querySelectorAll('link')?.length; diff --git a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e01f288a026d709587.md b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e01f288a026d709587.md index 6139de2ae81..0fdd4d8abe6 100644 --- a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e01f288a026d709587.md +++ b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f3ef6e01f288a026d709587.md @@ -9,7 +9,7 @@ dashedName: step-66 Você pode usar um elemento `hr` para exibir um divisor entre seções de conteúdo diferente. -First, add an `hr` element between the `p` element with the class `established` and the first `section` element. +Primeiramente, adicione um elemento `hr` entre o elemento `p` com a classe `established` e o primeiro elemento `section`. # --hints-- @@ -19,27 +19,27 @@ Você deve adicionar um elemento `hr`. assert.match(code, //i); ``` -The `hr` element is a void element, it should not have an end tag ``. +O elemento `hr` deve ser um elemento nulo, sem uma tag final ``. ```js assert.notMatch(code, /<\/hr>/i); ``` -You should not change your existing `p` element with the class `established`. +Você não deve alterar o elemento `p` existente com a classe `established`. ```js const pElementCount = document.querySelectorAll('p.established')?.length; assert.strictEqual(pElementCount, 1); ``` -You should not change your existing `main` element. +O elemento preexistente `main` deve permanecer o mesmo. ```js const mainElementCount = document.querySelectorAll('main')?.length; assert.strictEqual(mainElementCount, 1); ``` -Your `hr` element should be between your `p` element and your `section` element. +O elemento `hr` deve estar entre os elementos `p` e `section`. ```js const hrElement = document.querySelector('hr'); diff --git a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f46e8284aae155c83015dee.md b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f46e8284aae155c83015dee.md index 81d91e520c7..d6449428391 100644 --- a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f46e8284aae155c83015dee.md +++ b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-basic-css-by-building-a-cafe-menu/5f46e8284aae155c83015dee.md @@ -13,27 +13,27 @@ Sob o título `Coffee`, adicione uma imagem usando o url `https://cdn.freecodeca # --hints-- -You should have an `` tag. +Você deve ter uma tag ``. ```js const imageElementCount = document.querySelectorAll('img')?.length; assert.strictEqual(imageElementCount, 1); ``` -The `img` element is a void element, it should not have an end tag ``. +O elemento `img` deve ser um elemento nulo, sem uma tag final ``. ```js assert.notMatch(code, /<\/img>/i); ``` -Your `img` element should have a `src` attribute, with the value `"https://cdn.freecodecamp.org/curriculum/css-cafe/coffee.jpg"`. +O elemento `img` deve ter o atributo `src` com o valor de `"https://cdn.freecodecamp.org/curriculum/css-cafe/coffee.jpg"`. ```js const imageSrcValue = document.querySelector('img')?.getAttribute('src'); assert.strictEqual(imageSrcValue, 'https://cdn.freecodecamp.org/curriculum/css-cafe/coffee.jpg'); ``` -Your `img` element should have an `alt` attribute, with the value `"coffee icon"`. +O elemento `img` deve ter o atributo `alt` com o valor de `"coffee icon"`. ```js const imageAltValue = document.querySelector('img')?.getAttribute('alt'); diff --git a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-css-variables-by-building-a-city-skyline/5d822fd413a79914d39e98fb.md b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-css-variables-by-building-a-city-skyline/5d822fd413a79914d39e98fb.md index 452d85775b6..9cee73c2f81 100644 --- a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-css-variables-by-building-a-city-skyline/5d822fd413a79914d39e98fb.md +++ b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-css-variables-by-building-a-city-skyline/5d822fd413a79914d39e98fb.md @@ -7,7 +7,7 @@ dashedName: step-51 # --description-- -As transições gradientes muitas vezes mudam gradualmente de uma cor para outra. When a more abrupt change is required, the transition can be made with a hard stop like this: +As transições gradientes muitas vezes mudam gradualmente de uma cor para outra. Quando é necessária uma mudança mais brusca, a transição pode ser feita com uma parada brusca, assim: ```css linear-gradient( diff --git a/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index ff5b846d4c5..cd9af55a170 100644 --- a/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -Neste projeto, você criará um conjunto de cards de time de futebol e aprenderá sobre objetos aninhados, desestruturação de objetos, parâmetros padrão (default), "ouvintes" de eventos e instruções switch. Todo o HTML e o CSS para este projeto foram fornecidos para você. +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. Todo o HTML e o CSS para este projeto foram fornecidos para você. Start by accessing the `id` called `"team"` from the HTML document and storing it in a `const` variable called `teamName`. diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 47d13a7bd4d..22f7290c63e 100644 --- a/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/swahili/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Well done! diff --git a/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index e1b4a0f48c7..4c874138cf1 100644 --- a/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -In this project, you will build a set of football team cards and learn about nested objects, object destructuring, default parameters, event listeners, and switch statements. All of the HTML and CSS for this project has been provided for you. +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. All of the HTML and CSS for this project has been provided for you. Start by accessing the `id` called `"team"` from the HTML document and storing it in a `const` variable called `teamName`. diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md new file mode 100644 index 00000000000..6539a80efb9 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662a6bc12cde72c32fb526f0.md @@ -0,0 +1,30 @@ +--- +id: 662a6bc12cde72c32fb526f0 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +An interface is like a blueprint for a class. An interface contains a set of methods and properties that a class should implement. + +Start this project by declaring an empty class named `Equation`. You will use this class to define an interface, a blueprint for a generic equation. + +# --hints-- + +You should define a new class named `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md new file mode 100644 index 00000000000..0bfb730af31 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd456896f16d9bd03f1a6.md @@ -0,0 +1,47 @@ +--- +id: 662bd456896f16d9bd03f1a6 +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +Within the `Equation` class, define two new instance methods named `solve` and `analyze`. + +# --hints-- + +You should define a method named `solve` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +class Equation: + pass +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md new file mode 100644 index 00000000000..5e251139431 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd552e1c1d2db1b88ba47.md @@ -0,0 +1,40 @@ +--- +id: 662bd552e1c1d2db1b88ba47 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Now, define another class named `LinearEquation` and make it inherit from `Equation`. You'll use this class to represent linear equations. + +# --hints-- + +You should define a class named `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_class("LinearEquation")`)) }) +``` + +Your `LinearEquation` class should inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").inherits_from("Equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md new file mode 100644 index 00000000000..e215fc03528 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bd8260da84bdd5feae419.md @@ -0,0 +1,48 @@ +--- +id: 662bd8260da84bdd5feae419 +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +You want the `LinearEquation` class to implement and not simply inherit all the methods defined inside the `Equation` class, which should act as an interface. + +Currently, the `Equation` class is simply the parent class of `LinearEquation`. In the next steps you will learn how to turn it into a formal interface. + +For now, create an instance of `Equation` and assign it to a variable `eq`, and an instance of `LinearEquation` and assign it to a variable `lin_eq`. + +# --hints-- + +You should declare a variable `eq` and assign it an instance of `Equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("eq = Equation()")`)) }) +``` + +You should declare a variable `lin_eq` and assign it an instance of `LinearEquation`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md new file mode 100644 index 00000000000..776994dbfb5 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bdd364bf2cde1487922a9.md @@ -0,0 +1,44 @@ +--- +id: 662bdd364bf2cde1487922a9 +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Unlike other programming languages, Python does not implement interfaces in its core language, but the Python standard library allows you to define interfaces in a simple way. + +For this project, you'll use utilities from the `abc` module. Therefore, import this module in your code. + +# --hints-- + +You should import the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import abc")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation: + def solve(self): + pass + + def analyze(self): + pass + + +class LinearEquation(Equation): + pass + + +eq = Equation() +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md new file mode 100644 index 00000000000..e456cd42865 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662bde88dc84f1e249801b1a.md @@ -0,0 +1,52 @@ +--- +id: 662bde88dc84f1e249801b1a +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +`ABC` stands for *Abstract Base Classes*. The `ABC` class enables you to turn a regular class into an abstract class, which is a class that acts as a blueprint for concrete classes. + +Modify your `import` statement to import just the `ABC` class from the `abc` module. You can import a specific object `x` from a module `y` following the import construct `from y import x`. + +Then, turn your `Equation` class into an abstract class by making it inherit from `ABC`. + +# --hints-- + +You should import `ABC` from the `abc` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("from abc import ABC")`)) }) +``` + +Your `Equation` class should inherit from `ABC`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").inherits_from("ABC")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import abc + + +class Equation: + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md new file mode 100644 index 00000000000..01862510583 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f6d7c92381a3049e4c987.md @@ -0,0 +1,57 @@ +--- +id: 662f6d7c92381a3049e4c987 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +An interface doesn't have to define only abstract methods, but it can also implement methods to be inherited by the concrete classes. + +Before taking care of the actual implementation of `solve` and `analyze`, within the `Equation` class, define an `__init__` method. Do not use any decorator on it. + +# --hints-- + +You should define an `__init__` method in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC, abstractmethod + + +class Equation(ABC): + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md new file mode 100644 index 00000000000..e9f3eec422d --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662f96576ef178927de87975.md @@ -0,0 +1,88 @@ +--- +id: 662f96576ef178927de87975 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +In order to be recognized as an abstract method, a method should be decorated with the `@abstractmethod` decorator. + +Modify your import statement to import the `abstractmethod` decorator and decorate both the `solve` and `analyze` methods of the `Equation` class. This will raise two exceptions. + +Once a class inheriting from `ABC` has an abstract method, the class cannot be instantiated anymore. Therefore, delete the `Equation` instance to get rid of the error. + +The other error occurs because the `LinearEquation` class must implement all the abstract methods defined in the interface. Make sure to define them inside the `LinearEquation` class, too. You must not use the `abstractmethod` decorator in the concrete class. + +# --hints-- + +You should import `abstractmethod` from the `abc` module. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_import("from abc import ABC, abstractmethod") or \\ +_Node(_code).has_import("from abc import abstractmethod, ABC") or \\ +(_Node(_code).has_import("from abc import abstractmethod") and _Node(_code).has_import("from abc import ABC")) +`)) }) +``` + +You should decorate with `@abstractmethod` the `solve` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("solve").has_decorators("abstractmethod")`)) }) +``` + +You should decorate with `@abstractmethod` the `analyze` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("analyze").has_decorators("abstractmethod")`)) }) +``` + +You should define a method named `solve` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define a method named `analyze` within the `LinearEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_function("analyze")`)) }) +``` + +Your `solve` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_args("self")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +from abc import ABC + + +class Equation(ABC): + def solve(self): + pass + + def analyze(self): + pass + +class LinearEquation(Equation): + pass + +eq = Equation() +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md new file mode 100644 index 00000000000..3fa9502e3d9 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fa2e2cf27c09f21f4f5d0.md @@ -0,0 +1,52 @@ +--- +id: 662fa2e2cf27c09f21f4f5d0 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +In Python, data types are recognized during runtime (when the code is executed). Therefore, you don't have to specify the data type of a variable when you declare it. Nonetheless, you can annotate a variable to clarify that it will hold a specific data type with `variable: = value` or just `variable: `. Note that the Python interpreter does not enforce the types used to annotate variables, and normally you'd need external tools to do it. + +Inside the `Equation` class, define a class attribute `degree`. Do not assign it a value. Instead use a type annotation of `int` to show that it will store an integer number inside the concrete classes. + +Later on, you'll use this class attribute as a part of the validation process of the arguments passed to instantiate the equation objects. + +# --hints-- + +You should define class attribute named `degree` and annotate it with `int` within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_variable("degree").is_equivalent("degree: int")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + def __init__(self): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md new file mode 100644 index 00000000000..ffbd0e05c81 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fbcef5f05e1b84f541a0c.md @@ -0,0 +1,83 @@ +--- +id: 662fbcef5f05e1b84f541a0c +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + +Each equation object will be instantiated passing as many arguments as the coefficients of the equation, starting from n-th degree of \\( x \\) down to the zero-th degree, including the possible coefficient with the value of `0`. + +For example, `LinearEquation(4, 5)` would represent the equation \\( 4x + 5 = 0 \\), with `4` being the coefficient of the first (highest here) degree and `5` the coefficient of the zero-th degree. + +You need to check that the right number of arguments is passed to instantiate the equation object. + +Inside the `__init__` method, create an `if` statement to check if the length of `args` is different from the number of coefficients the equation should have (`degree + 1`). If it is, raise a `TypeError` and use the following string to provide a custom message: `f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given"`. + +Then, fix the error by passing the `2` and `3` to instantiate `lin_eq`. + +# --hints-- + +You should create an `if` statement that checks if the number of coefficients used to instantiate the equation is different from `degree + 1`. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_conditions()[0] +cond.is_equivalent("(self.degree + 1) != len(args)") or cond.is_equivalent("len(args) != (self.degree + 1)") +`)) }) +``` + +You should raise a `TypeError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[0].find_bodies()[0].has_stmt('raise TypeError(f"\\'{self.__class__.__name__}\\' object takes {self.degree + 1} positional arguments but {len(args)} were given")') +`)) }) +``` + +You should pass `2` and `3` to instantiate `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("lin_eq = LinearEquation(2, 3)")`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + pass + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation() +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md new file mode 100644 index 00000000000..9e5aea86947 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/662fc3eba556a6bf800d48c1.md @@ -0,0 +1,87 @@ +--- +id: 662fc3eba556a6bf800d48c1 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +The `isinstance()` built-in function takes two arguments and returns a Boolean indicating if the object passed as the first argument is an instance of the class passed as the second argument. + +```py +isinstance(7, int) # True +``` + +Another thing you want to check is that every argument is a number. After your first `if`, create a `for` loop that iterates over `args` and checks if the argument at the current iteration is not an instance of `int` or `float`. Use the `isinstance()` function and pass it a tuple containing `int` and `float` as the second argument. + +If the argument is not a number, raise a `TypeError` saying `"Coefficients must be of type 'int' or 'float'"`. + +# --hints-- + +You should create a `for` loop that iterates over `args` after your `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_iter().is_equivalent("args")`)) }) +``` + +You should create an `if` statement that checks if the current coefficient is not an instance of either `int` or `float` within the `for` loop. + +```js +({ test: () => assert(runPython(` +var = str(_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_for_vars()) +cond1 = f'not isinstance({var}, (int, float))' +cond2 = f'not isinstance({var}, (float, int))' +if_stmt = _Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +if_stmt.is_equivalent(cond1) or if_stmt.is_equivalent(cond2) +`)) }) +``` + +You should use the provided string to raise a `TypeError` within the `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md new file mode 100644 index 00000000000..1e53fa4d25f --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639f947d3a1818c9322c64a.md @@ -0,0 +1,74 @@ +--- +id: 6639f947d3a1818c9322c64a +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +The last step of validating the coefficients is checking that the highest degree coefficient is different from zero. Remember that the highest degree coefficient should be passed as the first argument when instantiating the object. + +Add an `if` statement for that and raise a `ValueError` using the following string to provide a custom message: `'Highest degree coefficient must be different from zero'`. + +# --hints-- + +You should create an `if` statement that checks if the first coefficient passed to instantiate the equation is equal to zero. + +```js +({ test: () => assert(runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_conditions()[0] +cond.is_equivalent("args[0] == 0") or cond.is_equivalent("0 == args[0]") or cond.is_equivalent("not args[0]") +`)) }) +``` + +You should raise a `ValueError` within the new `if` statement and use the provided string to return a custom error message. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[2].find_bodies()[0].has_stmt("raise ValueError('Highest degree coefficient must be different from zero')") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md new file mode 100644 index 00000000000..246baa90993 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6639fdcc701833a54c364211.md @@ -0,0 +1,94 @@ +--- +id: 6639fdcc701833a54c364211 +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +After validating the coefficients, you need to store them in an instance attribute. Use a dictionary comprehension to create a dictionary in which the key is the degree of the coefficient and the corresponding value is the coefficient, and assign it to an attribute named `coefficients`. + +For example, a `LinearEquation` object instantiated with `2` and `4` should have the following `coefficients` attribute: `{1: 2, 0: 4}`, because `2` corresponds to the first degree of `x` and `4` corresponds to zero-th degree of `x`. + +Create the key-value pairs in your new dictionary following the same order as in `args`. + +# --hints-- + +You should declare an attribute named `coefficients` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_variable("self.coefficients")`)) }) +``` + +You should use a dictionary comprehension to store your coefficients. + +```js +({ test: () => runPython(` +import ast +node = _Node(_code).find_class("Equation").find_function("__init__").find_variable("self.coefficients") +assert isinstance(node.tree.value, ast.DictComp) +`) }) +``` + +Your `coefficients` attribute should be a dictionary containing key-value pairs in the form degree-coefficient. Remember to follow the same order in which coefficients are stored inside `args`. + +```js +({ test: () => runPython(` +actual1 = list(LinearEquation(1, 6).coefficients.items()) +expected1 = list({1: 1, 0: 6}.items()) +actual2 = list(LinearEquation(-3.5, 0).coefficients.items()) +expected2 = list({1: -3.5, 0: 0}.items()) +assert actual1 == expected1 +assert actual2 == expected2 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") +--fcc-editable-region-- + +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md new file mode 100644 index 00000000000..05a88ba37c3 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a22ba7420c4d2f7fd2aec.md @@ -0,0 +1,96 @@ +--- +id: 663a22ba7420c4d2f7fd2aec +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +It's time to implement the `solve` method. Given a linear equation in the form \\( ax + b = 0 \\), the solution is \\(x = -\frac{b}{a}\\). + +Unpack the coefficients stored in the `coefficients` attribute into the variables `a` and `b`. Note that you'll need to use the `.values()` method. + +Then, declare a variable `x`, assign it the solution of the equation and return it from the `solve` method. + +# --hints-- + +You should unpack the values stored inside the `coefficients` attribute into the variables `a` and `b`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("a, b = self.coefficients.values()")`)) }) +``` + +You should declare a variable named `x` and assign it the solution of the linear equation. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_stmt("x = -b/a")`)) }) +``` + +You should return `x` from your `solve` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("x")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+').strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 +--fcc-editable-region-- + def solve(self): + pass +--fcc-editable-region-- + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md new file mode 100644 index 00000000000..594daf44dd7 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a2dd1901cbeecc28748bd.md @@ -0,0 +1,83 @@ +--- +id: 663a2dd1901cbeecc28748bd +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +It's time to test the `solve` method. Call it on `lin_eq` and print the result. + +# --hints-- + +You should call the `solve` method of your `lin_eq` object and print the result. + +```js +({ test: () => assert(runPython(` +_Node(_code).has_call("print(lin_eq.solve())") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md new file mode 100644 index 00000000000..91bdcb2dcbe --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663a32735b317af9812eb0d7.md @@ -0,0 +1,106 @@ +--- +id: 663a32735b317af9812eb0d7 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +In linear equations in the form \\( ax + b = 0 \\), the slope is simply the coefficient \\( a \\), and the y-intercept is the coefficient \\( b \\). + +a plot of a linear function + +You are going to use the `analyze` method to provide additional information about the equation. Inside the `analyze` method, unpack the coefficients into the variables `slope` and `intercept`. + +Then, return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. After that, call `analyze` on `lin_eq` and print the result. + + +# --hints-- + +You should unpack the values stored in the `coefficients` attribute into the variables `slope` and `intercept` inside the `analyze` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("analyze").has_stmt("slope, intercept = self.coefficients.values()")`)) }) +``` + +The `analyze` method should return a dictionary with the keys `'slope'` and `'intercept'` and the values of the slope and the y-intercept, respectively. + +```js +({ test: () => runPython(` +eq = LinearEquation(2.2, 1.5) +a = eq.analyze() +assert a['slope'] == 2.2, "Expected different slope" +assert a['intercept'] == 1.5, "Expected different intercept" +`) }) +``` + +You should call the `analyze` method of your `lin_eq` object. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq.analyze())")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x +--fcc-editable-region-- + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +print(lin_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md new file mode 100644 index 00000000000..b7d80398ff5 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b7fefd437bd984e091cbf.md @@ -0,0 +1,116 @@ +--- +id: 663b7fefd437bd984e091cbf +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +Next, create a new class named `QuadraticEquation` and make it inherit from `Equation`. You'll use this new class to represent quadratic equations, which are second-degree equations having the form $ax^2 + bx + c = 0$. + +Inside your new class, define a `degree` class attribute with the value `2`, which is the degree of a quadratic equation. Also, define the `solve` and `analyze` methods. You will take care of the implementation in the following steps. + +# --hints-- + +You should create a new class named `QuadraticEquation` and make it inherit from the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").inherits_from("Equation")`)) }) +``` + +You should define a `solve` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("solve")`)) }) +``` + +Your `solve` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").has_args("self")`)) }) +``` + +You should define an `analyze` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("analyze")`)) }) +``` + +Your `analyze` method should take a single parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("analyze").has_args("self")`)) }) +``` + +You should define a `degree` class attribute within the `QuadraticEquation` class and assign it the value `2`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_variable("degree").is_equivalent("degree = 2")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md new file mode 100644 index 00000000000..62c12ba631f --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b83a28943e6aa6275a514.md @@ -0,0 +1,97 @@ +--- +id: 663b83a28943e6aa6275a514 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +Still within the `Equation` class, define a `__str__` method to give a proper string representation to the equation objects you are going to create. + +For now, within the `__str__` method, declare a variable `terms` and assign it an empty list. You'll use this variable to store each term (coefficient times \\( x^n \\)) of your equation. + +Then, declare a variable `equation_string`, assign it the result of joining the elements in the `terms` list with a space. Finally, return `equation_string`. + +# --hints-- + +You should define a `__str__` method within the `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_function("__str__")`)) }) +``` + +Your `__str__` method should take one parameter, `self`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_args("self")`)) }) +``` + +You should declare a variable `terms` and assign it an empty list within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("terms = []")`)) }) +``` + +You should declare a variable `equation_string` and assign it the result of joining the elements in `terms` with a space within the `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_stmt("equation_string = ' '.join(terms)")`)) }) +``` + +You should return `equation_string` from your `__str__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("equation_string")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md new file mode 100644 index 00000000000..a950eeb6c51 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b93aee129b3c4cc07d0db.md @@ -0,0 +1,110 @@ +--- +id: 663b93aee129b3c4cc07d0db +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Just after the `terms` list, create a `for` loop and use the `.items()` method to iterate over the keys and values stored in the `coefficients` attribute. Use `n` and `coefficient` as the loop variables. + +Inside the loop, create an `if` statement that checks if the coefficient at the current iteration has a falsy value and skip the iteration in that case. This is because you don't want to represent coefficients with the value of zero. + +# --hints-- + +You should create a `for` loop that iterates over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_iter().is_equivalent("self.coefficients.items()")`)) }) +``` + +Your `for` loop should use `n` and `coefficient` to iterate over `coefficients.items()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_for_vars().is_equivalent("n, coefficient")`)) }) +``` + +You should create an `if` statement to check if `coefficient` has a falsy value inside your `for` loop. + +```js +({ test: () => assert(runPython(` +if_cond = _Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_conditions()[0] +conditions = ["not coefficient", "coefficient == 0", "0 == coefficient"] +any(if_cond.is_equivalent(condition) for condition in conditions) +`)) }) +``` + +You should use the `continue` keyword inside your new `if` statement. + +```js +({ test: () => assert(runPython(` +_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[0].find_bodies()[0].has_stmt("continue") +`)) }) +``` + +Your `for` loop should be placed just after the declaration of `terms`. + +```js +({ test: () => assert(runPython(` +loop = str(_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0]) +_Node(_code).find_class("Equation").find_function("__str__").is_ordered("terms = []", loop, "equation_string = ' '.join(terms)", "return equation_string") +`)) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + +--fcc-editable-region-- + equation_string = ' '.join(terms) + return equation_string + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md new file mode 100644 index 00000000000..354e5eff2ac --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663b95d65caeb3ca04c5fef4.md @@ -0,0 +1,82 @@ +--- +id: 663b95d65caeb3ca04c5fef4 +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +If the coefficient has a non-zero value, you can have different cases. If `n == 0`, the term is made by the coefficient itself. + +After your `if` statement, create another `if` statement for this case and append a string containing the coefficient to the `terms` list. Use an f-string for that. + +# --hints-- + +You should create an `if` statement to check if `n` is equal to `0` after your existing `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[0].is_equivalent("n==0")`)) }) +``` + +You should append `f'{coefficient}'` to the `terms` list within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md new file mode 100644 index 00000000000..f670c2b02ba --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c981b9b06922e13a97fe9.md @@ -0,0 +1,84 @@ +--- +id: 663c981b9b06922e13a97fe9 +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +Create an `elif` clause for the case `n == 1`. Within the `elif` clause, create an f-string containing the coefficient directly followed by a lowercase `x` and append it to the `terms` list. + +# --hints-- + +You should create an `elif` clause to check if `n` is equal to `1`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[1].is_equivalent("n==1")`)) }) +``` + +You should append `f'{coefficient}x'` to the `terms` list within your new `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md new file mode 100644 index 00000000000..ce38ba0718e --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/663c9f31306353460da54542.md @@ -0,0 +1,86 @@ +--- +id: 663c9f31306353460da54542 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +As you can see, the `+` sign is missing from the output. The number sign is displayed by default only if negative. To change this behaviour, you can write a colon after the expression to be evaluated within the curly braces of your f-string, and specify the option `+`. This will allow you to display the sign both for positive and negative numbers. + +Modify the string in your two conditional clauses by adding `:+` inside the curly braces after `coefficient`. + +# --hints-- + +You should modify the string to append to the `terms` list within your `if` statement into `f'{coefficient:+}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[0].is_equivalent("terms.append(f'{coefficient:+}')")`)) }) +``` + +You should modify the string to insert into the `terms` list within your `elif` clause into `f'{coefficient:+}x'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[1].is_equivalent("terms.append(f'{coefficient:+}x')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) +--fcc-editable-region-- + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient}') + elif n == 1: + terms.append(f'{coefficient}x') + equation_string = ' '.join(terms) + return equation_string +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md new file mode 100644 index 00000000000..14d18f57d55 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664c670069bae45fd060c25d.md @@ -0,0 +1,66 @@ +--- +id: 664c670069bae45fd060c25d +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +Next, print your `lin_eq` instance. + +# --hints-- + +You should print `lin_eq`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(lin_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md new file mode 100644 index 00000000000..a009e7ed8fc --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664cb04a16fe6938708967ef.md @@ -0,0 +1,87 @@ +--- +id: 664cb04a16fe6938708967ef +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +After joining the terms, concatenate the string `' = 0'` to `equation_string` to display the complete equation. + +Also, to refine the output, remove any leading `+` sign from `equation_string`. + +# --hints-- + +The `__str__` method should return a different string representation. + +```js +({ test: () => assert(runPython(` +eq1 = LinearEquation(4, 2) +str(eq1) == '4x +2 = 0' +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + continue + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') +--fcc-editable-region-- + equation_string = ' '.join(terms) + + return equation_string +--fcc-editable-region-- + + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md new file mode 100644 index 00000000000..30cb8685989 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4a590b52ba8d2adff19f.md @@ -0,0 +1,116 @@ +--- +id: 664e4a590b52ba8d2adff19f +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The discriminant of a quadratic equation in the form \\( ax^2 + bx + c = 0 \\), usually indicated by the capital Greek letter delta, is equal to \\( Δ = b^2 - 4ac \\). + +Within the `QuadraticEquation` class, define an `__init__` method. Use `super()` to call the `__init__` method from the parent class. Then, define a new attribute named `delta`, which stores the value of the discriminant of the equation. + +# --hints-- + +You should define an `__init__` method within the `QuadraticEquation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_function("__init__")`)) }) +``` + +Your `__init__` method should take two parameters, `self` and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_args("self, *args")`)) }) +``` + +You should call `super().__init__(*args)` within your `__init__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("__init__").has_call("super().__init__(*args)")`)) }) +``` + +You should declare a `delta` attribute within your `__init__` method and assign it the value of the discriminant of the equation. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(2, -3, -4) +assert eq.delta == 41 +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 +--fcc-editable-region-- + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md new file mode 100644 index 00000000000..a6f25390538 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664e4e1b6c35a99cbba49e84.md @@ -0,0 +1,105 @@ +--- +id: 664e4e1b6c35a99cbba49e84 +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +Now, create an instance of the `QuadraticEquation` class to represent the equation \\( 11x^2 - x + 1 = 0 \\). + +Assign the new instance to a variable `quadr_eq`, then print your new variable. Note that, at this point, the second degree term would be missing from the string representation of the equation. + +# --hints-- + +You should declare a variable named `quadr_eq` and assign it an instance of `QuadraticEquation` passing it `11`, `-1`, and `1` as the arguments. + +```js +({ test: () => assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(11, -1, 1)")`)) }) +``` + +You should print your `quadr_eq` variable. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(quadr_eq)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md new file mode 100644 index 00000000000..cb13649f25e --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ee8037f4bbe3c0944c35e.md @@ -0,0 +1,110 @@ +--- +id: 664ee8037f4bbe3c0944c35e +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +As you can see, the second-degree term is missing from the string representation. Within the `__str__` method, create an `else` clause to handle the case in which the exponent of \\( x \\) is greater than `1`. + +Append a string to the `terms` list so that the term is represented as `x**`. Display the number sign both for positive and negative coefficients and make sure that the inserted string is suitable to represent equations of degree > 2, too. + +# --hints-- + +You should create an `else` clause after your existing `elif` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_conditions()[2].is_empty()`)) }) +``` + +You should append `f'{coefficient:+}x**{n}'` to the `terms` list within your new `else` clause. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").find_for_loops()[0].find_ifs()[1].find_bodies()[2].is_equivalent("terms.append(f'{coefficient:+}x**{n}')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient +--fcc-editable-region-- + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + +--fcc-editable-region-- + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md new file mode 100644 index 00000000000..d8e26443b9d --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eec7f38234443b42c206f.md @@ -0,0 +1,105 @@ +--- +id: 664eec7f38234443b42c206f +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +Your equation is currently represented as `11x**2 -1x +1 = 0`, but it would be nice not to display the coefficient multiplying \\( x \\) when it's equal to one. So that equation is represented as `11x**2 -x +1 = 0`. + +Import the `re` module. You are going to use a regular expression to substitute the coefficients for this case during the next steps. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert(runPython(`_Node(_code).has_import("import re")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +--fcc-editable-region-- + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md new file mode 100644 index 00000000000..eabae3cd1d6 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664eef158d792a509e8d708a.md @@ -0,0 +1,114 @@ +--- +id: 664eef158d792a509e8d708a +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +The `sub` function from the `re` module enables you to replace text inside a string based on a regex pattern. + +```py +verse = 'Always look on the bright side of life' +spam = re.sub('bright', 'spam', verse) +spam == 'Always look on the spam side of life' # True +``` + +It takes three arguments: the regex pattern to match, the replacement, and the string on which you want to perform the replacement. + +From your `__str__` function, return a `sub()` call passing the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments. This will replace each `1` with an empty string. The result is not refined yet and you'll continue to work on the regex pattern in the next steps. + +# --hints-- + +You should return a `re.sub()` call from your `__str__` method. Pass the string `'1'`, an empty string, and your existing `equation_string.strip('+')` call as the arguments to `re.sub()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub('1', '', equation_string.strip('+'))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' +--fcc-editable-region-- + return equation_string.strip('+') +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + +class QuadraticEquation(Equation): + degree = 2 + + def __init__(self, *args): + super().__init__(*args) + a, b, c = self.coefficients.values() + self.delta = b**2 - 4 * a * c + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(11, -1, 1) +print(quadr_eq) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md new file mode 100644 index 00000000000..b525da7b4a8 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/664ef4623946e65e18d59764.md @@ -0,0 +1,124 @@ +--- +id: 664ef4623946e65e18d59764 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +In a regex pattern, a *lookaround* is an assertion that matches a certain pattern without consuming characters in the string. One kind of lookaround is the lookbehind, which can be either positive or negative. They are denoted by `(?<=...)` and `(? assert(runPython(` +node = _Node(_code).find_class("Equation").find_function("__str__") +values = [ + "re.sub('(? assert(runPython(`_Node(_code).find_class("Equation").find_function("__str__").has_return("re.sub(r'(? assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_conditions()[0].is_equivalent("self.delta < 0")`)) }) +``` + +You should return an empty list from your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[0].find_bodies()[0].has_return("[]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(-1, 2, 3) +assert eq.solve() == [-1, 3] or eq.solve() == [3, -1] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_call("print(quadr_eq.solve())") or _Node(_code).has_call("print(quadr_eq.solve(), quadr_eq.results)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(-11, -1, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).has_stmt("quadr_eq = QuadraticEquation(1, 2, 1)")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +node = _Node(_code).find_class("QuadraticEquation").find_function("solve").find_ifs()[1].find_conditions()[0] +node.is_equivalent("self.delta == 0") or node.is_equivalent("not self.delta") +`)) }) +``` + +You should return a list containing the root within your new `if` statement. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(4, 4, 1) +assert eq.solve() == [-0.5] +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(`_Node(_code).find_class("LinearEquation").find_function("solve").has_return("[x]")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? runPython(` +eq = QuadraticEquation(16, 2, 1) +assert eq.analyze() == {'x': -0.0625, 'y': 0.9375} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? + +Declare a `concavity` variable and assign it either the string `'upwards'` or `'downwards'`, depending on the concavity of the parabola. Also, declare a variable named `min_max` and assign it either the string `'min'` or `'max'`, depending on if the vertex is a minimum or a maximum, respectively. + +Finally, add the dictionary to return two keys `'min_max'` and `'concavity'` with the values of `min_max'` and `concavity`, respectively. + +# --hints-- + +Your `analyze` method should return a dictionary with four keys, `'x'`, `'y'`, `'min_max'`, and `'concavity'` and the values of `x`, `y`, `min_max`, and `concavity`, respectively. + +```js +({ test: () => runPython(` +eq1 = QuadraticEquation(16, 2, 1) +eq2 = QuadraticEquation(-16, 2, 1) +assert eq1.analyze() == {'x': -0.0625, 'y': 0.9375, 'min_max': 'min', 'concavity': 'upwards'} +assert eq2.analyze() == {'x': 0.0625, 'y': 1.0625, 'min_max': 'max', 'concavity': 'downwards'} +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? assert(runPython(` +_Node(_code).find_calls("print") == []`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +print(lin_eq) +quadr_eq = QuadraticEquation(1, 2, 1) +print(quadr_eq) +print(quadr_eq.solve()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md new file mode 100644 index 00000000000..9a649cdc2a8 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66558720bbe6e038315b7f81.md @@ -0,0 +1,121 @@ +--- +id: 66558720bbe6e038315b7f81 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +Next, you are going to create a function that will trigger the instance methods you wrote to solve the equation. Also, it will display the results in a formatted output. + +Outside the classes, create a new function named `solver` that takes a single parameter, `equation`. + +# --hints-- + +You should define a function named `solver` that takes a single parameter, `equation`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_args("equation")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- + +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md new file mode 100644 index 00000000000..0a4163d5396 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665621ef85db565d26632761.md @@ -0,0 +1,126 @@ +--- +id: 665621ef85db565d26632761 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +Within your new function, create an `if` statement that checks if `equation` is not an instance of the `Equation` class and raise a `TypeError` using the string `'Argument must be an Equation object'` to provide a custom message. + +# --hints-- + +You should create an `if` statement to check if `equation` is not an instance of the `Equation` class within your `solver` function. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(equation, Equation)")`)) }) +``` + +You should raise a `TypeError` with the provided string within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_ifs()[0].find_bodies()[0].has_stmt("raise TypeError('Argument must be an Equation object')")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + pass +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md new file mode 100644 index 00000000000..be7a851ae3c --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66562f71937f877c66123bbe.md @@ -0,0 +1,152 @@ +--- +id: 66562f71937f877c66123bbe +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +The first thing to display at the top of the output will be the equation type. Add a class attribute named `type` to the `Equation` class and annotate it with `str`. + +Then, add another `if` statement to the `__init_subclass__` method to check if the classes inheriting from `Equation` have the `type` attribute. Use the same format of the existing `if` statement with the appropriate modifications. + +Finally, add the new class attribute to the `LinearEquation` class and to the `QuadraticEquation` class. Assign it the string `'Linear Equation'` and the string `'Quadratic Equation'`, respectively. + +# --hints-- + +You should define a class variable named `type` within the `Equation` class and annotate it with `str`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").has_stmt("type: str")`)) }) +``` + +You should create an `if` statement that checks if `cls` does not have the attribute `type` inside the `__init_subclass__` method and raise an `AttributeError` using the provided string. + +```js +({ test: () => assert(runPython(` +if_str = """ +if not hasattr(cls, 'type'): + raise AttributeError( + f\\"Cannot create '{cls.__name__}' class: missing required attribute 'type'\\" + ) +""" +_Node(_code).find_class("Equation").find_function("__init_subclass__").has_stmt(if_str) +`)) }) +``` + +The `type` attribute of the `LinearEquation` class shouls have the value `'Linear Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("LinearEquation").has_stmt("type = 'Linear Equation'")`)) }) +``` + +The `type` attribute of the `QuadraticEquation` class should have the value `'Quadratic Equation'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("QuadraticEquation").has_stmt("type = 'Quadratic Equation'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + +--fcc-editable-region-- +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md new file mode 100644 index 00000000000..817a0d5924b --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/665ee783d35cb68875c626d4.md @@ -0,0 +1,89 @@ +--- +id: 665ee783d35cb68875c626d4 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +Now, remove both the `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls from your code. + +# --hints-- + +You should remove both your `print(lin_eq.solve())` and `print(lin_eq.analyze())` calls. + +```js +({ test: () => runPython(` +assert not _Node(_code).has_call("print(lin_eq.analyze())") +assert not _Node(_code).has_call("print(lin_eq.solve())") +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + equation_string = ' '.join(terms) + ' = 0' + return equation_string.strip('+') + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + a, b = self.coefficients.values() + x = -b / a + return x + + def analyze(self): + slope, intercept = self.coefficients.values() + return {'slope': slope, 'intercept': intercept} + + +lin_eq = LinearEquation(2, 3) +print(lin_eq) +--fcc-editable-region-- +print(lin_eq.solve()) +print(lin_eq.analyze()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md new file mode 100644 index 00000000000..0142477a03a --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66759e32b88fb5459b1e0234.md @@ -0,0 +1,56 @@ +--- +id: 66759e32b88fb5459b1e0234 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `__init_subclass__` method is called whenever the class that defines it is subclassed and it enables to customize the child classes. The method takes a parameter named by convention `cls` (standing for "class"), which represents the new child class. + +Define an `__init_subclass__` method in your `Equation` class and give it a `cls` parameter. + +# --hints-- + +You should define an `__init_subclass__` method with a `cls` parameter in your `Equation` class. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").has_args("cls")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + +--fcc-editable-region-- + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md new file mode 100644 index 00000000000..cbadf97b11e --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675a38a8b535e4ff3274520.md @@ -0,0 +1,73 @@ +--- +id: 6675a38a8b535e4ff3274520 +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +The `hasatttr` built-in function takes an object as its first argument and a string representing an attribute name as its second argument. It returns a boolean indicating if the object has the specified attribute. + +Now you are going to use the `__init_subclass__` method to check if the child class has the `degree` attribute at the moment of the instantiation. + +Create an `if` statement to check if `cls` does not have a `degree` attribute. If so, raise an `AttributeError` and use the string `f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'"` to provide a custom message. + +After that, fix the error that has appeared in the terminal by declaring a `degree` class attribute inside the `LinearEquation` class. This attribute should represent the degree of the equation, which is the exponent of the highest \\( x \\) term. Therefore, assign the integer `1` to the `degree` atttribute. + +# --hints-- + +You should create an `if` statement that checks if `cls` does not have the attribute `degree` inside the `__init_subclass__` method. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_conditions()[0].is_equivalent("not hasattr(cls, 'degree')")`)) }) +``` + +You should raise an `AttributeError` using the provided string inside your `if` statement. + +```js +({ test: () => runPython(` +raise_stmt = 'raise AttributeError(f"Cannot create \\'{cls.__name__}\\' class: missing required attribute \\'degree\\'")' +node = _Node(_code).find_class("Equation").find_function("__init_subclass__").find_ifs()[0].find_bodies()[0] +assert node.has_stmt(raise_stmt) +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + pass + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + +--fcc-editable-region-- + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md new file mode 100644 index 00000000000..dea055bffe4 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6675aaf418b41157f6ccd692.md @@ -0,0 +1,62 @@ +--- +id: 6675aaf418b41157f6ccd692 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +It's time to go back to the `__init__` method. Depending on the equation type, you'll need to pass a variable number of arguments during the instantiation. + +Add a second parameter `args` to the method and use the `*` operator to make it accept a variable number of arguments. + +# --hints-- + +Your `__init__` method should take two parameters, `self`, and `*args`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").has_args("self, *args")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int +--fcc-editable-region-- + def __init__(self): + pass +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + + +lin_eq = LinearEquation() +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md new file mode 100644 index 00000000000..7a8fd5412dc --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667938f754145d165c25725d.md @@ -0,0 +1,153 @@ +--- +id: 667938f754145d165c25725d +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +An interesting feature of f-strings is the capability of forcing the output to be right/left-aligned, or centered. After the expression to be evaluated is inside the curly braces, you need to write a colon followed by an alignment option (`<` to left-align, `>` to right-align, `^` to center) and a number representing the width, that is the number of characters in which you want to arrange the text. For example: + +```py +f'{"Hello World":>20}' +``` + +Printing the string from the example above would result in right-aligned text arranged in a space of 20 characters. + +Back to the `solver` function, after your `if` statement, create a variable named `output_string` and assign it an f-string containing the equation type centered in a width of `24` characters. Make the string begin with a new line character, and return `output_string` from your function. + +Then, call the `solver` function passing `lin_eq` as the argument, and print the result. + +# --hints-- + +You should define a variable named `output_string` and assign it `f'\n{equation.type:^24}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:^24}'")`)) }) +``` + +Your `solver` function should return `output_string`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_return("output_string")`)) }) +``` + +You should print `solver(lin_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} +--fcc-editable-region-- +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md new file mode 100644 index 00000000000..a87dd80888e --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793a552f357b17006a8726.md @@ -0,0 +1,138 @@ +--- +id: 66793a552f357b17006a8726 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Between the colon and the alignment option, you can specify a fill character, which will be used to fill the space around the text within the specified width. + +Add a `-` between the colon and the `^` in your f-string. + +# --hints-- + +You should add a `-` character between the colon and the `^` in your f-string. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("output_string = f'\\\\n{equation.type:-^24}'")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:^24}' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md new file mode 100644 index 00000000000..9851356bcbc --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793c5b4bdacc17c40ff8e7.md @@ -0,0 +1,150 @@ +--- +id: 66793c5b4bdacc17c40ff8e7 +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Another feature of f-strings enables you to convert the content of the replacement field (the curly braces) into a string by using a `!` followed by the conversion type `s`. For example, `f'{obj!s}'` converts `obj` into a string and it is equivalent to `f'{str(obj)}'`. + +From now on, you'll keep building the output by concatenating strings to `output_string`. + +Create a string containing the string representation of your equation centered in a width of `24` characters. Make the string begin and end with two newline characters, and add your new string to the current value of `output_string`. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md new file mode 100644 index 00000000000..792e99bb3dd --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66793d1e1581681871635ac6.md @@ -0,0 +1,149 @@ +--- +id: 66793d1e1581681871635ac6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Add a new piece to your `output_string` formed by the string `'Solutions'` centered in a width of 24 characters. Use a `-` as a fill character, and make the string end with two new line characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md new file mode 100644 index 00000000000..8a2b0347810 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66794346ddfa141cbe70093a.md @@ -0,0 +1,139 @@ +--- +id: 66794346ddfa141cbe70093a +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +Now, call the `solve()` method of `equation` and assign the result a variable named `results`. + +# --hints-- + +You should declare a variable `results` and assign it the result of calling `equation.solve()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("results = equation.solve()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") +--fcc-editable-region-- + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md new file mode 100644 index 00000000000..2125a296a4e --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667944fed1f6b61da3406bd8.md @@ -0,0 +1,164 @@ +--- +id: 667944fed1f6b61da3406bd8 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Structural pattern matching is a Python construct that enables matching a pattern with a subject value, which is specified after the `match` keyword: + +```py +match value: + case x: + + case y: + +``` + +Each pattern is specified after the `case` statement. If the match is positive, the code inside the `case` block is run. + +Use the `match`/`case` syntax to check the length of `results`. In case the length is `0`, assign a list containing the string `'No real roots'` to a variable named `result_list`. + +# --hints-- + +You should create a `match`/`case` construct using `len(results)` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should create a new `case` with the pattern `0`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("0")`)) }) +``` + +You should assign a list containing `'No real roots'` to `result_list` inside the `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' +--fcc-editable-region-- + results = equation.solve() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md new file mode 100644 index 00000000000..20249ffa187 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799278873fd2570217bffa.md @@ -0,0 +1,165 @@ +--- +id: 66799278873fd2570217bffa +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +Add another `case` for when the length of `results` is `1`. In this case, assign to `result_list` a list containing a string with the format `x = `, where `` is the solution of the equation. Format the string so that both positive and negative sign are displayed for the solution. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("0") +assert case.find_case_body().is_equivalent("result_list = ['No real roots']") +`) }) +``` + +You should create a new `case` with the pattern `1` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("1")`)) }) +``` + +You should assign a list containing `f'x = {results[0]:+}'` to `result_list` inside your new `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md new file mode 100644 index 00000000000..cd7723a4b48 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679934707d5fe577f898efd.md @@ -0,0 +1,170 @@ +--- +id: 6679934707d5fe577f898efd +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Add another case for when the length of `results` is `2`. This time, assign `result_list` a list containing two strings with the format `x1 = ` and `x2 = `. Again, make the solution display both positive and negative signs. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("len(results)")`)) }) +``` + +You should not modify your existing `case` blocks. + +```js +({ test: () => runPython(` +case0 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0] +assert case0.find_case_pattern().is_equivalent("0") +assert case0.find_case_body().is_equivalent("result_list = ['No real roots']") +case1 = _Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1] +assert case1.find_case_pattern().is_equivalent("1") +assert case1.find_case_body().is_equivalent("result_list = [f'x = {results[0]:+}']") +`) }) +``` + +You should create a new `case` with the pattern `2` after the existing `case` block. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("2")`)) }) +``` + +You should assign a list containing two strings with the format `x1 = ` and `x2 = ` to `result_list` inside your new `case` body. Display both positive and negative signs for the results. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md new file mode 100644 index 00000000000..48d17a5c390 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799ba07c5fd58a61a604d3.md @@ -0,0 +1,159 @@ +--- +id: 66799ba07c5fd58a61a604d3 +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +After your `match`/`case` block, iterate through `result_list` and concatenate each element to `output_string`. Keep aligning the text to the center and make each result string end with a new line character. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.75 +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md new file mode 100644 index 00000000000..152b1676683 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/66799c1a0204668cef35555d.md @@ -0,0 +1,157 @@ +--- +id: 66799c1a0204668cef35555d +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +f-strings also enable you to set a specific precision to your numerical data by using the `.nf` format specifier, where `n` is the number of decimal digits to display. + +Within the curly braces of the f-strings contained inside `result_list`, write the format specifier needed to display `3` decimal digits just after the `:+`. + +# --hints-- + +You should modify the string contained in `result_list` in your `case 1` block into `f'x = {results[0]:+.3f}'`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {results[0]:+.3f}']")`)) }) +``` + +You should modify the strings contained in `result_list` in your `case 2` block so that the results are displayed with `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+}'] + case 2: + result_list = [f'x1 = {results[0]:+}', f'x2 = {results[1]:+}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md new file mode 100644 index 00000000000..6f36d12d9d9 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bf00da92e5c0db0ffdc3.md @@ -0,0 +1,164 @@ +--- +id: 6679bf00da92e5c0db0ffdc3 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Right after your `for` loop, add another piece to your output. Create a string having the text `Details` centered. Use a `-` as a fill character and make your string begin with a single newline character and end with two newline characters. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(4, 3) +expected = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md new file mode 100644 index 00000000000..be61f2d2802 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/6679bfe40a6d77c6a3c17e06.md @@ -0,0 +1,150 @@ +--- +id: 6679bfe40a6d77c6a3c17e06 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +Now, call the `analyze` method of `equation` and assign the result to a new variable named `details`. + +# --hints-- + +You should declare a variable `details` and assign it the result of calling `equation.analyze()`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").has_stmt("details = equation.analyze()")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' +--fcc-editable-region-- + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md new file mode 100644 index 00000000000..14be1277b8b --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a7ce2a9925416e7b4781b.md @@ -0,0 +1,197 @@ +--- +id: 667a7ce2a9925416e7b4781b +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +The structural pattern matching enables you to verify that the subject has a specific structure. In addition to that, it binds names in the pattern to elements of the subject. For example: + +```py +match my_list: + case [a]: + print(a) + case [a, b]: + print(a, b) +``` + +Modify your `match`/`case` construct to match `results` instead of `len(results)`. Then, modify each `case` to use a list with the appropriate number of elements. Use `x` for the case the list contains a single element, and `x1` and `x2` for the case the list contains two elements. + +Finally, modify the f-strings to use the variable names used in each `case`. + +# --hints-- + +You should modify your `match` statement to use `results` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_subject().is_equivalent("results")`)) }) +``` + +You should modify your first `case` to use the pattern `[]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_pattern().is_equivalent("[]")`)) }) +``` + +You should not modify your first `case` body. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[0].find_case_body().is_equivalent("result_list = ['No real roots']")`)) }) +``` + +You should modify your second `case` to use the pattern `[x]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_pattern().is_equivalent("[x]")`)) }) +``` + +You should modify the f-string contained inside `result_list` to use `x` in place of `result[0]`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[1].find_case_body().is_equivalent("result_list = [f'x = {x:+.3f}']")`)) }) +``` + +You should modify your third `case` to use a list containing `x1` and `x2` as the pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_pattern().is_equivalent("[x1, x2]")`)) }) +``` + +You should modify the f-strings contained inside `result_list` to use the bound variables from your pattern. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[0].find_match_cases()[2].find_case_body().is_equivalent("result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() +--fcc-editable-region-- + match len(results): + case 0: + result_list = ['No real roots'] + case 1: + result_list = [f'x = {results[0]:+.3f}'] + case 2: + result_list = [f'x1 = {results[0]:+.3f}', f'x2 = {results[1]:+.3f}'] +--fcc-editable-region-- + for result in result_list: + output_string += f'{result:^24}\n' + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md new file mode 100644 index 00000000000..68458df93f3 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a860c3b61f61b7a18930c.md @@ -0,0 +1,168 @@ +--- +id: 667a860c3b61f61b7a18930c +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Create another `match`/`case` construct to match the value of the `details` variable. + +When the equation is linear, `details` is a dictionary having the form `{'slope': slope, 'intercept': intercept}`. Use it as the pattern for your first `case`. + +Then, inside the `case` block, declare a variable named `details_list` and assign it a list containing two strings having the form `slope = ` and `y-intercept = `, respectively. Format the strings to display `3` decimal digits. + +# --hints-- + +You should create a new `match` statement that uses `details` as the subject value. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should create a new `case` with the pattern `{'slope': slope, 'intercept': intercept}`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}")`)) }) +``` + +You should assign a list containing two f-strings having the form `slope = ` and `y-intercept = ` to `details_list` inside the `case` body. Remember to format the numerical values to display `3` decimal digits. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0].find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']")`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md new file mode 100644 index 00000000000..2c003da8995 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a8d7a735cf221729570ff.md @@ -0,0 +1,225 @@ +--- +id: 667a8d7a735cf221729570ff +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +Add another `case` for when the equation is quadratic. Use a dictionary with the same format returned by the `analyze` method of `QuadraticEquation`. + +Then, assign `details_list` a list containing two strings with the format `concavity = ` and ` = (, )`, respectively. Format `` and `` to display `3` decimal digits. + +Finally, after the `match`/`case` block, iterate through `details_list` and add each item to the current value of `output_string`. Make sure that each string item ends with a newline character. Do not use any additional format option here. + +# --hints-- + +You should not modify the subject value of your `match` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_matches()[1].find_match_subject().is_equivalent("details")`)) }) +``` + +You should not modify your existing `case` block. + +```js +({ test: () => runPython(` +case = _Node(_code).find_function("solver").find_matches()[1].find_match_cases()[0] +assert case.find_case_pattern().is_equivalent("{'slope': slope, 'intercept': intercept}") +assert case.find_case_body().is_equivalent("details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}']") +`) }) +``` + +You should create a new `case` block for when `equation` is a quadratic equation. + +```js +({ test: () => assert(runPython(`len(_Node(_code).find_function("solver").find_matches()[1].find_match_cases()) == 2`)) }) +``` + +You should create a `for` loop to iterate over `details_list`. + +```js +({ test: () => assert(runPython(`_Node(_code).find_function("solver").find_for_loops()[1].find_for_iter().is_equivalent("details_list")`)) }) +``` + +Your `solver` function should return a different string. + +```js +({ test: () => runPython(` +expected1 = """ +----Linear Equation----- + + 4x +3 = 0 + +-------Solutions-------- + + x = -0.750 + +--------Details--------- + +slope = 4.000 +y-intercept = 3.000 +""" +eq1 = LinearEquation(4, 3) +actual1 = solver(eq1) +assert expected1 == actual1 + +expected2 = """ +---Quadratic Equation--- + + x**2 -3x +1 = 0 + +-------Solutions-------- + + x1 = +2.618 + x2 = +0.382 + +--------Details--------- + +concavity = upwards +min = (1.500, -1.250) +""" +eq2 = QuadraticEquation(1, -3, 1) +actual2 = solver(eq2) +assert expected2 == actual2 +`) }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' +--fcc-editable-region-- + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] + +--fcc-editable-region-- + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md new file mode 100644 index 00000000000..a8d82d3b4a0 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a965d5a4b5825ffb2e1d8.md @@ -0,0 +1,196 @@ +--- +id: 667a965d5a4b5825ffb2e1d8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Modify the strings contained inside `details_list` to right-align the numerical values of the slope and the intercept. The final output should look like this: + +```py + +----Linear Equation----- + + 2x +3 = 0 + +-------Solutions-------- + + x = -1.500 + +--------Details--------- + +slope = 2.000 +y-intercept = 3.000 + +``` + +Note that the align option and the width should be placed between the colon and the precision format specifier. + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = LinearEquation(44, 3) +expected = """ +----Linear Equation----- + + 44x +3 = 0 + +-------Solutions-------- + + x = -0.068 + +--------Details--------- + +slope = 44.000 +y-intercept = 3.000 +""" +assert solver(eq) == expected, f'{solver(eq)}' +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: +--fcc-editable-region-- + details_list = [f'slope = {slope:.3f}', f'y-intercept = {intercept:.3f}'] +--fcc-editable-region-- + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + + return output_string + +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md new file mode 100644 index 00000000000..0ae7e702a1d --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667a9c91a87bb453a355b63d.md @@ -0,0 +1,173 @@ +--- +id: 667a9c91a87bb453a355b63d +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +Feel free to change the coefficients of your `lin_eq` to see how the output changes. + +Then, delete your `print(solver(lin_eq))` call, and print the result of calling `solver()` with `quadr_eq` as the argument. + +# --hints-- + +You should not have `print(solver(lin_eq))` in your code. + +```js +({ test: () => assert.isFalse(runPython(`_Node(_code).has_call("print(solver(lin_eq))")`)) }) +``` + +You should print `solver(quadr_eq)`. + +```js +({ test: () => assert(runPython(`_Node(_code).has_call("print(solver(quadr_eq))")`)) }) +``` + +# --hints-- + +Test 1 + +```js + +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +--fcc-editable-region-- +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(lin_eq)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md new file mode 100644 index 00000000000..42102e9c4c7 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667aa056f1240f58fb9a2c17.md @@ -0,0 +1,331 @@ +--- +id: 667aa056f1240f58fb9a2c17 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As a last step, modify the strings contained in `details_list` so that the text placed after the equal sign is right-aligned for each line. Your final output should look like this: + +```py + +---Quadratic Equation--- + + x**2 +2x +1 = 0 + +-------Solutions-------- + + x = -1.000 + +--------Details--------- + +concavity = upwards +min = (-1.000, 0.000) + +``` + +With that, the project is complete! + +# --hints-- + +The `solver` function should return a different string. + +```js +({ test: () => runPython(` +eq = QuadraticEquation(-4, 3, 2) +expected = """ +---Quadratic Equation--- + + -4x**2 +3x +2 = 0 + +-------Solutions-------- + + x1 = -0.425 + x2 = +1.175 + +--------Details--------- + +concavity = downwards +max = (0.375, 2.562) +""" +assert solver(eq) == expected +`) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept:>10.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' +--fcc-editable-region-- + details_list = [f'concavity = {concavity}', f'{min_max} = {coord}'] +--fcc-editable-region-- + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` + +# --solutions-- + +```py +from abc import ABC, abstractmethod +import re + + +class Equation(ABC): + degree: int + type: str + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'Equation' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) + if any(not isinstance(arg, (int, float)) for arg in args): + raise TypeError("Coefficients must be of type 'int' or 'float'") + if args[0] == 0: + raise ValueError("Highest degree coefficient must be different from zero") + self.coefficients = {(len(args) - n - 1): arg for n, arg in enumerate(args)} + + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + if not hasattr(cls, "type"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'type'" + ) + + def __str__(self): + terms = [] + for n, coefficient in self.coefficients.items(): + if not coefficient: + coefficient + if n == 0: + terms.append(f'{coefficient:+}') + elif n == 1: + terms.append(f'{coefficient:+}x') + else: + terms.append(f"{coefficient:+}x**{n}") + equation_string = ' '.join(terms) + ' = 0' + return re.sub(r"(? 0: + concavity = 'upwards' + min_max = 'min' + else: + concavity = 'downwards' + min_max = 'max' + return {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity} + + +def solver(equation): + if not isinstance(equation, Equation): + raise TypeError("Argument must be an Equation object") + + output_string = f'\n{equation.type:-^24}' + output_string += f'\n\n{equation!s:^24}\n\n' + output_string += f'{"Solutions":-^24}\n\n' + results = equation.solve() + match results: + case []: + result_list = ['No real roots'] + case [x]: + result_list = [f'x = {x:+.3f}'] + case [x1, x2]: + result_list = [f'x1 = {x1:+.3f}', f'x2 = {x2:+.3f}'] + for result in result_list: + output_string += f'{result:^24}\n' + output_string += f'\n{"Details":-^24}\n\n' + details = equation.analyze() + match details: + case {'slope': slope, 'intercept': intercept}: + details_list = [f'slope = {slope:>16.3f}', f'y-intercept = {intercept>10:.3f}'] + case {'x': x, 'y': y, 'min_max': min_max, 'concavity': concavity}: + coord = f'({x:.3f}, {y:.3f})' + details_list = [f'concavity = {concavity:>12}', f'{min_max} = {coord:>18}'] + for detail in details_list: + output_string += f'{detail}\n' + return output_string +lin_eq = LinearEquation(2, 3) +quadr_eq = QuadraticEquation(1, 2, 1) +print(solver(quadr_eq)) + +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md new file mode 100644 index 00000000000..36ddcef2f38 --- /dev/null +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-interfaces-by-building-an-equation-solver/667e623208053643ca9d3c6e.md @@ -0,0 +1,116 @@ +--- +id: 667e623208053643ca9d3c6e +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +Now, replace the `for` loop and `if` statement you added in the previous step with an `if` statement that uses the `any()` built-in function. + +# --hints-- + +The condition of your new `if` statement should be a call to `any()`. + +```js +({ test: () => runPython(` +cond = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0] +calls = _Node(str(cond)).find_calls("any") +assert len(calls) == 1 +`) }) +``` + +You should pass a generator expression as the argument to your `any()` call. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +assert isinstance(argument.tree, ast.GeneratorExp) +`) }) +``` + +The generator expression passed to `any()` should iterate over `args`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +iters = argument.find_comp_iters() +assert len(iters) == 1 +assert iters[0].is_equivalent("args") +`) }) +``` + +Your `if` statement should check if any of the arguments in `args` is not an instance of either `int` or `float`. + +```js +({ test: () => runPython(` +import ast +argument = _Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_conditions()[0].find_call_args()[0] +target = argument.find_comp_targets()[0] +expr = argument.find_comp_expr() +solutions = [ + f"not isinstance({target}, (int, float))", + f"not isinstance({target}, (float, int))", + f"not isinstance({target}, float) and not isinstance({target}, int)", + f"not isinstance({target}, int) and not isinstance({target}, float)", +] +assert any(expr.is_equivalent(sol) for sol in solutions) +`) }) +``` + +You should use the provided string to raise a `TypeError` within your new `if` statement. + +```js +({ test: () => assert(runPython(`_Node(_code).find_class("Equation").find_function("__init__").find_ifs()[1].find_bodies()[0].has_stmt("raise TypeError(\\"Coefficients must be of type 'int' or 'float'\\")") +`)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +from abc import ABC, abstractmethod + + +class Equation(ABC): + degree: int + + def __init__(self, *args): + if (self.degree + 1) != len(args): + raise TypeError( + f"'{self.__class__.__name__}' object takes {self.degree + 1} positional arguments but {len(args)} were given" + ) +--fcc-editable-region-- + for arg in args: + if not isinstance(arg, (int, float)): + raise TypeError("Coefficients must be of type 'int' or 'float'") +--fcc-editable-region-- + def __init_subclass__(cls): + if not hasattr(cls, "degree"): + raise AttributeError( + f"Cannot create '{cls.__name__}' class: missing required attribute 'degree'" + ) + + @abstractmethod + def solve(self): + pass + + @abstractmethod + def analyze(self): + pass + +class LinearEquation(Equation): + degree = 1 + + def solve(self): + pass + + def analyze(self): + pass + +lin_eq = LinearEquation(2, 3) +``` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md index c9e2224dad3..c5ec17d49b0 100644 --- a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601a8fb2e993b55912f9e9f.md @@ -7,17 +7,17 @@ dashedName: step-74 # --description-- -The dot product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: +The cross product between two 3D vectors \\( \mathbf{a} \\) and \\( \mathbf{b} \\) can be computed as it follows: \\[ \mathbf{a} \times \mathbf{b} = \begin{pmatrix} a_yb_z - a_zb_y \\\ a_zb_x - a_xb_z \\\ a_xb_y - a_yb_x \end{pmatrix} \\] Where the resulting vector is represented as a column vector. -Implement the formula above to compute the dot product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. +Implement the formula above to compute the cross product between two 3-dimensional vectors and return the resulting vector from the `cross()` method. # --hints-- -The `cross()` method should return a new `R3Vector` instance resulting from the dot product computation. +The `cross()` method should return a new `R3Vector` instance resulting from the cross product computation. ```js ({ test: () => assert(runPython(` diff --git a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md index 5b8e165be3e..faeebabea16 100644 --- a/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md +++ b/curriculum/challenges/ukrainian/07-scientific-computing-with-python/learn-special-methods-by-building-a-vector-space/6601ad0fe415985a5c83f3cc.md @@ -7,7 +7,7 @@ dashedName: step-77 # --description-- -As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the dot product. +As a final step, call the `print` function and pass it the f-string `f'v1 x v2 = {v6}'` to see the output of the cross product. With that, you have completed the vector space project. Хороша робота! diff --git a/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md index 08fcb3b91da..ca2d70d8a0a 100644 --- a/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md +++ b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-modern-javascript-methods-by-building-football-team-cards/63c620161fc2b49ac340ffc4.md @@ -7,7 +7,7 @@ dashedName: step-1 # --description-- -In this project, you will build a set of football team cards and learn about nested objects, object destructuring, default parameters, event listeners, and switch statements. Вам надано HTML та CSS для цього проєкту. +In this project, you will build a set of football team cards and learn about nested objects, object destructuring, and default parameters. Вам надано HTML та CSS для цього проєкту. Start by accessing the `id` called `"team"` from the HTML document and storing it in a `const` variable called `teamName`.