From 350f0f230d80533f066c85415888087e5c904e85 Mon Sep 17 00:00:00 2001 From: denisf2 <124052583+denisf2@users.noreply.github.com> Date: Mon, 18 Mar 2024 00:26:45 +0300 Subject: [PATCH 1/4] Create mentoring.md --- tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md diff --git a/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md b/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md new file mode 100644 index 000000000..75ff73bb9 --- /dev/null +++ b/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md @@ -0,0 +1,4 @@ +The atbash cipher is symmetrical that is why it is possible to use one function to encode and decode. + +Ask a student to refactor. +`Could you extract chunk splitting code and make refactoring of you code taking in account that fact?` From 24202e280461dc8f54c2422f086e9ad6d3395465 Mon Sep 17 00:00:00 2001 From: denisf2 <124052583+denisf2@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:46:34 +0300 Subject: [PATCH 2/4] Update mentoring.md --- .../atbash-cipher/atbash-cipher/mentoring.md | 78 ++++++++++++++++++- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md b/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md index 75ff73bb9..b18a6130d 100644 --- a/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md +++ b/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md @@ -1,4 +1,76 @@ -The atbash cipher is symmetrical that is why it is possible to use one function to encode and decode. +# Mentoring + +## Reasonable solutions +```cpp +#include + +namespace atbash_cipher +{ + +std::string apply_cypher(std::string aStr); +std::string apply_spaces(const std::string& aStr); + +std::string encode(const std::string& aStr) +{ + auto str = apply_cypher(aStr); + return apply_spaces(str); +} + +std::string apply_spaces(const std::string& aStr) +{ + std::string out; + out.reserve(aStr.length() + aStr.length() / 5); + for(size_t i = 0; i < aStr.length(); ++i) + { + if(0 != i && 0 == i % 5) + out.push_back(' '); + out.push_back(aStr[i]); + } + + return out; +} + +std::string decode(const std::string& aStr) +{ + return apply_cypher(aStr); +} + +std::string apply_cypher(std::string aStr) +{ + auto wr_it = std::begin(aStr); + for(auto rd_it = std::cbegin(aStr); rd_it != std::cend(aStr); ++rd_it) + { + if(std::isalpha(*rd_it)) + { + const auto a = static_cast('a'); + const auto z = static_cast('z'); + *wr_it = static_cast(z - std::tolower(*rd_it) + a); + ++wr_it; + } + else if(std::isdigit(*rd_it)) + { + *wr_it = *rd_it; + ++wr_it; + } + } + + aStr.erase(wr_it, aStr.end()); + + return aStr; +} +} // namespace atbash_cipher + +``` +## Common suggestions + + - The atbash cipher is symmetrical that is why it is possible to use one function to encode and decode. Ask a student to refactor. `Could you extract chunk splitting code and make refactoring of you code taking in account that fact?` + - Passing function non-POD arguments by value (here usually std::string). + - Explain the problem of time efficiency + - Ask use references or lightweight objects (here std::string_view) + - Students usually use mapping algorithm (map/array chars) + - Explain what is ASCII table, char type + - Ask refactor code using math equation to mutate a char + - Introduce to a student standart functions to check character (std::isalpha/std::isalnum/..) + +## Talking points -Ask a student to refactor. -`Could you extract chunk splitting code and make refactoring of you code taking in account that fact?` From 63364fc62b01c9b00162cd4c46cd832de391a83b Mon Sep 17 00:00:00 2001 From: denisf2 <124052583+denisf2@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:47:30 +0300 Subject: [PATCH 3/4] Apply mentoros suggestions --- .../cpp/exercises/atbash-cipher/mentoring.md | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 tracks/cpp/exercises/atbash-cipher/mentoring.md diff --git a/tracks/cpp/exercises/atbash-cipher/mentoring.md b/tracks/cpp/exercises/atbash-cipher/mentoring.md new file mode 100644 index 000000000..a143a5d5a --- /dev/null +++ b/tracks/cpp/exercises/atbash-cipher/mentoring.md @@ -0,0 +1,73 @@ +# Mentoring + +## Reasonable solutions +```cpp +#include + +namespace atbash_cipher +{ + +std::string apply_cypher(std::string aStr); +std::string apply_spaces(const std::string& aStr); + +std::string encode(const std::string& aStr) +{ + auto str = apply_cypher(aStr); + return apply_spaces(str); +} + +std::string apply_spaces(const std::string& aStr) +{ + std::string out; + out.reserve(aStr.length() + aStr.length() / 5); + for(size_t i = 0; i < aStr.length(); ++i) + { + if(0 != i && 0 == i % 5) + out.push_back(' '); + out.push_back(aStr[i]); + } + + return out; +} + +std::string decode(const std::string& aStr) +{ + return apply_cypher(aStr); +} + +std::string apply_cypher(std::string aStr) +{ + auto wr_it = std::begin(aStr); + for(const unsigned char letter : aStr) + // ^ implicit cast bounded by cctype header functions ex. std::tolower and std::isdigit + { + if(std::isalpha(letter)) + { + const auto a = static_cast('a'); + const auto z = static_cast('z'); + *wr_it = static_cast(z - std::tolower(letter) + a); + ++wr_it; + } + else if(std::isdigit(letter)) + { + *wr_it = letter; + ++wr_it; + } + } + + aStr.erase(wr_it, aStr.end()); + + return aStr; +} // namespace atbash_cipher + +``` +## Common suggestions + +- Use `const std::string&` or `std::string_view` instead of `std::string` as a parameter, unless the string is re-used and returned. +- If students use structures representing alphabet for linear find, explain what is ASCII table, char type + +## Talking points + +- Be aware of hidden copies being made by using certain types as function parameters. (`std::string` in this case) +- When appending to a std::string, call std::string::reserve is a good optimization. +- Be aware of undefined behaviour using if the argument's value is neither representable as unsigned char nor equal to EOF \ No newline at end of file From 7c5f1d5a0553b2969b0f683a5025034adb9660a2 Mon Sep 17 00:00:00 2001 From: denisf2 <124052583+denisf2@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:50:02 +0300 Subject: [PATCH 4/4] Delete tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md --- .../atbash-cipher/atbash-cipher/mentoring.md | 76 ------------------- 1 file changed, 76 deletions(-) delete mode 100644 tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md diff --git a/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md b/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md deleted file mode 100644 index b18a6130d..000000000 --- a/tracks/cpp/exercises/atbash-cipher/atbash-cipher/mentoring.md +++ /dev/null @@ -1,76 +0,0 @@ -# Mentoring - -## Reasonable solutions -```cpp -#include - -namespace atbash_cipher -{ - -std::string apply_cypher(std::string aStr); -std::string apply_spaces(const std::string& aStr); - -std::string encode(const std::string& aStr) -{ - auto str = apply_cypher(aStr); - return apply_spaces(str); -} - -std::string apply_spaces(const std::string& aStr) -{ - std::string out; - out.reserve(aStr.length() + aStr.length() / 5); - for(size_t i = 0; i < aStr.length(); ++i) - { - if(0 != i && 0 == i % 5) - out.push_back(' '); - out.push_back(aStr[i]); - } - - return out; -} - -std::string decode(const std::string& aStr) -{ - return apply_cypher(aStr); -} - -std::string apply_cypher(std::string aStr) -{ - auto wr_it = std::begin(aStr); - for(auto rd_it = std::cbegin(aStr); rd_it != std::cend(aStr); ++rd_it) - { - if(std::isalpha(*rd_it)) - { - const auto a = static_cast('a'); - const auto z = static_cast('z'); - *wr_it = static_cast(z - std::tolower(*rd_it) + a); - ++wr_it; - } - else if(std::isdigit(*rd_it)) - { - *wr_it = *rd_it; - ++wr_it; - } - } - - aStr.erase(wr_it, aStr.end()); - - return aStr; -} -} // namespace atbash_cipher - -``` -## Common suggestions - - - The atbash cipher is symmetrical that is why it is possible to use one function to encode and decode. Ask a student to refactor. `Could you extract chunk splitting code and make refactoring of you code taking in account that fact?` - - Passing function non-POD arguments by value (here usually std::string). - - Explain the problem of time efficiency - - Ask use references or lightweight objects (here std::string_view) - - Students usually use mapping algorithm (map/array chars) - - Explain what is ASCII table, char type - - Ask refactor code using math equation to mutate a char - - Introduce to a student standart functions to check character (std::isalpha/std::isalnum/..) - -## Talking points -