I am working on the “List ops” exercise in Python. But when I try to test in it in the exercism web editor, the results are different, and wrong.
Any ideas as to how I can resolve this? Could the cause be that I am using recursion?
TIA
I am working on the “List ops” exercise in Python. But when I try to test in it in the exercism web editor, the results are different, and wrong.
Any ideas as to how I can resolve this? Could the cause be that I am using recursion?
TIA
We need some more information.
How are you running the tests locally?
What’s your code?
Which tests are failing in the editor?
Recursion is not a problem here. Are you actually running the Exercism tests locally?
Thanks for your quick response.
I am running my code locally in Visual Studio Code on Windows 11. The code is for the “concat” function in the “List Ops” exercise for Python.
By “what’s your code” do you mean you want to see the actual code? If yes, how would I do that? Copy and paste into a reply? Attach a file to a reply? Other?
Thanks for your quick reply.
I am running my code locally within Visual Studio Code on Windows 11. And I run the same test, successfully, that fails when I try to run it within Exercism’s web editor.
@jsmallt9 Please copy the commands you use to run the tests and all the code you have written and paste them into a reply, using code blocks, e.g. with this button:
. You should see something like this in the forum input:
```
type or paste code here
```
Thanks for your reply. I don’t see a “</>” button but I will try “Block quote”:
from collections.abc import Iterable
def is_iterable(x):
return isinstance(x, Iterable) and not isinstance(x, (str, bytes))
def concat(lists):
retval =
if len(lists) != 0:
for element in lists:
if is_iterable(element):
if len(element) != 0:
retval += concat(element)
elif element == 0 or element:
retval.append(element)
return retval
print(concat([[[1], [2]], [[3]], [], [[4, 5, 6]]]))
Blockquote
As I look at my post I can see that block quote did not work as I thought (or I used it incorrectly). But I did find the code blocks option (in a menu). So here’s another try:
from collections.abc import Iterable
def is_iterable(x):
return isinstance(x, Iterable) and not isinstance(x, (str, bytes))
def concat(lists):
retval = []
if len(lists) != 0:
for element in lists:
if is_iterable(element):
if len(element) != 0:
retval += concat(element)
elif element == 0 or element:
retval.append(element)
return retval
print(concat([[[1], [2]], [[3]], [[]], [[4, 5, 6]]]))
The correct result (which I get in VS Code) is [1, 2, 3, 4, 5, 6]
The result I get in Exercism’s web editor is: [[1], [2], [3], [ ], [4, 5, 6]].
How are you running the tests in VSCode? Which tests are you running?
If you’re working locally, you should be using the Exercism CLI to download the Exercism unit tests. You should not be writing your own tests. You’re code should not need any prints.
The print statement in the code is to display the result of the test in VS Code. So I am just testing one of the test cases: the first one that fails when tested in Exercism’s web editor.
When I test in the Exercism web editor I do not include the print statement.
So far I have resisted downloading the CLI because I generally hesitate to install not-sure-what-it-does software from not-yet-trusted sources.
Am I the only one not using the CLI?
You can read the CLI code. It is an API wrapper to fetch the files from Exercism and submit the files to Exercism. You can manually download the tests from GitHub, too. But so long as you’re not running the actual unit tests, what you’re testing locally is pretty meaningless as it isn’t what Exercism is testing.
When I run the code in Exercism’s web editor and it fails, I can figure out what the test was and what the expected results are from the results. That is how I figured out that the failing test was for:
concat([[[1], [2]], [[3]], [[ ]], [[4, 5, 6]]]).
It is also how I am able to determine what the “expected result” is [1,2,3,4,5,6].
And even if am not using the same test as used by the web editor, it doesn’t explain how the code I have works in VS Code but fails in the web editor.
Except that’s not what the test is actually looking for. I think you’re looking at the test input and what your code produces, and you’re ignoring what the test actually expects!
Your expecting one thing, the tests expect something different. It “works” in VS Code because it produces what you are expecting … which is not what the tests actually expect.
It “works” in that it produces something. It produces what you expect. But if you were using the Exercism test, that output would fail locally.
Thank you (for your persistent) help! My concat function is now passing all its tests.
Yes, I was misreading the tests and expected results. This was due, in part, to my misreading the requirements for the function. (I thought I was supposed to be flattening the input!?)
Am I the only one who often finds the online instructions for (Python) exercises imprecise and/or incomplete?
That’s why we strongly recommend you use the provided unit tests ;)
There is a separate flatten array exercise; concat and flatten are not the same thing.
Exercise instructions are not meant to be comprehensive requirements. Exercism uses TDD; the tests provide the requirements. This is by design.
When working in the web editor, how does one access the “provided unit tests”? Under the tests tab on the right?
If so, all I see are inputs and expected outputs. It tells me nothing about how the function gets from the input to the output.
For example, I am now working on the “foldl” and “foldr” functions in the List Ops exercise. After reading the instructions and reading the tests I still have little idea how generate the correct outputs to the test inputs.
Under the “Tests” tab, I see:
def test_concat_list_of_nested_lists(self):
self.assertEqual(
concat([[[1], [2]], [[3]], [[]], [[4, 5, 6]]]),
[[1], [2], [3], [], [4, 5, 6]],
)
That shows the input [[[1], [2]], [[3]], [[]], [[4, 5, 6]]] being passed to the concat() function and being compared with the expected value [[1], [2], [3], [], [4, 5, 6]] via a self.assertEqual().
If you run the tests and look at the “Results” tab, you should see a “Failed” block for each failed test. You can click to expand. In those, you should see all the above details presented more cleanly.
The tests won’t tell you how to generate the output but they should make it pretty clear what the output is expected to be.
Fold functions are slightly trickier to decipher from the input/output. Fold functions take a function, a list (or iterable) and initial value. They call the function once for each element with an “accumulator” and element, “reducing” the list.
Thanks for the explanation. But I am still not clear on how to “fold”. I get that the element is an element of the list. But how does one determine the initial value for the accumulator?
The only way I succeeded in the exercise was to use the “reduce” function from the functools module. Or was that how the folding was supposed to be done?
The initial value is given to you as an argument.
The general expectation is that you implement this yourself. You start with the initial value (one of the function arguments) then call the function with each element and the accumulated value.
Roughly,
accumulator = initial
for element in list:
accumulator = function(accumulator, element)