DEV Community

Cover image for Dead Simple Python: Loops and Iterators

Dead Simple Python: Loops and Iterators

Jason C. McDonald on February 22, 2019

Like the articles? Buy the book! Dead Simple Python by Jason C. McDonald is available from No Starch Press. Remember the last time you lost som...
Collapse
 
aymanone profile image
aymanone

hello
it's a perfect article all the
series really
but in the code there something wrong
in the iterator for agents
as you implemented it it will return
the first nth items in the agents list
even if they're classified

Collapse
 
codemouse92 profile image
Jason C. McDonald

Hm. I just tested the code as implemented again, and it doesn't display the classified agents. If your tests have produced otherwise, would you mind sharing a screenshot? Thanks!

Collapse
 
aymanone profile image
aymanone

yes it'l work right
but try this
agents.add(not secret)
agents.add(secret)
agent.add(not secret)
agents.add(secret)
then
self.agents=[not secret,secret,not secret,secret]
then
self.agents-self.secret
4-2=2
then what will print is
self.agents[0] # not secret
then
self.agents[1]#secret
actually it's not big deal
not deal at all but
i read the article and when i reach that
i read it several times
because i thought may be i missed something
thanks for this series i hope
you continue it

Thread Thread
 
codemouse92 profile image
Jason C. McDonald

Ah, I hadn't quite addressed the [] operator in that example. Good catch.

Thread Thread
 
pkwhaley profile image
Pete (he/him)

I noticed this error case while reading through the article as well. In the sake of learning I just couldn't move on and ignore it.

Here is my fix. I am sure there are better ways to accomplish this, so please critique and let me know how I could better accomplish this.

The only thing I changed was the next method as follows:

    def __next__(self):
        if self._index == self._max:
            raise StopIteration
        else:
            _number, _name = self._roster[self._index]
            if _name in self._classified:
                self._roster.pop(self._index)
            r = self._roster[self._index]
            self._index += 1
            return r
Thread Thread
 
codemouse92 profile image
Jason C. McDonald

Hey, that's pretty good. However, my only concern is that it would delete the internally stored information about the classified agent (which we don't want).

Thread Thread
 
pkwhaley profile image
Pete (he/him)

Ah, good point.

Take 2 [move classified to end of _roster]:

            if _name in self._classified:
                self._roster.append(self._roster.pop(self._index))
            r = self._roster[self._index]

Thanks so much for these articles and for being so responsive. They are written very well , engaging, and a great resource.

Thread Thread
 
codemouse92 profile image
Jason C. McDonald

If I were going to fix this problem (which I may well do soon -- I have to take another pass through this material when writing the book), I would actually define the __getitem__() function instead, as that controls the behavior of the [] operator.

This all comes down to separation of concerns. It shouldn't be the responsibility of __next__() to mutate the internal data to obscure information. It's only job should be to determine whether it exposes that information, and how.

Of course, in all honesty, there's nothing preventing a direct call to agents._roster[1] (Python has no private variables). If we were going to obfuscate or remove classified data, that should really occur on the add_agent() function.

Collapse
 
ardunster profile image
Anna R Dunster

I see another comment thread addressed what I was wondering about the classified agents showing up if they weren't last ;)

For some reason I had the idea that lists and arrays were different in some functional way, but from your article it sounds they are functionally the same things, just with different vocabulary based on language?

I have a hard time grokking hashability. I've tried several times but something eludes me about the logic of why one thing is hashable and another isn't. I'd rather understand it than memorize it/look things up to check when it matters.

(Also, funny thing, OSX has grokking in the dictionary, but not hashable? what.)

Collapse
 
codemouse92 profile image
Jason C. McDonald • Edited

Yes, lists and arrays are effectively the same things. (There are some implementation differences internal to the language, mind you.)

Hashing means you perform some function, usually a form of one-way (lossy, as it were) encryption on the data to produce a (usually) unique value, often shorter than the original.

For example, here's the hashes for a few strings, according to Python's hash function. You'll notice they all produce a unique integer value, and all those integers are the same length.

"Hello" → 3483667490880649043
"Me" → 6066670828640188320
"Reverse the polarity of the neutron flow." → 7317767150724217908
"What evil lurks in the hearts of men? The shadow knows!" → -6411620787934941530

When two different input values have the same hash, that's known as a "hash collision", so any container that relies on a hash (such as Python's dictionaries) needs to be able to handle that situation.

For more information, watch this excellent explanation by the legendary @vaidehijoshi :

Collapse
 
ardunster profile image
Anna R Dunster

Thanks for the link, that's a great video and the visuals are quite helpful. Will check out the rest of her series, too.

Collapse
 
zhenmisher profile image
zhenmisher • Edited

Hello, I reimplemented the __next__ method to avoid classified elements got exposed

class AgentRoster_Iterator:

    def __init__(self, container):
        self._roster = list(container._agents.items())
        self._classified = container._classified
        self._max = len(self._roster)
        self._index = 0

    def __next__(self):
        while self._index < self._max:
            num, name = self._roster[self._index]
            self._index += 1
            if name not in self._classified:
                return num, name
        raise StopIteration
Collapse
 
codemouse92 profile image
Jason C. McDonald

Oh, top notch, thanks for catching that, mate.