Idiomatic Python or "Tabs vs. Spaces"

Posted on
Wed Mar 07, 2018 7:26 am
DaveL17 offline
User avatar
Posts: 6744
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Idiomatic Python or "Tabs vs. Spaces"

Made you look. :D

Seriously though, I'm in an never-ending quest to make my code more Pythonic and idiomatic. I was doing some code clean up and found what seems to be an inefficient use of handling types when making a function call -- where I always expect the arguments passed to the function to be of a certain type. Consider this simple example which shows essentially what I was doing:

Code: Select all
def addNumbers(a, b):
    c = float(a) + float(b)
    print(c)

a = float(1)
b = float(2)
addNumbers(a, b)

In the function, I have the added safety net of (re)floating the arguments to ensure they're the proper type before I continue, but could also NOT do that and instead do this:
Code: Select all
def addNumbers(a, b):
    if not isinstance(a, float) or not isinstance(b, float):
        print('wrong type')
    else:
        c = a + b
        print(c)

a = float(1)
b = float(2)
addNumbers(a, b)

or something similar.

What's the "right" way to handle argument type enforcement? What did they teach you "real" developers in programmer school?

I realize there's a hundred different ways you could do it, but what's "best"?

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Wed Mar 07, 2018 8:18 am
FlyingDiver offline
User avatar
Posts: 7189
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Idiomatic Python or "Tabs vs. Spaces"

What's the "right" way to handle argument type enforcement? What did they teach you "real" developers in programmer school?


I never went to programmer school, but when I did take programming classes as part of my engineering curriculum (mostly back in the late 70s), the languages we used all required explicit typing on function calls, I think. Basic , C, Algol, Pascal, Fortran were the languages that I started with.

I would argue that the more Python-ish solution would be to take anything, and throw an exception if you can't convert it to a float. Something like:
Code: Select all
def addNumbers(a, b):
    try:
        c = float(a) + float(b)
    except TypeError:
        print('wrong type')
        raise
   
    print(c)

try:
    addNumbers(1, 2)
    addNumbers(1.0, 2.0)
    addNumbers("1", "2")
except:
    pass

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Wed Mar 07, 2018 8:25 am
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: Idiomatic Python or "Tabs vs. Spaces"

I also do what Joe does when I have no other choice. I hate reverting to the "try it and trap the error" if I can avoid it, preferring to try to figure it out first if possible. Once exception is that I wrap almost every single method I write in Try End Try because it makes it a lot easier to debug problems. That's a habit I picked up when the first error trapping came out in languages and have used it ever since.

But, for me, I generally try something along the lines of:
Code: Select all
if type(a) == int or type(a) == float:
   b = float(a)
elif type(a) == string or type(a) == unicode:
  try
     .....

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Wed Mar 07, 2018 12:46 pm
jay (support) offline
Site Admin
User avatar
Posts: 18200
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Idiomatic Python or "Tabs vs. Spaces"

I read somewhere that a core philosophy of Guido's is to try it and deal with the exceptional case rather than try to validate first. This is often referred to as duck typing then handling the exceptions (@FlyingDiver's example).

This is somewhat backwards of what I was taught, but then again I learned fundamentals so long ago that the try/except pattern really wasn't much of a thing (I think Ada was the first language I learned that had a similar pattern) and incorrect types could actually cause not only the program to crash but the computer itself. I still find myself trying to do type checks first, but I'm getting better at just doing stuff and dealing with the exceptional consequences instead.

<tangent-feel free to skip>

This brought me to a tangental thought (along with the other thread where we were talking about how old we are): I've learned/used way too many languages in my life. To wit: Basic, Pascal, Assembler, Scheme, C, Ada, AppleScript, Lisp, C++, Perl, Java, SQL, Objective-C, PHP, JavaScript, Python (I'm not including markup languages like HTML or Markdown). The first 4 were learned in college but never used for any "production" code, everything else has been used at one time or another in a production environment (and I think they're roughly the order in which I started learning/using them). Just before Python, I started looking at Ruby but never got past the basic syntax (though I think I did fix a bug when the reflector backend was in Ruby).

But I really hope that I'm done. At one time, I found learning a new language a fun challenge - for me, learning new programming languages was like others collect coins. At this point though I'm pretty sure I'd just find it frustrating. I hate that I have to know JavaScript at all (and I don't know it very well), I'd much rather just use Python for the rest of my programming life.

</tangent>

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Wed Mar 07, 2018 12:59 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: Idiomatic Python or "Tabs vs. Spaces"

jay (support) wrote:
This is somewhat backwards of what I was taught, but then again I learned fundamentals so long ago that the try/except pattern really wasn't much of a thing (I think Ada was the first language I learned that had a similar pattern)

Same here, I've been in that mode ever since. It just has always seemed to me that duck typing was a lazy way to test conditions when, particularly in a small scripting language, there's negligible or no performance hit for proper typing.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Wed Mar 07, 2018 1:30 pm
jay (support) offline
Site Admin
User avatar
Posts: 18200
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Idiomatic Python or "Tabs vs. Spaces"

Colorado4Wheeler wrote:
Same here, I've been in that mode ever since. It just has always seemed to me that duck typing was a lazy way to test conditions when, particularly in a small scripting language, there's negligible or no performance hit for proper typing.


I'm finding that I like the pattern more. I think it's more aesthetically pleasing to read/follow in that the positive stuff happens first (everything works as planned) then you can see what can go wrong. I suspect your "lazy" feeling just stems from getting drilled when you were learning that type checking was so super important and you were just being lazy if you didn't do it. I know I was. Today's modern run-time environments are so much better at adapting to runtime errors that those old precepts don't really hold any more.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Wed Mar 07, 2018 1:45 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: Idiomatic Python or "Tabs vs. Spaces"

jay (support) wrote:
I think it's more aesthetically pleasing to read/follow in that the positive stuff happens first (everything works as planned) then you can see what can go wrong

I see that, but if the entire "everything works" portion is surround in multiple Try...Excepts then that can look messy too.

jay (support) wrote:
I suspect your "lazy" feeling just stems from getting drilled when you were learning that type checking was so super important and you were just being lazy if you didn't do it.

Yup, goes back to the whole idea that error trapping is the single biggest thing that most developers fail to do and they are lazy when they don't trap, even lazier if they don't prevent the things that cause it to error. Changing times I suppose. Kids today :P.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Wed Mar 07, 2018 2:57 pm
FlyingDiver offline
User avatar
Posts: 7189
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Idiomatic Python or "Tabs vs. Spaces"

I think one of the reasons that Guido leans the way he does is that since everything in Python is an object, you don't really know ahead of time which exact objects (variable types) will work and which won't. For instance, using the original example, what if someone had subclassed float for some reason? Then the tests for floats would (probably) fail, but the operations themselves probably would not have. Would it really be wrong to reject the function call?

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Wed Mar 07, 2018 4:37 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: Idiomatic Python or "Tabs vs. Spaces"

I see the logic in it, I do, but there are old habits to break to let everything that's not ideal drop to a trap and then deal with. It seems like the ultimate procrastination of programming. In your case, you are right, if float was subclassed or reclassed then the language works but that requires that you don't have control of your own code - which is fine in a team environment but then that also means you don't have a map or a plan. To me it all seems sloppy, but that doesn't mean that I also don't see the validity of it too.

I've always written my code as "trust but verify" rather than "innocent until proven guilty" which are, to me, excellent analogies for the two coding styles.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Wed Mar 07, 2018 4:43 pm
FlyingDiver offline
User avatar
Posts: 7189
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Idiomatic Python or "Tabs vs. Spaces"

Colorado4Wheeler wrote:
I've always written my code as "trust but verify" rather than "innocent until proven guilty" which are, to me, excellent analogies for the two coding styles.


I like that. ;)

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Wed Mar 07, 2018 5:07 pm
DaveL17 offline
User avatar
Posts: 6744
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Idiomatic Python or "Tabs vs. Spaces"

I really appreciate the thoughtful responses to this thread.

FlyingDiver wrote:
I would argue that the more Python-ish solution would be to take anything, and throw an exception if you can't convert it

It seems like that's the common theme that's emerging, and I do see the value in it. In other words, the method is in charge and wants a float so try to float whatever arrives and deal with the consequences if that doesn't work.

Colorado4Wheeler wrote:
Once exception is that I wrap almost every single method I write in Try End Try because it makes it a lot easier to debug problems.


I like this too. While learning through doing, I was entirely too zealous with try/except and need to be more judicious. I do run across errors in my code where I sometimes have to go methods deep to figure out where the trouble is.

jay wrote:
I still find myself trying to do type checks first, but I'm getting better at just doing stuff and dealing with the exceptional consequences instead.


Yep, I think that's what I'll do.

I know I'm supposed to start writing a new project with a pen and not a keyboard, but I still wind up building things iteratively (build a little, debug it, build a little..) and very literally (writing out long passages and then consolidating later) which is what leads me to find situations where I have these unintended redundancies. Sure, the code still works--nothing illegal in re-floating a float--but I always feel my code could use a little "lightness".

Appreciate it folks.

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Thu Mar 08, 2018 12:39 pm
jay (support) offline
Site Admin
User avatar
Posts: 18200
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Idiomatic Python or "Tabs vs. Spaces"

DaveL17 wrote:
I know I'm supposed to start writing a new project with a pen and not a keyboard


I think the current state of the art is TDD (test driven development) - where you write your tests first. Safe to say I don't particularly like that approach... :P

DaveL17 wrote:
but I still wind up building things iteratively (build a little, debug it, build a little..) and very literally (writing out long passages and then consolidating later) which is what leads me to find situations where I have these unintended redundancies. Sure, the code still works--nothing illegal in re-floating a float--but I always feel my code could use a little "lightness".


Ultimately I think this is the right approach. I think the key is to refactor when it's obvious that it's needed. Iterative development is great, but it can lead to cruft. Taking the time to refactor, even just sections of code, will help reduce the cruft and potential bugs related to it. It may take a little longer, but I think it's worth it in the end.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Thu Mar 08, 2018 1:26 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: Idiomatic Python or "Tabs vs. Spaces"

jay (support) wrote:
Ultimately I think this is the right approach.

I agree, it's how I've always developed as well. I may storyboard some, particularly when developing in a team, but overall I like to hit the code immediately so I can proof it and determine what needs to happen to make that process better.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Thu Mar 08, 2018 1:56 pm
DaveL17 offline
User avatar
Posts: 6744
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Idiomatic Python or "Tabs vs. Spaces"

jay (support) wrote:
Ultimately I think this is the right approach.

So what you're saying is that I'm on the vanguard of development. I like the sound of that. :D

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Thu Mar 08, 2018 2:01 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: Idiomatic Python or "Tabs vs. Spaces"

DaveL17 wrote:
So what you're saying is that I'm on the vanguard of development. I like the sound of that.

That's what I heard. Amaze-balls.

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Who is online

Users browsing this forum: No registered users and 2 guests

cron