11/15 SPOILER: Contains answer code


#1

SPOILER: CONTAINS ANSWER

The code that tests our function appears to reference check the sequence given after we have potentially messed with it.
My code provides the actual correct answer, but the reference check believes the answer should be 0 since all of the counted items have been removed.

My code below directly removes the item from the sequence while counting how many it removes:

def count(sequence, item):
    count = 0 
    while sequence.`__contains__`(item):
        sequence.remove(item)
        count += 1 
    return count

This returns an error for every sequence except for the first two, saying that the actual answer should be ‘0’

The answer code they provide doesn’t directly mess with the code:

def count(sequence, item):
count = 0
for i in sequence:
if i == item:
count += 1
return count


#2

the removal of items causes problems with the exercise validation, if you remove an item, the items are no longer in the list to be validated.


#3

Yes, the test code keeps hold of the original value, and you’re modifying it. You could for example empty out the input and return an answer of 0 and it’d probably pass you.
While the result may be correct, it still has an unwanted side-effect and the behaviour of the function is therefore wrong (even without taking into account what the test code passes or doesn’t pass, for example, emptying the list and returning 0 would also be wrong even if it passes (not sure if it would))

Also, it is rare that you should ever use names surrounded in double underscores directly. That name is used to implement behaviour for the operators in and not in


#4

I used the “help” function to help me find code I can use to solve the problem.
I’m doing these problem modules every few days, and its been over a month since I’ve been taught the code I’m supposed to be using.


#5

Is it possible to work around this?
Or even throw in a “don’t directly modify the sequence” in the instructions, like in the next practice problem :no_mouth:
Would be awesome and an easy fix :slight_smile:


#6

its very likely possible, yes

yes, its an easy fix. But the size of codecademy, there are dozen of this kind of small things which could be better, fixing them all would take days, if not weeks.


#7

I understand, thank you for your help!


#8

Another thing to note on that code is that testing if something is contained by a list means iterating through the whole list, and removing also does that. For a task where a single pass over the list is enough, that is horribly inefficient (only noticeable as the input gets larger).

For example, a list of 1 million 'a’s, removing each ‘a’, means iterating through the whole thing 2000000 times (1m for contains, 1m for remove), for a total of 2000000000000 iterations which is a large amount of operations relative to the clock speed of your cpu, it’ll take a lot of time.

Though, on average, the list will be half its original size, so it’s only half the amount of operations. completely irrelevant though, it’s really the number of zero’s we’re counting here


#9

Something I will likely learn as I continue coding.
Thank you for putting this in the forefront of my mind, I appreciate the input!


#10

Agreed. If a particular function’s primary purpose is to return information regarding the state of an object, the function should not change the state of that object, unless such a change is explicitly planned as one of the function’s actions. If, as is the case with the current example, the primary purpose of a function is to count occurrences of an item in a list, a user of the function is likely to be quite disappointed to learn that after requesting that count via the function, the user receives information that has been rendered obsolete by the action of that function. Another example would be a function that invokes a sort on a list in order to extract some information about the list, perhaps a median. That function should not sort the original list, unless one of the deliberate side effects of the function is to do so. A user of the function might want and expect to find the order of the items in the list unchanged after the function returns its result.

A case wherein a function might have a useful and deliberate side effect would be one that leaves a time stamp within an object that indicates when that object was last accessed. However, it would be essential for that feature of the function to be documented.


#11

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.