Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #92772 > unrolled thread
| Started by | "Jason P." <suscricions@gmail.com> |
|---|---|
| First post | 2015-06-17 12:21 -0700 |
| Last post | 2015-06-18 21:43 +1000 |
| Articles | 10 on this page of 30 — 13 participants |
Back to article view | Back to comp.lang.python
Classic OOP in Python "Jason P." <suscricions@gmail.com> - 2015-06-17 12:21 -0700
Re: Classic OOP in Python Skip Montanaro <skip.montanaro@gmail.com> - 2015-06-17 14:38 -0500
Re: Classic OOP in Python Ned Batchelder <ned@nedbatchelder.com> - 2015-06-17 12:44 -0700
Re: Classic OOP in Python Marko Rauhamaa <marko@pacujo.net> - 2015-06-17 23:39 +0300
Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-17 22:07 +0100
Re: Classic OOP in Python Ned Batchelder <ned@nedbatchelder.com> - 2015-06-17 14:14 -0700
Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-18 00:33 +0200
Re: Classic OOP in Python Ned Batchelder <ned@nedbatchelder.com> - 2015-06-17 15:55 -0700
Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-18 11:50 +0100
Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-19 01:01 +0200
Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-20 23:52 +0100
Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-21 10:26 +0200
Re: Classic OOP in Python sohcahtoa82@gmail.com - 2015-06-17 14:33 -0700
Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-17 22:49 +0100
Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-18 00:22 +0200
Re: Classic OOP in Python Marco Buttu <marco.buttu@gmail.com> - 2015-06-18 11:00 +0200
Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-18 00:09 +0200
Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-17 23:27 +0100
Re: Classic OOP in Python Steven D'Aprano <steve@pearwood.info> - 2015-06-18 08:58 +1000
Re: Classic OOP in Python Cousin Stanley <cousinstanley@gmail.com> - 2015-06-18 08:10 -0700
Re: Classic OOP in Python Terry Reedy <tjreedy@udel.edu> - 2015-06-17 19:46 -0400
Re: Classic OOP in Python Chris Angelico <rosuav@gmail.com> - 2015-06-18 10:07 +1000
Re: Classic OOP in Python "Jason P." <suscricions@gmail.com> - 2015-06-18 04:24 -0700
Re: Classic OOP in Python "Jason P." <suscricions@gmail.com> - 2015-06-18 04:21 -0700
Re: Classic OOP in Python Ned Batchelder <ned@nedbatchelder.com> - 2015-06-18 04:54 -0700
Re: Classic OOP in Python "Jason P." <suscricions@gmail.com> - 2015-06-18 04:22 -0700
Re: Classic OOP in Python sohcahtoa82@gmail.com - 2015-06-17 14:16 -0700
Re: Classic OOP in Python Fabien <fabien.maussion@gmail.com> - 2015-06-18 13:03 +0200
Re: Classic OOP in Python Marko Rauhamaa <marko@pacujo.net> - 2015-06-18 14:25 +0300
Re: Classic OOP in Python Chris Angelico <rosuav@gmail.com> - 2015-06-18 21:43 +1000
Page 2 of 2 — ← Prev page 1 [2]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-06-17 19:46 -0400 |
| Message-ID | <mailman.570.1434584839.13271.python-list@python.org> |
| In reply to | #92777 |
On 6/17/2015 4:39 PM, Marko Rauhamaa wrote:
> Ned Batchelder <ned@nedbatchelder.com>:
>
>> TDD is about writing tests as a way to design the best system, and
>> putting testing at the center of your development workflow. It works
>> great with Python even without interfaces.
I use what I might call 'smart TDD'. I think it a mistake to dismiss
TDD because 'stupid TDD' is possible, and maybe even extant.
The reason for having a test initially fail is to make sure that the
test is called. A unittest example:
class NoTest(unittest.TestCase):
def text_ohmygod(self):
assertEqual(True, False)
Why does this 'pass'? Within the last year, it was discovered that a
TestCase subclass in one of the Python test files was not being run. I
made a similar mistake in my own code. The more I do TDD
(intelligently), the more I like it.
> I wonder how great it really is. Testing is important, that's for sure,
> but to make it a dogmatic starting point of development is not that
> convincing.
The bugs in Python, whether already fixed, on the tracker, or yet to be
recorded, are the result of CPython not originally using TDD of some
version. In my opinion, CPython maintenance and enhancement has
improved since some semblance of TDD was instituted. A runable test is
now the first stage for tracker issues.
> The way it was explained to me was that in TDD you actually don't write
> code to any requirements or design:
Writing sane code to pass tests based on requirements or a design is
intended to ensure that one is actually meeting the design.
> you simply do the least to pass the tests.
The incantation I have read is 'simplest', not 'least'. I personally
interpret 'simplest' to include some presumption of sanity in relation
to the ultimate goal.
> Thus, say you need to write a program that inputs a string and
> outputs the same string surrounded by parentheses (the requirement),
One should write a reusable and easily testable *function* that takes a
string as input (and outputs the same string surrounded by parens).
Call the function paren_around.
> the starting point might be this test case:
>
> - run the program
> - give it the word "hello" as input
> - check that the program prints out "(hello)"
Doubly bad.
1. I consider mixing program i/o with function not related to i/o to be
a bad idea. TDD should cure one of this madness, not reinforce it.
2. The first test for smart TDD should best be with a falsey input (or
other corner or edge case). With this guideline, there is a good chance
the 'simplest code' will be augmented rather than replaced with
additional tests. A smart TDD test might be
assertEqual(paren_arount(''), '()')
> The right TDD thing would be to satisfy the test with this program:
>
> input()
> print("(hello)")
This does not work. The above adds '\n' to the end of the string, which
is not part of the specification. A human may not notice, but an
automated test that captures stdout and compares with "(hello)" will
notice and fail.
> That *ought* to be the first version of the program until further test
> cases are added that invalidate it.
As a statistician, I know about the mistake of overfitting functions to
data. 'Teaching to the test' is a related mistake Smart TDD should not
reinforce bad practice. This simple code passes the initial testcase above.
def paren_around(s):
"Return string s surrounded by '(' and ')'."
return '()'
Add a more generic (non-null) testcase.
assertEqual(paren_around('abc', '(abc)')
The irrelevant details should usually be ignored when augmenting the
code*. The simplicity of this example makes it easy to write a correct
assert, but is not relevant to the intent of the function.
def paren_around(s):
"Return string s surrounded by '(' and ')'."
return '({})'.format(s)
Code added, with nothing deleted.
> Another interesting ism I have read about is the idea that the starting
> point of any software project should be the user manual. The developers
> should then go and build the product that fits the manual.
The corresponding TDD approach is to write tests from the manual, and
then write code. One can also write tests from docs for existing code
- and then see if the code passes the doc-based tests. This is one way
people discover bugs.
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-06-18 10:07 +1000 |
| Message-ID | <mailman.572.1434586050.13271.python-list@python.org> |
| In reply to | #92777 |
On Thu, Jun 18, 2015 at 6:39 AM, Marko Rauhamaa <marko@pacujo.net> wrote: > Another interesting ism I have read about is the idea that the starting > point of any software project should be the user manual. The developers > should then go and build the product that fits the manual. I've seldom met a *user* manual that's truly the right way to start building, but there have been times when I've built *API* documentation prior to the code. That can work fairly well. I'll also often start a project with a copious set of notes that aren't quite user-facing, aren't quite programmer-friendly, but are somewhere in between. Here's a new project I'm starting now: https://github.com/Rosuav/ThirdSquare Prior to actually creating that repo, I'd done some thrash testing of the basic concepts (which is how I know that the basic idea will work - my thrash test achieved 100tps, massively exceeding the 40tps that I need, ergo it's worth proceeding to code), but the project itself started with the README, then the .sql files giving a basic run-down of the tables required. Now, and only now, I'm starting to look at actual code. Is that starting with the user manual? Not quite, but I think it captures the same concept that that's trying to capture. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | "Jason P." <suscricions@gmail.com> |
|---|---|
| Date | 2015-06-18 04:24 -0700 |
| Message-ID | <42563233-5269-41e7-87a9-1bde66480d09@googlegroups.com> |
| In reply to | #92777 |
El miércoles, 17 de junio de 2015, 22:39:31 (UTC+2), Marko Rauhamaa escribió:
> Ned Batchelder <ned@nedbatchelder.com>:
>
> > TDD is about writing tests as a way to design the best system, and
> > putting testing at the center of your development workflow. It works
> > great with Python even without interfaces.
>
> I wonder how great it really is. Testing is important, that's for sure,
> but to make it a dogmatic starting point of development is not that
> convincing.
>
> The way it was explained to me was that in TDD you actually don't write
> code to any requirements or design: you simply do the least to pass the
> tests. Thus, say you need to write a program that inputs a string and
> outputs the same string surrounded by parentheses (the requirement), the
> starting point might be this test case:
>
> - run the program
> - give it the word "hello" as input
> - check that the program prints out "(hello)"
>
> The right TDD thing would be to satisfy the test with this program:
>
> input()
> print("(hello)")
>
> That *ought* to be the first version of the program until further test
> cases are added that invalidate it.
>
>
> Another interesting ism I have read about is the idea that the starting
> point of any software project should be the user manual. The developers
> should then go and build the product that fits the manual.
>
>
> Marko
The refactor phase is key in TDD (red-green-refactor). Again, GOOS is an advisable source of knowledge in this matter.
[toc] | [prev] | [next] | [standalone]
| From | "Jason P." <suscricions@gmail.com> |
|---|---|
| Date | 2015-06-18 04:21 -0700 |
| Message-ID | <01adfef5-7edf-447c-9397-853c4fd65e53@googlegroups.com> |
| In reply to | #92775 |
El miércoles, 17 de junio de 2015, 21:44:51 (UTC+2), Ned Batchelder escribió: > On Wednesday, June 17, 2015 at 3:21:32 PM UTC-4, Jason P. wrote: > > Hello Python community. > > > > I come from a classic background in what refers to OOP. Mostly Java and PHP (> 5.3). I'm used to abstract classes, interfaces, access modifiers and so on. > > > > Don't get me wrong. I know that despite the differences Python is fully object oriented. My point is, do you know any book or resource that explains in deep the pythonic way of doing OOP? > > > > For example, I'm gonna try to develop a modest application from ground up using TDD. If it had been done in Java for instance, I would made extensive use of interfaces to define the boundaries of my system. How would I do something like that in Python? > > > > > > Many thanks! > > What other languages do with interfaces, Python does with duck-typing. You > can build something like interfaces in Python, but many people don't bother. > > I don't know if your project will be web-based, but here is an entire book > about developing Python web sites with a TDD approach: > > http://www.obeythetestinggoat.com/ > > (Don't mind the unusual domain name, it's a bit of an inside joke...) > > TDD and interfaces are separate concepts, and I'm not sure they even > intersect. TDD is about writing tests as a way to design the best system, > and putting testing at the center of your development workflow. It works > great with Python even without interfaces. > > --Ned. I'm aware of duck typing. The point in using interfaces is to be explicit about the boundaries of a system. Quite a red "Growing Object-Oriented Software, Guided by Tests", by the way. In fact interfaces are key components in the style of building software they propose, in good company with TDD. Thx!
[toc] | [prev] | [next] | [standalone]
| From | Ned Batchelder <ned@nedbatchelder.com> |
|---|---|
| Date | 2015-06-18 04:54 -0700 |
| Message-ID | <69585e5b-a8c6-413b-849b-ce51585b72c7@googlegroups.com> |
| In reply to | #92818 |
On Thursday, June 18, 2015 at 7:21:29 AM UTC-4, Jason P. wrote: > El miércoles, 17 de junio de 2015, 21:44:51 (UTC+2), Ned Batchelder escribió: > > On Wednesday, June 17, 2015 at 3:21:32 PM UTC-4, Jason P. wrote: > > > Hello Python community. > > > > > > I come from a classic background in what refers to OOP. Mostly Java and PHP (> 5.3). I'm used to abstract classes, interfaces, access modifiers and so on. > > > > > > Don't get me wrong. I know that despite the differences Python is fully object oriented. My point is, do you know any book or resource that explains in deep the pythonic way of doing OOP? > > > > > > For example, I'm gonna try to develop a modest application from ground up using TDD. If it had been done in Java for instance, I would made extensive use of interfaces to define the boundaries of my system. How would I do something like that in Python? > > > > > > > > > Many thanks! > > > > What other languages do with interfaces, Python does with duck-typing. You > > can build something like interfaces in Python, but many people don't bother. > > > > I don't know if your project will be web-based, but here is an entire book > > about developing Python web sites with a TDD approach: > > > > http://www.obeythetestinggoat.com/ > > > > (Don't mind the unusual domain name, it's a bit of an inside joke...) > > > > TDD and interfaces are separate concepts, and I'm not sure they even > > intersect. TDD is about writing tests as a way to design the best system, > > and putting testing at the center of your development workflow. It works > > great with Python even without interfaces. > > > > --Ned. > > I'm aware of duck typing. The point in using interfaces is to be explicit about the boundaries of a system. > > Quite a red "Growing Object-Oriented Software, Guided by Tests", by the way. In fact interfaces are key components in the style of building software they propose, in good company with TDD. Yes, that book uses interfaces, because that book uses Java. Different languages offer different tools. You can make interfaces in Python, but you don't need to. They aren't enforced by Python, so you aren't gaining much other than documentation from them, so why not just use documentation? Abstract classes provide another tool. They can insist that you provide implementations of abstract methods. In my experience, it is easy to get to a point where you are struggling to satisfy your simple-minded abstract classes, rather than writing the code that you know you need to solve your actual problem. As Chris just mentioned elsewhere in this thread, you have to be very careful how you define your abstract classes. I've worked in Java projects where I had to provide 10 dummy implementations of methods I knew I wasn't going to need, just because the interface insisted they had to exist. The Python culture is to document your expectations, and write enough tests to verify that your code does what it claims to do. You are already planning on a TDD flow, so you will have plenty of tests. Try doing without interfaces or abstract classes. See how it goes. It's the Python way. :) --Ned.
[toc] | [prev] | [next] | [standalone]
| From | "Jason P." <suscricions@gmail.com> |
|---|---|
| Date | 2015-06-18 04:22 -0700 |
| Message-ID | <48b428f0-7373-4847-b1fd-2c8532c056ee@googlegroups.com> |
| In reply to | #92775 |
El miércoles, 17 de junio de 2015, 21:44:51 (UTC+2), Ned Batchelder escribió: > On Wednesday, June 17, 2015 at 3:21:32 PM UTC-4, Jason P. wrote: > > Hello Python community. > > > > I come from a classic background in what refers to OOP. Mostly Java and PHP (> 5.3). I'm used to abstract classes, interfaces, access modifiers and so on. > > > > Don't get me wrong. I know that despite the differences Python is fully object oriented. My point is, do you know any book or resource that explains in deep the pythonic way of doing OOP? > > > > For example, I'm gonna try to develop a modest application from ground up using TDD. If it had been done in Java for instance, I would made extensive use of interfaces to define the boundaries of my system. How would I do something like that in Python? > > > > > > Many thanks! > > What other languages do with interfaces, Python does with duck-typing. You > can build something like interfaces in Python, but many people don't bother. > > I don't know if your project will be web-based, but here is an entire book > about developing Python web sites with a TDD approach: > > http://www.obeythetestinggoat.com/ > > (Don't mind the unusual domain name, it's a bit of an inside joke...) > > TDD and interfaces are separate concepts, and I'm not sure they even > intersect. TDD is about writing tests as a way to design the best system, > and putting testing at the center of your development workflow. It works > great with Python even without interfaces. > > --Ned. I forgot to mention that the book you recommend seems to be a good starting point ;)
[toc] | [prev] | [next] | [standalone]
| From | sohcahtoa82@gmail.com |
|---|---|
| Date | 2015-06-17 14:16 -0700 |
| Message-ID | <f0c76343-7230-499c-ba30-33d7f6513503@googlegroups.com> |
| In reply to | #92772 |
On Wednesday, June 17, 2015 at 12:21:32 PM UTC-7, Jason P. wrote:
> Hello Python community.
>
> I come from a classic background in what refers to OOP. Mostly Java and PHP (> 5.3). I'm used to abstract classes, interfaces, access modifiers and so on.
>
> Don't get me wrong. I know that despite the differences Python is fully object oriented. My point is, do you know any book or resource that explains in deep the pythonic way of doing OOP?
>
> For example, I'm gonna try to develop a modest application from ground up using TDD. If it had been done in Java for instance, I would made extensive use of interfaces to define the boundaries of my system. How would I do something like that in Python?
>
>
> Many thanks!
You don't need interfaces with Python. Duck typing makes that all possible. This is perfectly valid:
class Dog(object):
def move(self):
print "Dog is moving"
class Car(object):
def move(self):
print "Car is moving"
things = [Dog(), Car()]
for thing in things:
thing.move()
Despite Dog and Car being completely different classes with no relationship with each other, the code runs just fine.
[toc] | [prev] | [next] | [standalone]
| From | Fabien <fabien.maussion@gmail.com> |
|---|---|
| Date | 2015-06-18 13:03 +0200 |
| Message-ID | <mlu8hh$ntr$1@speranza.aioe.org> |
| In reply to | #92781 |
On 06/17/2015 11:16 PM, sohcahtoa82@gmail.com wrote:
> You don't need interfaces with Python. Duck typing makes that all possible.
Yes, but I also like interfaces (or in python: mimicked interfaces with
NotImplementedError) for their clarity and documentation purposes.
Would you consider the following kind of program "unpythonic"?
class MovingObject(object):
"""Great doc about what a moving object is"""
def move(self):
"""Great doc about move"""
raise NotImplementedError()
class Dog(MovingObject):
def move(self):
print "Dog is moving"
class Car(MovingObject):
def move(self):
print "Car is moving"
(Disclaimer: I learned OOP with Java)
Fabien
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-06-18 14:25 +0300 |
| Message-ID | <87oakdz2ah.fsf@elektro.pacujo.net> |
| In reply to | #92816 |
Todd <toddrjen@gmail.com>: > On Thu, Jun 18, 2015 at 1:03 PM, Fabien <fabien.maussion@gmail.com> wrote: >> Would you consider the following kind of program "unpythonic"? >> >> class MovingObject(object): >> """Great doc about what a moving object is""" >> >> def move(self): >> """Great doc about move""" >> raise NotImplementedError() >> >> class Dog(MovingObject): >> def move(self): >> print "Dog is moving" >> >> class Car(MovingObject): >> def move(self): >> print "Car is moving" >> >> (Disclaimer: I learned OOP with Java) >> >> > I think this is what abstract base classes are for in Python. And they can be ok as long as you're not making them into a habit. Marko
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-06-18 21:43 +1000 |
| Message-ID | <mailman.595.1434627811.13271.python-list@python.org> |
| In reply to | #92816 |
On Thu, Jun 18, 2015 at 9:03 PM, Fabien <fabien.maussion@gmail.com> wrote: > Would you consider the following kind of program "unpythonic"? > > class MovingObject(object): > """Great doc about what a moving object is""" > > def move(self): > """Great doc about move""" > raise NotImplementedError() > > class Dog(MovingObject): > def move(self): > print "Dog is moving" > > class Car(MovingObject): > def move(self): > print "Car is moving" > > (Disclaimer: I learned OOP with Java) Now try extending the concept to two, three, or four such interfaces. Files can be moved, opened, copied, and unlinked. Should they share any sort of interface with dogs, boxes, handwriting, and railway carriages? It's much better to simply define the attributes of each object separately; most non-trivial cases don't involve simple methods with no additional arguments, and the chances of an incompatibility (or worse, a forced compatibility) go up. ChrisA
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.python
csiph-web