Strategy
Strategy
To To support (coding and) code review (especially when asking for alternatives), state (in the code) the goal pursued during coding. (Double linkage/last serves no purpose I can see.)
If
If not literally re-inventing a support on solid surfaces combining low longitudinal friction with good lateral guide, use/implement an existing "protocol"/"interface" - mutable sequence comes to mind seeing the methods you present; something like test_MutableSequence() may fall into your lap.
Explicitly
Explicitly specify everything protocol but not standard using docstrings. Sketch tests: If you don't know what to test, you don't know what to implement.
Tactics
- specify what is to happen with parameter values without "natural" meaning, e.g., index smaller zero or not smaller count.
- (as @Peilonrayz demanded:) Don’t Repeat Yourself
- provide docstrings for classes (and modules), too
- check comments and, arguably more important, docstrings for correctness
- when a second error passes unit testing after thinking unit tests complete, revise unit tests
Tactics
- specify what is to happen with parameter values without "natural" meaning, e.g., index smaller zero or not smaller
count. - (as @Peilonrayz demanded:) Don’t Repeat Yourself
- provide docstrings for classes (and modules), too
- check comments and, arguably more important, docstrings for correctness
- when a second error passes unit testing after thinking unit tests complete, revise unit tests
Observations about the code,
[especially] insert, find, replace, at_index:
- insert fails to update count
- find, replace: replace (& _find) might use find. With quality satisfied with more than one node's data, both are underspecified.
- _at_index: if count/2 < index < count, walk backwards
(it may be useful to allow indices from -count (even with at_index or generally) - cf. slicing)
- delete looks non-adapted from a singly-linked list implementation (no need for last)
current.next.last should be set depending on current == tail
should use find()
- insert fails to set old_head.last
- reverse: how about transmuting to an instance of ListLinkedDoubly, with roles of next and last exchanged(&head/tail, if sticking with no sentinel node (@Peilonrayz, again))
As presented, reverse() is a costly operation - reversed() returns an iterator
- __str__: return '[]' if 0 == self.count \
else '[-(' + ')<=>('.join(self.items()) + ')-]'
insertfails to updatecountfind,replace:replace(&_find) might usefind. Withqualitysatisfied with more than one node'sdata, both are underspecified._at_index: ifcount/2<index<count, walk backwards
(it may be useful to allow indices from-count(even withat_indexor generally) - cf. slicing)deletelooks non-adapted from a singly-linked list implementation (no need forlast)
current.next.lastshould be set depending oncurrent==tail
should usefind()insertfails to setold_head.lastreverse: how about transmuting to an instance ofListLinkedDoubly, with roles ofnextandlastexchanged(&head/tail, if sticking with no sentinel node (@Peilonrayz, again))
As presented,reverse()is a costly operation -reversed()returns an iterator__str__:return '[]' if 0 == self.count \
else '[-(' + ')<=>('.join(self.items()) + ')-]'