Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #12075 > unrolled thread
| Started by | smith jack <thinke365@gmail.com> |
|---|---|
| First post | 2011-08-23 19:59 +0800 |
| Last post | 2011-08-27 23:51 -0500 |
| Articles | 20 on this page of 47 — 21 participants |
Back to article view | Back to comp.lang.python
is there any principle when writing python function smith jack <thinke365@gmail.com> - 2011-08-23 19:59 +0800
Re: is there any principle when writing python function Peter Otten <__peter__@web.de> - 2011-08-23 14:20 +0200
Re: is there any principle when writing python function Roy Smith <roy@panix.com> - 2011-08-23 08:56 -0400
Re: is there any principle when writing python function Mel <mwilson@the-wire.com> - 2011-08-23 08:53 -0400
Re: is there any principle when writing python function Roy Smith <roy@panix.com> - 2011-08-23 08:55 -0400
Re: is there any principle when writing python function Ulrich Eckhardt <ulrich.eckhardt@dominolaser.com> - 2011-08-23 15:00 +0200
Re: is there any principle when writing python function Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-08-24 01:22 +1000
Re: is there any principle when writing python function Terry Reedy <tjreedy@udel.edu> - 2011-08-23 14:29 -0400
Re: is there any principle when writing python function rantingrick <rantingrick@gmail.com> - 2011-08-23 13:22 -0700
Re: is there any principle when writing python function Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-08-24 11:44 +1000
Re: is there any principle when writing python function Seebs <usenet-nospam@seebs.net> - 2011-08-23 16:53 +0000
Re: is there any principle when writing python function rantingrick <rantingrick@gmail.com> - 2011-08-23 10:02 -0700
Re: is there any principle when writing python function alex23 <wuwei23@gmail.com> - 2011-08-23 20:05 -0700
Re: is there any principle when writing python function alex23 <wuwei23@gmail.com> - 2011-08-23 20:08 -0700
Re: is there any principle when writing python function Red John <redjohn367@gmail.com> - 2011-08-24 16:29 -0700
Re: is there any principle when writing python function ting@thsu.org - 2011-08-25 22:20 -0700
Re: is there any principle when writing python function Roy Smith <roy@panix.com> - 2011-08-26 07:15 -0400
Re: is there any principle when writing python function rantingrick <rantingrick@gmail.com> - 2011-08-26 08:20 -0700
Re: is there any principle when writing python function John Gordon <gordon@panix.com> - 2011-08-26 15:40 +0000
Re: is there any principle when writing python function rantingrick <rantingrick@gmail.com> - 2011-08-26 11:05 -0700
Re: is there any principle when writing python function Chris Angelico <rosuav@gmail.com> - 2011-08-27 07:45 +1000
Re: is there any principle when writing python function rantingrick <rantingrick@gmail.com> - 2011-08-26 15:26 -0700
Re: is there any principle when writing python function Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-08-27 11:26 +1000
Re: is there any principle when writing python function Chris Angelico <rosuav@gmail.com> - 2011-08-27 11:37 +1000
Re: is there any principle when writing python function Roy Smith <roy@panix.com> - 2011-08-27 12:41 -0400
Re: is there any principle when writing python function Chris Angelico <rosuav@gmail.com> - 2011-08-28 02:57 +1000
Re: is there any principle when writing python function Emile van Sebille <emile@fenx.com> - 2011-08-27 10:27 -0700
Re: is there any principle when writing python function Ben Finney <ben+python@benfinney.id.au> - 2011-08-28 07:57 +1000
Re: is there any principle when writing python function Emile van Sebille <emile@fenx.com> - 2011-08-27 15:21 -0700
Re: is there any principle when writing python function rantingrick <rantingrick@gmail.com> - 2011-08-27 16:01 -0700
Re: is there any principle when writing python function Roy Smith <roy@panix.com> - 2011-08-27 19:09 -0400
Re: is there any principle when writing python function Stephen Hansen <me+list/python@ixokai.io> - 2011-08-27 16:27 -0700
Re: is there any principle when writing python function Chris Angelico <rosuav@gmail.com> - 2011-08-28 03:31 +1000
Re: is there any principle when writing python function Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-08-28 06:27 +1000
Re: is there any principle when writing python function Chris Angelico <rosuav@gmail.com> - 2011-08-28 06:38 +1000
Re: is there any principle when writing python function Roy Smith <roy@panix.com> - 2011-08-27 17:09 -0400
Re: is there any principle when writing python function Tobiah <tobiah@teranews.com> - 2011-08-26 08:48 -0700
Re: is there any principle when writing python function Chris Angelico <rosuav@gmail.com> - 2011-08-27 02:10 +1000
Re: is there any principle when writing python function Neil Cerutti <neilc@norwich.edu> - 2011-08-29 14:52 +0000
Re: is there any principle when writing python function Chris Angelico <rosuav@gmail.com> - 2011-08-30 04:20 +1000
Re: is there any principle when writing python function Neil Cerutti <neilc@norwich.edu> - 2011-08-29 18:40 +0000
Re: is there any principle when writing python function Chris Angelico <rosuav@gmail.com> - 2011-08-30 05:02 +1000
For some value of “sing” (was: is there any principle when writing python function) Ben Finney <ben+python@benfinney.id.au> - 2011-08-30 08:17 +1000
Re: is there any principle when writing python function Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2011-08-29 23:20 -0700
Re: is there any principle when writing python function Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-08-27 04:16 +1000
Re: is there any principle when writing python function rantingrick <rantingrick@gmail.com> - 2011-08-26 15:37 -0700
Re: is there any principle when writing python function harrismh777 <harmar@member.fsf.org> - 2011-08-27 23:51 -0500
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-08-27 07:45 +1000 |
| Message-ID | <mailman.453.1314395156.27778.python-list@python.org> |
| In reply to | #12238 |
On Sat, Aug 27, 2011 at 4:05 AM, rantingrick <rantingrick@gmail.com> wrote: > Now take a look at MY simple ONE module solution. It has JUST enough > methods and NOT a single more! I disagree - create_widgets() is completely unnecessary in the presence of show(), unless it's possible to show the dialog, hide it, and then re-show it without recreating the widgets. On Sat, Aug 27, 2011 at 4:16 AM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > I can think of at least five reasons apart from re-use why it might be > appropriate to pull out code into its own function or method even if it is > used in one place only: I'm glad you say "might be", because your five reasons aren't always reasons for refactoring. I'll play devil's advocate for a moment, because discussion is both fun and informative: :) > (1) Extensibility. Just earlier today I turned one method into three: > I did this so that subclasses could override the behaviour of each component > individually, even though the caller is not expected to call raw_select or > choose directly. (I may even consider making them private.) Definitely, but it's no value if you make every tiny thing into your own function. Sometimes the best way to code is to use lower-level functionality directly (not wrapping input() inside raw_select() for instance), and letting someone monkey-patch if they want to change your code. A judgment call. > (2) Testing. It is very difficult to reach into the middle of a function and > test part of it. ... By splitting it > into functions, you can test each part in isolation, which requires much > less work. Yes, but 100% coverage isn't that big a deal. If the function does precisely one logical thing, then you don't _need_ to test parts in isolation - you can treat it as a black box and just ensure that it's doing the right thing under various circumstances. However, this ties in nicely with your next point... > (3) Fault isolation. If you have a 100 line function that fails on line 73, > that failure may have been introduced way back in line 16. By splitting the > function up into smaller functions, you can more easily isolate where the > failure comes from, by checking for violated pre- and post-conditions. ... and here's where #2 really shines. If you break your function in two, the natural thing to do is to test each half separately, with the correct preconditions, and examine its output. If your fault was on line 16, your test for that half of the function has a chance of detecting it. I don't have a Devil's Advocate put-down for this one, save the rather weak comment that it's possible to check pre- and post-conditions without refactoring. :) > (4) Maintainability. It's just easier to document and reason about a > function that does one thing, than one that tries to do everything. Which > would you rather work with, individual functions for: > ... omnomnom ... > Even if each function is only called once, maintenance is simpler if the > code is broken up into more easily understood pieces. Yes, as long as you do the job intelligently. Goes back to what I said about naming functions - in your kitchen example, every function has a self-documenting name, which means you've broken it out more-or-less correctly. (I'd still want to have prepare_and_serve_five_course_meal() of course, but it would be calling on all the others.) Breaking something out illogically doesn't help maintainability at all - in fact, it'll make it worse. "So this function does what, exactly? And if I need to add a line of code, ought I to do it here, or over there? Does anyone else actually call this function? MIGHT someone be reaching into my module and calling this function directly? I'd better keep it... ugh." > (5) Machine efficiency. This can go either way. And that's the very best thing to say about efficiency. Ever. In C, I can write static functions and let the compiler inline them; in Java, I tried to do the same thing, and found ridiculous overheads. Ended up making a monolith rather than go through Java's overhead. But if I'd changed what VM I was running it on, that might well have changed. Profile, profile, profile. > So that's four really good reasons for splitting code into functions, and > one borderline one, other than code re-use. There may be others. I'm sure there are. But let's face it: We're programming in PYTHON. Not C, not Erlang, not Pike, not PHP. Python. If this has been the right choice, then we should assume that efficiency isn't king, but readability and maintainability probably are; so the important considerations are not "will it take two extra nanoseconds to execute" but "can my successor understand what the code's doing" and "will he, if he edits my code, have a reasonable expectation that he's not breaking stuff". These are always important. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | rantingrick <rantingrick@gmail.com> |
|---|---|
| Date | 2011-08-26 15:26 -0700 |
| Message-ID | <681242ae-33ed-4440-8918-c7e540e0bf8c@n35g2000yqf.googlegroups.com> |
| In reply to | #12242 |
On Aug 26, 4:45 pm, Chris Angelico <ros...@gmail.com> wrote:
> On Sat, Aug 27, 2011 at 4:05 AM, rantingrick <rantingr...@gmail.com> wrote:
> > Now take a look at MY simple ONE module solution. It has JUST enough
> > methods and NOT a single more!
>
> I disagree - create_widgets() is completely unnecessary in the
> presence of show(),
Well since you cannot see the underlying code i won't be too harsh on
you :), but yes, i can assure you that create widgets IS necessary for
readability. show() calls "self.create_widgets()" then adds a special
hit tag to the text widget and sets up a modal behavior of the dialog,
it's only 5-7 lines of setup code but i think the separation is
warranted.
Could i have rolled all the create_widgets() code into the show()
method? Of course, however i do see a good reason for separation here
for the sake of readability. Although i must admit, had the interface
been much larger i most assuredly would have rolled it together.
> unless it's possible to show the dialog, hide it,
> and then re-show it without recreating the widgets.
Yes the instance lives on between session to save state. Also the
"find_again" binding of the text widget calls the
SearchReplaceDialog.find_again() method when {CONTROL+G} event fires.
> I'm sure there are. But let's face it: We're programming in PYTHON.
> Not C, not Erlang, not Pike, not PHP. Python. If this has been the
> right choice, then we should assume that efficiency isn't king, but
> readability and maintainability probably are; so the important
> considerations are not "will it take two extra nanoseconds to
> execute" but "can my successor understand what the code's doing" and
> "will he, if he edits my code, have a reasonable expectation that
> he's not breaking stuff". These are always important.
Bravo! That has to be most lucid and intelligent statement from you to
date. And i must say the warm fuzzies i got from imagining the defeat
D'Aprano must have felt whist reading it left me with a nice feeling.
How do like them apples, D'Aprano? :-)
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-08-27 11:26 +1000 |
| Message-ID | <4e5847bc$0$29978$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #12242 |
Chris Angelico wrote: > On Sat, Aug 27, 2011 at 4:16 AM, Steven D'Aprano > <steve+comp.lang.python@pearwood.info> wrote: >> I can think of at least five reasons apart from re-use why it might be >> appropriate to pull out code into its own function or method even if it >> is used in one place only: > > I'm glad you say "might be", because your five reasons aren't always > reasons for refactoring. I'll play devil's advocate for a moment, > because discussion is both fun and informative: :) Naturally :) I say "might be" because I mean it: these arguments have to be weighed up against the argument against breaking code out of functions. It's easy to imagine an extreme case where there are a billion *tiny* functions, each of which does one micro-operation: def f1(x): return x + 1 def f2(x): return 3*x def f3(x): return f2(f1(x)) # instead of 3*(x+1) ... If spaghetti code (GOTOs tangled all through the code with no structure) is bad, so is ravioli code (code bundled up into tiny parcels and then thrown together higgledy-piggledy). Both cases can lead to an unmaintainable mess. Nobody is arguing that "More Functions Is Always Good". Sensible coders understand that you should seek a happy medium and not introduce more functions just for the sake of having More! Functions!. But I'm not arguing with you, we're in agreement. One last comment though: [...] > Definitely, but it's no value if you make every tiny thing into your > own function. Sometimes the best way to code is to use lower-level > functionality directly (not wrapping input() inside raw_select() for > instance), and letting someone monkey-patch if they want to change > your code. A judgment call. I agree on the first part (don't split *everything* into functions) but I think that the monkey-patch idea is tricky and dangerous in practice. The first problem is, how do you know what needs to be monkey-patched? You may not have access to the source code to read, and it may not be as obvious as "oh, it gets input from the user, so it must be calling input()". Second, even if you know what to monkey-patch, it's really hard to isolate the modification to just the method you want. By their nature, monkey- patches apply globally to the module. And if you patch the builtins module, they apply *everywhere*. So while monkey-patching can work, it's tricky to get it right and it should be left as a last resort. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-08-27 11:37 +1000 |
| Message-ID | <mailman.455.1314409507.27778.python-list@python.org> |
| In reply to | #12246 |
On Sat, Aug 27, 2011 at 11:26 AM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > I say "might be" because I mean it: these arguments have to be weighed up > against the argument against breaking code out of functions. It's easy to > imagine an extreme case where there are a billion *tiny* functions, each of > which does one micro-operation: > > def f1(x): return x + 1 > def f2(x): return 3*x > def f3(x): return f2(f1(x)) # instead of 3*(x+1) This fails the "give it a decent name" test. Can you name these functions according to what they do, as opposed to how they do it? For instance: def add_flagfall(x): return x + 1 # add a $1 flagfall to the price def add_tax(x): return 3*x # this is seriously nasty tax def real_price(x): return add_tax(add_flagfall(x)) # instead of 3*(x+1) This would be acceptable, because each micro-operation has real meaning. I'd prefer to do it as constants rather than functions, but at least they're justifying their names. And you're absolutely right about monkey-patching. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2011-08-27 12:41 -0400 |
| Message-ID | <roy-C5BFB8.12413627082011@news.panix.com> |
| In reply to | #12242 |
Chris Angelico <rosuav@gmail.com> wrote: > the important > considerations are not "will it take two extra nanoseconds to execute" > but "can my successor understand what the code's doing" and "will he, > if he edits my code, have a reasonable expectation that he's not > breaking stuff". These are always important. Forget about your successor. Will *you* be able to figure out what you did 6 months from now? I can't tell you how many times I've looked at some piece of code, muttered, "Who wrote this crap?" and called up the checkin history only to discover that *I* wrote it :-)
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-08-28 02:57 +1000 |
| Message-ID | <mailman.465.1314464273.27778.python-list@python.org> |
| In reply to | #12270 |
On Sun, Aug 28, 2011 at 2:41 AM, Roy Smith <roy@panix.com> wrote: > Forget about your successor. Will *you* be able to figure out what you > did 6 months from now? I can't tell you how many times I've looked at > some piece of code, muttered, "Who wrote this crap?" and called up the > checkin history only to discover that *I* wrote it :-) Heh. In that case, you were your own successor :) I always word it as a different person to dodge the "But I'll remember!" excuse, but you are absolutely right, and I've had that exact same experience myself. Fred comes up to me and says, "How do I use FooMatic?" Me: "I dunno, ask Joe." Fred: "But didn't you write it?" Me: "Yeah, that was years ago, I've forgotten. Ask Joe, he still uses the program." ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Emile van Sebille <emile@fenx.com> |
|---|---|
| Date | 2011-08-27 10:27 -0700 |
| Message-ID | <mailman.468.1314466082.27778.python-list@python.org> |
| In reply to | #12270 |
On 8/27/2011 9:41 AM Roy Smith said... > Chris Angelico<rosuav@gmail.com> wrote: > >> the important >> considerations are not "will it take two extra nanoseconds to execute" >> but "can my successor understand what the code's doing" and "will he, >> if he edits my code, have a reasonable expectation that he's not >> breaking stuff". These are always important. > > Forget about your successor. Will *you* be able to figure out what you > did 6 months from now? I can't tell you how many times I've looked at > some piece of code, muttered, "Who wrote this crap?" and called up the > checkin history only to discover that *I* wrote it :-) When you consider that you're looking at the code six months later it's likely for one of three reasons: you have to fix a bug; you need to add features; or the code's only now getting used. So you then take the extra 20-30 minutes, tease the code apart, refactor as needed and end up with better more readable debugged code. I consider that the right time to do this type of cleanup. For all the crap I write that works well for six months before needing to be cleaned up, there's a whole lot more crap that never gets looked at again that I didn't clean up and never spent the extra 20-30 minutes considering how my future self might view what I wrote. I'm not suggesting that you shouldn't develop good coding habits that adhere to established standards and result in well structured readable code, only that if that ugly piece of code works that you move on. You can bullet proof it after you uncover the vulnerabilities. Code is first and foremost written to be executed. Emile
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2011-08-28 07:57 +1000 |
| Message-ID | <87vctitt43.fsf@benfinney.id.au> |
| In reply to | #12279 |
Emile van Sebille <emile@fenx.com> writes:
> Code is first and foremost written to be executed.
−1 QotW. I disagree, and have a counter-aphorism:
“Programs must be written for people to read, and only incidentally for
machines to execute.”
—Abelson & Sussman, _Structure and Interpretation of Computer Programs_
Yes, the primary *function* of the code you write is for it to
eventually execute. But the primary *audience* of the text you type into
your buffer is not the computer, but the humans who will read it. That's
what must be foremost in your mind while writing that text.
--
\ “If you can't beat them, arrange to have them beaten.” —George |
`\ Carlin |
_o__) |
Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Emile van Sebille <emile@fenx.com> |
|---|---|
| Date | 2011-08-27 15:21 -0700 |
| Message-ID | <mailman.489.1314483681.27778.python-list@python.org> |
| In reply to | #12307 |
On 8/27/2011 2:57 PM Ben Finney said... > Emile van Sebille<emile@fenx.com> writes: > >> Code is first and foremost written to be executed. > > “Programs must be written for people to read, and only incidentally for > machines to execute.” > —Abelson& Sussman, _Structure and Interpretation of Computer Programs_ > That's certainly self-fulfilling -- code that doesn't execute will need to be read to be understood, and to be fixed so that it does run. Nobody cares about code not intended to be executed. Pretty it up as much as you have free time to do so to enlighten your intended audience. Code that runs from the offset may not ever again need to be read, so the only audience will ever be the processor. I find it much to easy to waste enormous amounts of time prettying up code that works. Pretty it up when it doesn't -- that's the code that needs the attention. Emile > Yes, the primary *function* of the code you write is for it to > eventually execute. But the primary *audience* of the text you type into > your buffer is not the computer, but the humans who will read it. That's > what must be foremost in your mind while writing that text. >
[toc] | [prev] | [next] | [standalone]
| From | rantingrick <rantingrick@gmail.com> |
|---|---|
| Date | 2011-08-27 16:01 -0700 |
| Message-ID | <6930db73-816a-44a9-be1f-0915ced571a3@p10g2000yqi.googlegroups.com> |
| In reply to | #12308 |
On Aug 27, 5:21 pm, Emile van Sebille <em...@fenx.com> wrote: > On 8/27/2011 2:57 PM Ben Finney said... > > > Emile van Sebille<em...@fenx.com> writes: > > >> Code is first and foremost written to be executed. > > > “Programs must be written for people to read, and only incidentally for > > machines to execute.” > > —Abelson& Sussman, _Structure and Interpretation of Computer Programs_ > > That's certainly self-fulfilling -- code that doesn't execute will need > to be read to be understood, and to be fixed so that it does run. > Nobody cares about code not intended to be executed. Pretty it up as > much as you have free time to do so to enlighten your intended audience. > > Code that runs from the offset may not ever again need to be read, so > the only audience will ever be the processor. WRONG! Code may need to be extended someday no matter HOW well it executes today. Also, code need to be readable so the readers can learn from it.
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2011-08-27 19:09 -0400 |
| Message-ID | <roy-EC1B60.19094127082011@news.panix.com> |
| In reply to | #12308 |
In article <mailman.489.1314483681.27778.python-list@python.org>, Emile van Sebille <emile@fenx.com> wrote: > code that doesn't execute will need to be read to be understood, and > to be fixed so that it does run. That is certainly true, but it's not the whole story. Even code that works perfectly today will need to be modified in the future. Business requirements change. Your code will need to be ported to a new OS. You'll need to make it work for 64-bit. Or i18n. Or y2k (well, don't need to worry about that one any more). Or with a different run-time library. A new complier. A different database. Regulatory changes will impose new requirements Or, your company will get bought and you'll need to interface with a whole new system. Code is never done. At least not until the project is dead.
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hansen <me+list/python@ixokai.io> |
|---|---|
| Date | 2011-08-27 16:27 -0700 |
| Message-ID | <mailman.492.1314487653.27778.python-list@python.org> |
| In reply to | #12307 |
[Multipart message — attachments visible in raw view] — view raw
On 8/27/11 3:21 PM, Emile van Sebille wrote: > On 8/27/2011 2:57 PM Ben Finney said... >> Emile van Sebille<emile@fenx.com> writes: >> >>> Code is first and foremost written to be executed. >> > > >> “Programs must be written for people to read, and only >> incidentally for >> machines to execute.” >> —Abelson& Sussman, _Structure and Interpretation of Computer >> Programs_ >> > > That's certainly self-fulfilling -- code that doesn't execute will need > to be read to be understood, and to be fixed so that it does run. Nobody > cares about code not intended to be executed. Pretty it up as much as > you have free time to do so to enlighten your intended audience. Er, you're interpreting the quote... way overboard. No one's talking about code that isn't intended to be executed, I don't think; the quote includes, "and only incidentally for machines to execute." That's still the there, and its still important. It should just not be the prime concern while actually writing the code. The code has to actually do something. If not, obviously you'll have to change it. The Pythonic emphasis on doing readable, pretty code isn't JUST about making code that just looks good; its not merely an aesthetic that the community endorses. And although people often tout the very valid reason why readability counts-- that code is often read more then written, and that coming back to a chunk of code 6 months later and being able to understand fully what its doing is very important... that's not the only reason readability counts. Readable, pretty, elegantly crafted code is also far more likely to be *correct* code. However, this: > Code that runs from the offset may not ever again need to be read, so > the only audience will ever be the processor. > > I find it much to easy to waste enormous amounts of time prettying up > code that works. Pretty it up when it doesn't -- that's the code that > needs the attention. ... seems to me to be a rather significant self-fulfilling prophecy in its own right. The chances that the code does what its supposed to do, accurately, and without any bugs, goes down in my experience quite significantly the farther away from "pretty" it is. If you code some crazy, overly clever, poorly organized, messy chunk of something that /works/ -- that's fine and dandy. But unless you have some /seriously/ comprehensive test coverage then the chances that you can eyeball it and be sure it doesn't have some subtle bugs that will call you back to fix it later, is pretty low. In my experience. Its not that pretty code is bug-free, but code which is easily read and understood is vastly more likely to be functioning correctly and reliably. Also... it just does not take that much time to make "pretty code". It really doesn't. The entire idea that its hard, time-consuming, effort-draining or difficult to make code clean and "pretty" from the get-go is just wrong. You don't need to do a major "prettying up" stage after the fact. Sure, sometimes refactoring would greatly help a body of code as it evolves, but you can do that as it becomes beneficial for maintenance reasons and not just for pretty's sake. -- Stephen Hansen ... Also: Ixokai ... Mail: me+list/python (AT) ixokai (DOT) io ... Blog: http://meh.ixokai.io/
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-08-28 03:31 +1000 |
| Message-ID | <mailman.470.1314466282.27778.python-list@python.org> |
| In reply to | #12270 |
On Sun, Aug 28, 2011 at 3:27 AM, Emile van Sebille <emile@fenx.com> wrote: > Code is first and foremost written to be executed. > +1 QOTW. Yes, it'll be read, and most likely read several times, by humans, but ultimately its purpose is to be executed. And in the case of some code, the programmer needs the same treatment, but that's a different issue... ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-08-28 06:27 +1000 |
| Message-ID | <4e595334$0$30000$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #12281 |
Chris Angelico wrote: > On Sun, Aug 28, 2011 at 3:27 AM, Emile van Sebille <emile@fenx.com> wrote: >> Code is first and foremost written to be executed. >> > > +1 QOTW. Yes, it'll be read, and most likely read several times, by > humans, but ultimately its purpose is to be executed. You've never noticed the masses of code written in text books, blogs, web pages, discussion forums like this one, etc.? Real world code for production is usually messy and complicated and filled with data validation and error checking code. There's a lot of code without that, because it was written explicitly to be read by humans, and the fact that it may be executed as well is incidental. Some code is even written in pseudo-code that *cannot* be executed. It's clear to me that a non-trivial amount of code is specifically written to be consumed by other humans, not by machines. It seems to me that, broadly speaking, there are languages designed with execution of code as the primary purpose: Fortran, C, Lisp, Java, PL/I, APL, Forth, ... and there are languages designed with *writing* of code as the primary purpose: Perl, AWK, sed, bash, ... and then there are languages where *reading* is the primary purpose: Python, Ruby, Hypertalk, Inform 7, Pascal, AppleScript, ... and then there are languages where the torment of the damned is the primary purpose: INTERCAL, Oook, Brainf*ck, Whitespace, Malbolge, ... and then there are languages with few, or no, design principles to speak of, or as compromise languages that (deliberately or accidentally) straddle the other categories. It all depends on the motivation and values of the language designer, and the trade-offs the language makes. Which category any specific language may fall into may be a matter of degree, or a matter of opinion, or both. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-08-28 06:38 +1000 |
| Message-ID | <mailman.482.1314477514.27778.python-list@python.org> |
| In reply to | #12296 |
On Sun, Aug 28, 2011 at 6:27 AM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > You've never noticed the masses of code written in text books, blogs, web > pages, discussion forums like this one, etc.? > > Real world code for production is usually messy and complicated and filled > with data validation and error checking code. There's a lot of code without > that, because it was written explicitly to be read by humans, and the fact > that it may be executed as well is incidental. Some code is even written in > pseudo-code that *cannot* be executed. It's clear to me that a non-trivial > amount of code is specifically written to be consumed by other humans, not > by machines. Yes, I'm aware of the quantities of code that are primarily for human consumption. But in the original context, which was of editing code six months down the track, I still believe that such code is primarily for the machine. In that situation, there are times when it's not worth the hassle of writing beautiful code; you'd do better to just get that code generated and in operation. Same goes for lint tools and debuggers - sometimes, it's easier to just put the code into a live situation (or a perfect copy of) and see where it breaks, than to use a simulation/test harness. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2011-08-27 17:09 -0400 |
| Message-ID | <roy-636404.17095127082011@news.panix.com> |
| In reply to | #12296 |
In article <4e595334$0$30000$c3e8da3$5496439d@news.astraweb.com>, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > and then there are languages with few, or no, design principles to speak of Oh, like PHP?
[toc] | [prev] | [next] | [standalone]
| From | Tobiah <tobiah@teranews.com> |
|---|---|
| Date | 2011-08-26 08:48 -0700 |
| Message-ID | <ifP5q.1635$EP3.888@newsfe05.iad> |
| In reply to | #12221 |
> Furthermore: If you are moving code out of one function to ONLY be
> called by that ONE function then you are a bad programmer and should
> have your editor taken away for six months. You should ONLY create
> more func/methods if those func/methods will be called from two or
> more places in the code. The very essence of func/meths is the fact
> that they are reusable.
While I understand and agree with that basic tenet, I think
that the capitalized 'ONLY' is too strong. I do split out
code into function for readability, even when the function
will only be called from the place from which I split it out.
I don't think that this adds to the 'spaghetti' factor. It
can make my life much easier when I go to debug my own code
years later.
In python, I use a small function to block out an idea
as a sort of pseudo code, although it's valid python. Then
I just define the supporting functions, and the task is done:
def validate_registrants():
for dude in get_registrants():
id = get_id(dude)
amount_paid = get_amount_paid(dude)
amount_owed = get_amount_owed(dude)
if amount_paid != amount_owed():
flag(dude)
I get that this cries out for a 'dude' object, but
I'm just making a point. When I go back to this code,
I can very quickly see what the overall flow is, and
jump to the problem area by function name. The above
block might expand to a couple of hundred lines if I
didn't split it out like this.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-08-27 02:10 +1000 |
| Message-ID | <mailman.446.1314375037.27778.python-list@python.org> |
| In reply to | #12227 |
On Sat, Aug 27, 2011 at 1:48 AM, Tobiah <tobiah@teranews.com> wrote: > While I understand and agree with that basic tenet, I think > that the capitalized 'ONLY' is too strong. I do split out > code into function for readability, even when the function > will only be called from the place from which I split it out. > This can be good and can be bad. It's good when it aids readability; it's bad when you need to pass practically the entire locals() as function arguments and/or return values. I would split the function only when both halves (caller and callee) can be given short and useful names - if you can't explain what a block of code does in a few words, it's probably a poor choice for splitting out into a function. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Neil Cerutti <neilc@norwich.edu> |
|---|---|
| Date | 2011-08-29 14:52 +0000 |
| Message-ID | <9c1ndoFj9iU10@mid.individual.net> |
| In reply to | #12231 |
On 2011-08-26, Chris Angelico <rosuav@gmail.com> wrote: > On Sat, Aug 27, 2011 at 1:48 AM, Tobiah <tobiah@teranews.com> > wrote: >> While I understand and agree with that basic tenet, I think >> that the capitalized 'ONLY' is too strong. ?I do split out >> code into function for readability, even when the function >> will only be called from the place from which I split it out. > > This can be good and can be bad. It's good when it aids > readability; it's bad when you need to pass practically the > entire locals() as function arguments and/or return values. Even when lots of context is needed, defining the context with function calls is a big improvement over directly using names in a module's global namespace. Sometimes repeatedly reused context suggests that creating new classes of objects might be a good idea. > I would split the function only when both halves (caller and > callee) can be given short and useful names - if you can't > explain what a block of code does in a few words, it's probably > a poor choice for splitting out into a function. I agree, except for the implied unconditional preference for short names. I believe the length of a name should usually be proportional to the scope of the object it represents. In my house, I'm dad. In my chorus, I'm Neil. In town I'm Neil Cerutti, and in the global scope I have to use a meaningless unique identifier. Hopefully no Python namespace ever gets that big. -- Neil Cerutti
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-08-30 04:20 +1000 |
| Message-ID | <mailman.550.1314642053.27778.python-list@python.org> |
| In reply to | #12404 |
On Tue, Aug 30, 2011 at 12:52 AM, Neil Cerutti <neilc@norwich.edu> wrote: >> I would split the function only when both halves (caller and >> callee) can be given short and useful names - if you can't >> explain what a block of code does in a few words, it's probably >> a poor choice for splitting out into a function. > > I agree, except for the implied unconditional preference for > short names. I believe the length of a name should usually be > proportional to the scope of the object it represents. Oh,I definitely prefer short names to this: http://thedailywtf.com/Articles/Double-Line.aspx "Short" is a relative term. If the function's name is 20 characters long and meaningful, that's fine. > In my house, I'm dad. In my chorus, I'm Neil. In town I'm Neil > Cerutti, and in the global scope I have to use a meaningless > unique identifier. Hopefully no Python namespace ever gets that > big. Chorus? Does that imply that you sing? Neat :) What you have, I think, is a module named Cerutti, in which you have a class of which Neil is an instance. Inside method functions, you can be referenced by "self" (which is to code what pronouns are to English); outside of them, you are referred to as Neil; and outside the module, Cerutti.Neil is the cleanest way to reference you. But your name is still Neil, no matter how you're referenced. Chris Angelico whose name is sometimes Chris, sometimes Rosuav, and sometimes "Chris or Michael" by people who can't distinguish him from his brother
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | comp.lang.python
csiph-web