New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(curriculum): description improvement case converter program #54051
base: main
Are you sure you want to change the base?
Conversation
...on/learn-list-comprehension-by-building-a-case-converter-program/657e928716b77b2277980276.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657ee28cefc4945568287673.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657efa642593c5746acc5c81.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f01ae9aea647b27402d3e.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f025ec86c3d7c4177b6be.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f465f8e718b19c5105ae5.md
Outdated
Show resolved
Hide resolved
The changes are good to go from my end. 🎉 |
If this is ready, you can take it out of draft mode @larymak. There should be a button below that says "ready for review" you can click. |
This reverts commit c6396b8.
…CodeCamp/freeCodeCamp into feat/case-converter-program
c6396b8
to
873b86b
Compare
...on/learn-list-comprehension-by-building-a-case-converter-program/657f01ae9aea647b27402d3e.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657efa642593c5746acc5c81.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657ee28cefc4945568287673.md
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In step 12
To display the output, enclose the fucntion call within the
print()
function.
Replace fucntion with function.
...on/learn-list-comprehension-by-building-a-case-converter-program/657e928716b77b2277980276.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657ed53c19461d4b95c4757a.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657ee28cefc4945568287673.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657efce98e958b75df86b305.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657effaa2a5e0277d71f9cbe.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f01ae9aea647b27402d3e.md
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f465f8e718b19c5105ae5.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f43d341a0dd17120cdb08.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f456223b8c1187b461987.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f465f8e718b19c5105ae5.md
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657effaa2a5e0277d71f9cbe.md
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think some important changes are required to clarify how to work with list comprehensions:
- step 17
I'd leave thesnake_cased_char_list
list empty for this step. Let's add the
return ''.join(snake_cased_char_list).strip('_')
here to add interactivity, so the campers can actually see what happens. - step 18
snake_cased_char_list
becomes
['_' + char.lower() for char in pascal_or_camel_cased_string]
- step 19
snake_cased_char_list = ['_' + char.lower() for char in pascal_or_camel_cased_string if char.isupper()]
- step 20
snake_cased_char_list = [ '_' + char.lower() if char.isupper() else char for char in pascal_or_camel_cased_string ]
In this way:
- we add a bit of interactivity
- we write comprehensions that work in each step
- we teach the difference between having an
if
and anif
/else
(which is quite annoying)
...on/learn-list-comprehension-by-building-a-case-converter-program/657ee28cefc4945568287673.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657efa642593c5746acc5c81.md
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657effaa2a5e0277d71f9cbe.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657effaa2a5e0277d71f9cbe.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657effaa2a5e0277d71f9cbe.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f0044be09db790b1eb1c5.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f0044be09db790b1eb1c5.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f0353c9523d7d896873ea.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f43d341a0dd17120cdb08.md
Outdated
Show resolved
Hide resolved
Need more clarity on this |
We should change the following step:
seed code def convert_to_snake_case(pascal_or_camel_cased_string):
# snake_cased_char_list = []
# for char in pascal_or_camel_cased_string:
# if char.isupper():
# converted_character = '_' + char.lower()
# snake_cased_char_list.append(converted_character)
# else:
# snake_cased_char_list.append(char)
# snake_cased_string = ''.join(snake_cased_char_list)
# clean_snake_cased_string = snake_cased_string.strip('_')
# return clean_snake_cased_string
snake_cased_char_list = [ ]
--fcc-editable-region--
--fcc-editable-region--
def main():
print(convert_to_snake_case('aLongAndComplexString'))
if __name__ == '__main__':
main()
seed code def convert_to_snake_case(pascal_or_camel_cased_string):
# snake_cased_char_list = []
# for char in pascal_or_camel_cased_string:
# if char.isupper():
# converted_character = '_' + char.lower()
# snake_cased_char_list.append(converted_character)
# else:
# snake_cased_char_list.append(char)
# snake_cased_string = ''.join(snake_cased_char_list)
# clean_snake_cased_string = snake_cased_string.strip('_')
# return clean_snake_cased_string
--fcc-editable-region--
snake_cased_char_list = [ ]
--fcc-editable-region--
return ''.join(snake_cased_char_list).strip('_')
def main():
print(convert_to_snake_case('aLongAndComplexString'))
if __name__ == '__main__':
main()
seed code def convert_to_snake_case(pascal_or_camel_cased_string):
# snake_cased_char_list = []
# for char in pascal_or_camel_cased_string:
# if char.isupper():
# converted_character = '_' + char.lower()
# snake_cased_char_list.append(converted_character)
# else:
# snake_cased_char_list.append(char)
# snake_cased_string = ''.join(snake_cased_char_list)
# clean_snake_cased_string = snake_cased_string.strip('_')
# return clean_snake_cased_string
--fcc-editable-region--
snake_cased_char_list = ['_' + char.lower() for char in pascal_or_camel_cased_string]
--fcc-editable-region--
return ''.join(snake_cased_char_list).strip('_')
def main():
print(convert_to_snake_case('aLongAndComplexString'))
if __name__ == '__main__':
main()
seed code def convert_to_snake_case(pascal_or_camel_cased_string):
# snake_cased_char_list = []
# for char in pascal_or_camel_cased_string:
# if char.isupper():
# converted_character = '_' + char.lower()
# snake_cased_char_list.append(converted_character)
# else:
# snake_cased_char_list.append(char)
# snake_cased_string = ''.join(snake_cased_char_list)
# clean_snake_cased_string = snake_cased_string.strip('_')
# return clean_snake_cased_string
--fcc-editable-region--
snake_cased_char_list = ['_' + char.lower() for char in pascal_or_camel_cased_string if char.isupper()]
--fcc-editable-region--
return ''.join(snake_cased_char_list).strip('_')
def main():
print(convert_to_snake_case('aLongAndComplexString'))
if __name__ == '__main__':
main()
|
Changes incorporated, share feedback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there should be some improvements
...on/learn-list-comprehension-by-building-a-case-converter-program/657f43d341a0dd17120cdb08.md
Outdated
Show resolved
Hide resolved
const transformedCode = code.replace(/\r/g, ""); | ||
const convert_to_snake_case = __helpers.python.getDef("\n" + transformedCode, "convert_to_snake_case"); | ||
const { function_body } = convert_to_snake_case; | ||
|
||
assert.match(function_body, / +snake_cased_char_list\s*=\s*\[\s*("|')_\1\s*\+\s*char\.lower\(\s*\)\s+if\s+char\.isupper\(\s*\)\s*\]/); | ||
assert.match(function_body, /return\s*''\.join\(snake_cased_char_list\)\.strip\('_'\)/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use AST tests when we are creating new ones, it allows any equivalent code, irrespective of spaces and quotes used and stuff.
const transformedCode = code.replace(/\r/g, ""); | |
const convert_to_snake_case = __helpers.python.getDef("\n" + transformedCode, "convert_to_snake_case"); | |
const { function_body } = convert_to_snake_case; | |
assert.match(function_body, / +snake_cased_char_list\s*=\s*\[\s*("|')_\1\s*\+\s*char\.lower\(\s*\)\s+if\s+char\.isupper\(\s*\)\s*\]/); | |
assert.match(function_body, /return\s*''\.join\(snake_cased_char_list\)\.strip\('_'\)/); | |
({ | |
test: () => assert(runPython(` | |
_Node(_code).find_function('convert_to_snake_case').find_return().is_equivalent('return "".join(snake_cased_char_list).strip('_')) | |
`)) | |
}) |
...on/learn-list-comprehension-by-building-a-case-converter-program/657f456223b8c1187b461987.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f456223b8c1187b461987.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f47b12c51e41b3149e584.md
Outdated
Show resolved
Hide resolved
const transformedCode = code.replace(/\r/g, ""); | ||
const convert_to_snake_case = __helpers.python.getDef("\n" + transformedCode, "convert_to_snake_case"); | ||
const { function_body } = convert_to_snake_case; | ||
|
||
assert.match(function_body, / +snake_cased_char_list\s*=\s*\[\s*'_'\s*\+\s*char\.lower\(\s*\)\s+if\s+char\.isupper\(\s*\)\s*else\s*char\s*for\s+char\s+in\s+pascal_or_camel_cased_string\s*\]/); | ||
} | ||
}) | ||
assert.match(function_body, /if\s*char\.isupper\(\)/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test passes on the seed code.
...on/learn-list-comprehension-by-building-a-case-converter-program/657f465f8e718b19c5105ae5.md
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't able to leave suggestions in some steps, so I left simple comments.
Some example of list comprehension syntax are required. I wrote the first examples that came to my mind but we can write something more meaningful.
...on/learn-list-comprehension-by-building-a-case-converter-program/657effaa2a5e0277d71f9cbe.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657effaa2a5e0277d71f9cbe.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f0044be09db790b1eb1c5.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f0044be09db790b1eb1c5.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f43d341a0dd17120cdb08.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f43d341a0dd17120cdb08.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f456223b8c1187b461987.md
Outdated
Show resolved
Hide resolved
...on/learn-list-comprehension-by-building-a-case-converter-program/657f456223b8c1187b461987.md
Show resolved
Hide resolved
@@ -7,26 +7,22 @@ dashedName: step-19 | |||
|
|||
# --description-- | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--description--
List comprehensions accept conditional statements, to evaluate the provided expression only if certain condition are met:
spam = [i * 2 for i in iterable if i > 0]
As you can see from the output, the list of characters generated from pascal_or_camel_cased_string
has been joined. Since the expression inside the list comprehension is evaluated for each character, the result is a lowercase string with all the characters separated by an underscore.
Follow the example above to add an if
clause to your list comprehension so that the expression is executed only if the character is uppercase.
--hints--
You should add and if
clause with the condition char.isupper()
to your list comprehension.
({ test: () => assert(runPython(`
ifs = _Node(_code).find_function("convert_to_snake_case").find_variable("snake_cased_char_list").find_comp_ifs()
len(ifs) == 1 and ifs[0].is_equivalent("char.isupper()")
`)) })
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can consider to add another test to check the existing part of the comprehension.
...on/learn-list-comprehension-by-building-a-case-converter-program/657f47b12c51e41b3149e584.md
Show resolved
Hide resolved
--- | ||
id: 663b10c10a4c0a0e095137ee | ||
title: Step 18 | ||
challengeType: 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
challengeType: 0 | |
challengeType: 20 |
({ | ||
test: () => assert(runPython(` | ||
_Node(_code).find_function('convert_to_snake_case').find_return().is_equivalent('return "".join(snake_cased_char_list)') | ||
`)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`)); | |
`)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JFYI .find_return().is_equivalent("return x")
works fine, but if you want you can use .has_return("x")
which does the same thing under the hood.
--- | ||
id: 663b16e62fee463b4caf46e9 | ||
title: Step 19 | ||
challengeType: 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
challengeType: 0 | |
challengeType: 20 |
```js | ||
({ | ||
test: () => assert(runPython(` | ||
_Node(_code).find_function("convert_to_snake_case").find_variable("snake_cased_char_list").finfind_comp_expr()[0].is_equivalent("'_' + char.lower()") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_Node(_code).find_function("convert_to_snake_case").find_variable("snake_cased_char_list").finfind_comp_expr()[0].is_equivalent("'_' + char.lower()") | |
_Node(_code).find_function("convert_to_snake_case").find_variable("snake_cased_char_list").find_comp_expr().is_equivalent("'_' + char.lower()") |
The using the return statement, return an empty string `''` joined with `snake_cased_char_list` as the argument, and strip any leading or trailing underscores from the result. | ||
Before proceeding to work on the list comprehension, you're going to give your function a return value. In this way you'll be able to check the output. | ||
|
||
Using the the return statement, return the list `snake_cased_char_list`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the the return statement, return the list `snake_cased_char_list`. | |
Use the `return` statement to return the list `snake_cased_char_list` from your function. |
|
||
After returning the list `snake_cased_char_list`, you will need to join its elements into a single string using an empty string `''` as the separator. | ||
|
||
Modify the return statement to return the list `snake_cased_char_list` joined with an empty string as a separator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modify the return statement to return the list `snake_cased_char_list` joined with an empty string as a separator. | |
Modify the `return` statement to return the result of joining `snake_cased_char_list` with an empty string as a separator. |
|
||
# --hints-- | ||
|
||
You should modify the return statement to join the `snake_cased_char_list` using the `join` method with an empty string `''` as the separator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should modify the return statement to join the `snake_cased_char_list` using the `join` method with an empty string `''` as the separator. | |
You should modify the `return` statement to return the result of joining `snake_cased_char_list` with an empty string `''` as the separator using the `.join()` method. |
--- | ||
|
||
# --description-- | ||
|
||
List comprehensions are more than just transformation, they can also filter elements based on conditions using `if` statements. You can add an `if` statement within a list comprehension to filter elements based on a given condition. | ||
List comprehensions accept conditional statements, to evaluate the provided expression only if certain condition are met: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
List comprehensions accept conditional statements, to evaluate the provided expression only if certain condition are met: | |
List comprehensions accept conditional statements, to evaluate the provided expression only if certain conditions are met: |
|
||
# --hints-- | ||
|
||
You should add `if` statement after the `for` clause within the square braces of `snake_cased_char_list` to check if `char` is uppercase. | ||
You should add and `if` clause with the condition `char.isupper()` to your list comprehension. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add and `if` clause with the condition `char.isupper()` to your list comprehension. | |
You should add an `if` clause with the condition `char.isupper()` to your list comprehension. |
|
||
# --description-- | ||
|
||
After joining the elements of the list `snake_cased_char_list`, you will need to remove any leading or trailing underscores from the resulting string. For this, use the `strip` method with the underscore character `_` as an argument. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably we should explain explicitly that method calls can be chained and how it should be done.
Checklist:
main
branch of freeCodeCamp.Closes: #54232
Closes: #53359