Re: Object-oriented philosophy

2018-09-11 Thread Abdur-Rahmaan Janhangeer
i know about the ban but since marko was getting it was wondering how

thanks !

Abdur-Rahmaan Janhangeer
https://github.com/Abdur-rahmaanJ
Mauritius

Ranting Rick is banned from posting to python-list. (And maybe also
> from other Python project lists, I'm not sure about that.)
> You can read about further details in the topic "Users banned".
>
> You should only see his messages if you read the Newsgroup or if
> someone quotes a message that Rick has posted on the Newsgroup, since
> the Newsgroup is unmoderated.
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-11 Thread Abdur-Rahmaan Janhangeer
i did not see rick's mail on my gmail

Abdur-Rahmaan Janhangeer
https://github.com/Abdur-rahmaanJ
Mauritius


Rick Johnson :
>
> > Michael F. Stemper wrote:
> >> Object-oriented philosophy
> > [...] [...] [...]
> >
> > So, to make a long story short, you may want to do some
> > googling...
>
> Long story short, Michael, Rick is a masterful troll extraordinaire.
> Highly amusing when you're in the mood.
>
>
> Marko
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-11 Thread Michael F. Stemper
On 2018-09-11 01:59, Marko Rauhamaa wrote:
> Rick Johnson :
> 
>> Michael F. Stemper wrote:
>>> Object-oriented philosophy
>> [...] [...] [...]
>>
>> So, to make a long story short, you may want to do some
>> googling...
> 
> Long story short, Michael, Rick is a masterful troll extraordinaire.

Is that why he misquoted "Big Yellow Taxi"? (Hint: a song with "raped"
in it would not have had any air time in 1970.)

> Highly amusing when you're in the mood.

Incoherent, too.

-- 
Michael F. Stemper
Galatians 3:28
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-11 Thread Marko Rauhamaa
Rick Johnson :

> Michael F. Stemper wrote:
>> Object-oriented philosophy
> [...] [...] [...]
>
> So, to make a long story short, you may want to do some
> googling...

Long story short, Michael, Rick is a masterful troll extraordinaire.
Highly amusing when you're in the mood.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-11 Thread Antoon Pardon
On 07-09-18 22:08, Michael F. Stemper wrote:
>
>>  try
>>id = xmlmodel.attrib['name']
>>  except KeyError:
>>id = "constant power"
> Never mind! After I continued testing, I realized that the above
> should have been written as:
>
>   if 'name' in xmlmodel.attrib:
> id = xmlmodel.attrib['name']
>   else:
> id = "constant power"
>
> 

How about:

id = xmlmodel.attrib.get('name', "constant power")


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-09 Thread Abdur-Rahmaan Janhangeer
 just see who a company employ as a py eng, ask him.

Abdur-Rahmaan Janhangeer
https://github.com/Abdur-rahmaanJ
Mauritius


>
> Does anyone here know anyone who would refer to themselves as a "Python
> engineer" with a straight face? I merely ask...
>
> -- Thomas
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-09 Thread Amirouche Boubekki
Le jeu. 6 sept. 2018 à 16:05, Michael F. Stemper
 a écrit :
>
> How does one judge when it's worthwhile to do this and when it's
> not? What criteria would somebody seasoned in OO and python use
> to say "good idea" vs "don't waste your time"?
>

I may qualify as experienced with Python, that being said, "to class
or not to class?" is still an open question.
I have been working on some stuff using Scheme and no OO machinery and
it worked well. Also, mocked
some stuff in the frontend using a purely functional approach. It works.

So, I am wondering what's the purpose of OOP?

Class-based error handling with exception and inheritance is very
handy maybe perfect.

I have been burned by Django class everywhere (ORM, REST, admin UI,
data validation, etc?).

Another place where class shines is when you have the same interface
for different objects.
Like others have said, it's more "duck typing" than OOP. Again
following the "common interface"
an abstract class is helpful and in this case, inheritance makes
sense. But that doesn't require
more that one or two level deep inheritance.

So, in the end, I think that except for error handling and the
subject.verb(**complements) syntax. OOP is dubious.

Multiple inheritances outside mixin anyone? Metaclass outside ORM / ODM?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-09 Thread Gene Heskett
On Sunday 09 September 2018 08:19:52 Gilmeh Serda wrote:

> On Thu, 06 Sep 2018 18:07:55 +0200, Thomas Jollans wrote:
> >> Also, get someone, preferrable a python engineer to review your
> >> code.
> >
> > Does anyone here know anyone who would refer to themselves as a
> > "Python engineer" with a straight face? I merely ask...
>
> We're all tinker bells.
>
> --
> Gilmeh

And some of us are just senior citizen tinkerers, like me :) I lurk here, 
hoping some of it will rub into me.


-- 
Cheers, Gene Heskett
--
"There are four boxes to be used in defense of liberty:
 soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
Genes Web page 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-08 Thread Michael F. Stemper
On 2018-09-06 16:04, Stefan Ram wrote:
> "Michael F. Stemper"  writes:
>>> You have a operation »Resistance( V )«.
>> Mathematically, that's an operation, I suppose. I tend to think of it
>> as either a function or a method.
> 
>   I deliberately did not use neither "a function" nor
>   "a method" because by "operation" I meant something else,
>   I meant the three methods "Resistance( V )« (literally,
>   »Resistance( self, V )«) of your three classes (and possible
>   of other model classes added in the future) /viewed together
>   as an abstract concept/ "get the resistance under 'this'
>   model", independent of any specific load model.

Took me two days, but I finally grok what you said.

>>> OOP is advantageous if you can anticipate that you will want
>>> to extend operations for other types.
>> Since the way that each operation (aside from __init__) differs
>>from one load type to the next, is there really an advantage?
> 
>   The implementation differs, but not the interface and meaning.
> 
>   The advantage is that you can extend this operation for
>   additional types /without/ modifying the existing implementations
>   (the open-closed principle!). Whereas with a single
>   procedure in a non-OOP language, you would have to /modify/
>   (error-prone!) an existing procedure.

And another advantage has surfaced through this discussion. Even though
the common code was only half-a-dozen lines or so, it changed three
times due to suggestions made in this thread. Abstracting it to a
parent meant that I only had to implement and test each of these changes
in one place, rather than three.

>>> (Non-OOP means in this case that you have a single
>>> definition of a function »Resistance( entity, V )« which
>>> contains an internal multiple branch on the type of the
>>> entity.)
>> To be honest, that sounds painful and hard to maintain. Of course,
>> back in my F77 days, it would have been the only option.
> 
>   Well, non-OOP is /not/ obsolete. It just has other specific
>   advantages and disadvantages. It could be advantageous,
>   when one adds new operations more often than new types.

To misquote "Chico Escuela", "Fortran been berry, berry good to me."

-- 
Michael F. Stemper
A preposition is something you should never end a sentence with.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-07 Thread Steven D'Aprano
On Fri, 07 Sep 2018 16:07:06 -0500, Michael F. Stemper wrote:

>>> In another case where I had a "bare exception", I was using it to see
>>> if something was defined and substitute a default value if it wasn't.
>>> Have I cleaned this up properly?
>>>
>>>   try
>>>     id = xmlmodel.attrib['name']
>>>   except KeyError:
>>>     id = "constant power"
>>>
>>> (Both changes appear to meet my intent, I'm more wondering about how
>>> pythonic they are.)

Yes, catch the direct exception you are expecting. That's perfectly 
Pythonic.


>> There's an alternative that's recommended when the key is often absent:
>> 
>>     id = xmlmodel.attrib.get('name', "constant power")
> 
> Oh, I like that much better than what I showed above, or how I "fixed"
> it cross-thread. Thanks!

However, if the key is nearly always present, and your code is 
performance-critical, calling the "get" method has the slight 
disadvantage that it will be slightly slower than using the try...except 
form you show above.

On the other hand, the get method has the big advantage that it's an 
expression that can be used in place, not a four-line compound statement.

If I don't care about squeezing out every last bit of performance from 
the interpreter, I use whatever looks good to me on the day. That will 
often be the "get" method.

But on the rare occasions I do care about performance, the basic rule of 
thumb I use is that if the key is likely to be missing more than about 
10% of the time, I use the "LBYL" idiom (either an explicit test using 
"if key in dict" or just call the dict.get method).

But don't stress about the choice. Chances are that any of the three 
options you tried (catch KeyError, check with "if" first, or using the 
get method) will be good enough.




-- 
Steven D'Aprano
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-07 Thread Michael F. Stemper
On 2018-09-07 15:39, MRAB wrote:
> On 2018-09-07 20:51, Michael F. Stemper wrote:
>> On 2018-09-06 16:00, MRAB wrote:

>>> A word of advice: don't use a "bare" except, i.e. one that doesn't
>>> specify what exception(s) it should catch.
>>
>> Given that I moved the first line ("P_0s = ...") out of the "try"
>> clause, does this align with your advice?
>>
>>   # If pre-validation has been run, guaranteed to have RatedPower
>>   P_0s = xmlmodel.findall( 'RatedPower' )[0].text
>>   try:
>>     self.P_0 = float( P_0s )
>>   except ValueError:
>>     Utility.DataErr( "Power for %s load, '%s', not parsable" \
>>   % (id,P_0s) )
>>   if self.P_0<=0.0:
>>     Utility.DataErr( "Power for %s load must be postive, not %s" \
>>   % (id,P_0s) )
>>
> That's better.
> 
> However, if P_0s can't be parse as a float, then self.P_0 will be
> unchanged (assuming that it already has a value, of course).

This is the unique place where self.P_0 might have a value assigned.

> Is it OK that if there's no rated power, or it's invalid, it'll report
> it and continue with whatever value, if any, that it already has?

No. If the data file doesn't have the right data, the simulation can't
run. That's why DataErr reports the problem and invokes sys.exit(71).


>> In another case where I had a "bare exception", I was using it to see if
>> something was defined and substitute a default value if it wasn't. Have
>> I cleaned this up properly?
>>
>>   try
>>     id = xmlmodel.attrib['name']
>>   except KeyError:
>>     id = "constant power"
>>
>> (Both changes appear to meet my intent, I'm more wondering about how
>> pythonic they are.)
>>
> There's an alternative that's recommended when the key is often absent:
> 
>     id = xmlmodel.attrib.get('name', "constant power")

Oh, I like that much better than what I showed above, or how I "fixed"
it cross-thread. Thanks!

-- 
Michael F. Stemper
You can lead a horse to water, but you can't make him talk like Mr. Ed
by rubbing peanut butter on his gums.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-07 Thread MRAB

On 2018-09-07 21:08, Michael F. Stemper wrote:

On 2018-09-07 14:51, Michael F. Stemper wrote:

On 2018-09-06 16:00, MRAB wrote:

On 2018-09-06 21:24, Michael F. Stemper wrote:



A word of advice: don't use a "bare" except, i.e. one that doesn't
specify what exception(s) it should catch.



In another case where I had a "bare exception", I was using it to see if
something was defined and substitute a default value if it wasn't. Have
I cleaned this up properly?

 try
   id = xmlmodel.attrib['name']
 except KeyError:
   id = "constant power"


Never mind! After I continued testing, I realized that the above
should have been written as:

   if 'name' in xmlmodel.attrib:
 id = xmlmodel.attrib['name']
   else:
 id = "constant power"




That's actually _less_ Pythonic.

Have a look at the entries "EAFP" and "LBYL" here:

https://docs.python.org/3/glossary.html
--
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-07 Thread MRAB

On 2018-09-07 20:51, Michael F. Stemper wrote:

On 2018-09-06 16:00, MRAB wrote:

On 2018-09-06 21:24, Michael F. Stemper wrote:

On 2018-09-06 09:35, Rhodri James wrote:



Is it worth creating the superclass in Python?  It sounds like it's a
bit marginal in your case.  I'm not that seasoned in object-oriented
design either, but my yardstick would be how much common code does it
eliminate?


About half a dozen lines. Here's the common part:

def __init__( self, xmlmodel, V, id ):

   try:
 P_0s = xmlmodel.findall( 'RatedPower' )[0].text
 self.P_0 = float( P_0s )
   except:
 Utility.DataErr( "Power not specified for %s load" % (id) )
   if self.P_0<=0.0:
 Utility.DataErr( "Power for %s load must be postive, not %s" \
   % (id,P_0s) )



A word of advice: don't use a "bare" except, i.e. one that doesn't
specify what exception(s) it should catch.


Given that I moved the first line ("P_0s = ...") out of the "try"
clause, does this align with your advice?

  # If pre-validation has been run, guaranteed to have RatedPower
  P_0s = xmlmodel.findall( 'RatedPower' )[0].text
  try:
self.P_0 = float( P_0s )
  except ValueError:
Utility.DataErr( "Power for %s load, '%s', not parsable" \
  % (id,P_0s) )
  if self.P_0<=0.0:
Utility.DataErr( "Power for %s load must be postive, not %s" \
  % (id,P_0s) )


That's better.

However, if P_0s can't be parse as a float, then self.P_0 will be 
unchanged (assuming that it already has a value, of course).


Is it OK that if there's no rated power, or it's invalid, it'll report 
it and continue with whatever value, if any, that it already has?



Your try...except above will catch _any_ exception. If you misspelled a
name in the 'try' part, it would raise NameError, which would also be
caught.


In another case where I had a "bare exception", I was using it to see if
something was defined and substitute a default value if it wasn't. Have
I cleaned this up properly?

  try
id = xmlmodel.attrib['name']
  except KeyError:
id = "constant power"

(Both changes appear to meet my intent, I'm more wondering about how
pythonic they are.)


There's an alternative that's recommended when the key is often absent:

id = xmlmodel.attrib.get('name', "constant power")

Catching an exception has a cost, so the usual advice is to use .get 
when the key is often absent, or catch KeyError when the key is usually 
present but occasionally is absent and you can provide a default value.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-07 Thread Michael F. Stemper
On 2018-09-07 14:51, Michael F. Stemper wrote:
> On 2018-09-06 16:00, MRAB wrote:
>> On 2018-09-06 21:24, Michael F. Stemper wrote:

>> A word of advice: don't use a "bare" except, i.e. one that doesn't
>> specify what exception(s) it should catch.

> In another case where I had a "bare exception", I was using it to see if
> something was defined and substitute a default value if it wasn't. Have
> I cleaned this up properly?
> 
>  try
>id = xmlmodel.attrib['name']
>  except KeyError:
>id = "constant power"

Never mind! After I continued testing, I realized that the above
should have been written as:

  if 'name' in xmlmodel.attrib:
id = xmlmodel.attrib['name']
  else:
id = "constant power"



-- 
Michael F. Stemper
Always use apostrophe's and "quotation marks" properly.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-07 Thread Michael F. Stemper
On 2018-09-06 16:00, MRAB wrote:
> On 2018-09-06 21:24, Michael F. Stemper wrote:
>> On 2018-09-06 09:35, Rhodri James wrote:

>>> Is it worth creating the superclass in Python?  It sounds like it's a
>>> bit marginal in your case.  I'm not that seasoned in object-oriented
>>> design either, but my yardstick would be how much common code does it
>>> eliminate?
>>
>> About half a dozen lines. Here's the common part:
>>
>> def __init__( self, xmlmodel, V, id ):
>>
>>    try:
>>  P_0s = xmlmodel.findall( 'RatedPower' )[0].text
>>  self.P_0 = float( P_0s )
>>    except:
>>  Utility.DataErr( "Power not specified for %s load" % (id) )
>>    if self.P_0<=0.0:
>>  Utility.DataErr( "Power for %s load must be postive, not %s" \
>>    % (id,P_0s) )

> A word of advice: don't use a "bare" except, i.e. one that doesn't
> specify what exception(s) it should catch.

Given that I moved the first line ("P_0s = ...") out of the "try"
clause, does this align with your advice?

 # If pre-validation has been run, guaranteed to have RatedPower
 P_0s = xmlmodel.findall( 'RatedPower' )[0].text
 try:
   self.P_0 = float( P_0s )
 except ValueError:
   Utility.DataErr( "Power for %s load, '%s', not parsable" \
 % (id,P_0s) )
 if self.P_0<=0.0:
   Utility.DataErr( "Power for %s load must be postive, not %s" \
 % (id,P_0s) )

> Your try...except above will catch _any_ exception. If you misspelled a
> name in the 'try' part, it would raise NameError, which would also be
> caught.

In another case where I had a "bare exception", I was using it to see if
something was defined and substitute a default value if it wasn't. Have
I cleaned this up properly?

 try
   id = xmlmodel.attrib['name']
 except KeyError:
   id = "constant power"

(Both changes appear to meet my intent, I'm more wondering about how
pythonic they are.)

-- 
Michael F. Stemper
Isaiah 10:1-2
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Steven D'Aprano
On Thu, 06 Sep 2018 22:00:26 +0100, MRAB wrote:

> On 2018-09-06 21:24, Michael F. Stemper wrote:
[...]
>>try:
>>  P_0s = xmlmodel.findall( 'RatedPower' )[0].text 
>>  self.P_0 = float( P_0s )
>>except:
[...]

> A word of advice: don't use a "bare" except, i.e. one that doesn't
> specify what exception(s) it should catch.

Excellent advice!

More here:

https://realpython.com/the-most-diabolical-python-antipattern/





-- 
Steven D'Aprano
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread MRAB

On 2018-09-06 21:24, Michael F. Stemper wrote:

On 2018-09-06 09:35, Rhodri James wrote:

On 06/09/18 15:04, Michael F. Stemper wrote:

Net net is that the only thing that ended up being common was the
__init__ methods. Two of the classes have identical __init__
methods; the third has a superset of that method. The other methods
all have completely different implementations. This isn't due to
poor coding, but due to the fact that what these model have
different physical characteristics.

Not being that familiar with object-oriented programming (I grew up
on FORTRAN and c), I'm seeking opinions:

Is there really any benefit to this change? Yes, I've eliminated
some (a few lines per class) duplicate code. On the other hand,
I've added the parent class and the (probably small, but not
non-existent) overhead of invoking super().


What you've done is the work you would have to do in a statically-typed
language such as C++.  You've been taking advantage of duck typing


Upon review, it seems that I haven't. However, as noted in another
followup, I think that I've found a way to do so.


Is it worth creating the superclass in Python?  It sounds like it's a
bit marginal in your case.  I'm not that seasoned in object-oriented
design either, but my yardstick would be how much common code does it
eliminate?


About half a dozen lines. Here's the common part:

def __init__( self, xmlmodel, V, id ):

   try:
 P_0s = xmlmodel.findall( 'RatedPower' )[0].text
 self.P_0 = float( P_0s )
   except:
 Utility.DataErr( "Power not specified for %s load" % (id) )
   if self.P_0<=0.0:
 Utility.DataErr( "Power for %s load must be postive, not %s" \
   % (id,P_0s) )

Actually, looking over it, I see that I can slightly simplify this.
I suppose that's a good reason for putting it in one place -- if I
want to change it, I only need to do it once, not three times.

Thanks for your input.

A word of advice: don't use a "bare" except, i.e. one that doesn't 
specify what exception(s) it should catch.


Your try...except above will catch _any_ exception. If you misspelled a 
name in the 'try' part, it would raise NameError, which would also be 
caught.


There are rare occasions when it's OK, but even then you'd just want to 
do something and then re-raise it.


Catch only those exceptions that you're prepared to deal with and allow 
any others to propagate and let you know that there's a problem!

--
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Michael F. Stemper
On 2018-09-06 12:32, Stefan Ram wrote:
> "Michael F. Stemper"  writes:
>> Is there really any benefit to this change? Yes, I've eliminated
>> some (a few lines per class) duplicate code. On the other hand,
>> I've added the parent class and the (probably small, but not
>> non-existent) overhead of invoking super().
> 
>   You have a operation »Resistance( V )«.

Mathematically, that's an operation, I suppose. I tend to think of it
as either a function or a method.

>   OOP is advantageous if you can anticipate that you will want
>   to extend operations for other types.

Since the way that each operation (aside from __init__) differs
from one load type to the next, is there really an advantage?

>   I.e., if you anticipate a new type »ConstantVoltage«, you

Actually, although the possibility of other load models exists,
ConstantVoltage() would be impossible, since these models are
all defined based on the behavior of the load *in response to a
change in voltage*. But your point is well-taken, which is part
of why I considered doing inheritance.

>   can add an operation »Resistance( V )« for this new type
>   without changing the existing definitions (open-closed
>   principle).
> 
>   Non-OOP is advantageous if you can anticipate that you will
>   want to add new operations for the existing types.
> 
>   (Non-OOP means in this case that you have a single
>   definition of a function »Resistance( entity, V )« which
>   contains an internal multiple branch on the type of the
>   entity.)

To be honest, that sounds painful and hard to maintain. Of course,
back in my F77 days, it would have been the only option.

Thanks for your time.

-- 
Michael F. Stemper
Why doesn't anybody care about apathy?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Michael F. Stemper
On 2018-09-06 10:40, Abdur-Rahmaan Janhangeer wrote:
> Also, get someone, preferrable a python engineer to review your code.

Sounds like an advertisement to me.

-- 
Michael F. Stemper
Why doesn't anybody care about apathy?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Michael F. Stemper
On 2018-09-06 09:35, Rhodri James wrote:
> On 06/09/18 15:04, Michael F. Stemper wrote:
>> Net net is that the only thing that ended up being common was the
>> __init__ methods. Two of the classes have identical __init__
>> methods; the third has a superset of that method. The other methods
>> all have completely different implementations. This isn't due to
>> poor coding, but due to the fact that what these model have
>> different physical characteristics.
>>
>> Not being that familiar with object-oriented programming (I grew up
>> on FORTRAN and c), I'm seeking opinions:
>>
>> Is there really any benefit to this change? Yes, I've eliminated
>> some (a few lines per class) duplicate code. On the other hand,
>> I've added the parent class and the (probably small, but not
>> non-existent) overhead of invoking super().
> 
> What you've done is the work you would have to do in a statically-typed
> language such as C++.  You've been taking advantage of duck typing

Upon review, it seems that I haven't. However, as noted in another
followup, I think that I've found a way to do so.

> Is it worth creating the superclass in Python?  It sounds like it's a
> bit marginal in your case.  I'm not that seasoned in object-oriented
> design either, but my yardstick would be how much common code does it
> eliminate?

About half a dozen lines. Here's the common part:

def __init__( self, xmlmodel, V, id ):

  try:
P_0s = xmlmodel.findall( 'RatedPower' )[0].text
self.P_0 = float( P_0s )
  except:
Utility.DataErr( "Power not specified for %s load" % (id) )
  if self.P_0<=0.0:
Utility.DataErr( "Power for %s load must be postive, not %s" \
  % (id,P_0s) )

Actually, looking over it, I see that I can slightly simplify this.
I suppose that's a good reason for putting it in one place -- if I
want to change it, I only need to do it once, not three times.

Thanks for your input.

-- 
Michael F. Stemper
Why doesn't anybody care about apathy?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Michael F. Stemper
On 2018-09-06 09:34, Marko Rauhamaa wrote:
> "Michael F. Stemper" :
> 
>> Since the three classes all had common methods (by design), I
>> thought that maybe refactoring these three classes to inherit from
>> a parent class would be beneficial. I went ahead and did so.
>> (Outlines of before and after are at the end of the post.)
>>
>> Net net is that the only thing that ended up being common was the
>> __init__ methods. Two of the classes have identical __init__
>> methods; the third has a superset of that method. The other methods
>> all have completely different implementations. This isn't due to
>> poor coding, but due to the fact that what these model have
>> different physical characteristics.
>>
>> [...]
>>
>> Is there really any benefit to this change? Yes, I've eliminated
>> some (a few lines per class) duplicate code. On the other hand,
>> I've added the parent class and the (probably small, but not
>> non-existent) overhead of invoking super().
>>
>> How does one judge when it's worthwhile to do this and when it's
>> not? What criteria would somebody seasoned in OO and python use
>> to say "good idea" vs "don't waste your time"?
> 
> Ultimately, a seasoned OO programmer might prefer one structure in the
> morning and another structure in the afternoon.

I figured that was the case, which is why I sought criteria to consider
rather than a cut-and-dried answer.

> Python's ducktyping makes it possible to develop classes to an interface
> that is not spelled out as a base class.

After reviewing my code, I have a feeling that I'm not taking
advantage of duck typing. I think that if LoadList held all types
of load and I did this:

for load in LoadList:
  load.served = load.Power( Feeder.V_load )
  LoadServed += load.served

it would be duck typing. Unfortunately, I'm not. I had thought that
I needed to handle the constant power load (if there is one)
separately in at least one point, and the same for a possible
constant current load. The (zero to many) constant impedance loads
are all in a list over which I loop.

However, inspired by your point, I think that I've found a way to
handle them all in one list. I'll play with it a little.

>   My opinion is that you should
> not define base classes only to show pedigree as you would need to in,
> say, Java.

Maybe it was from what I've read about Java (zero experience) that gave
me the idea to try this.

> Then, is it worthwhile to define a base class just to avoid typing the
> same constructor twice? That's a matter of opinion. You can go either
> way. Just understand that the base class doesn't serve a philosophical
> role but is simply an implementation utility. Be prepared to refactor
> the code and get rid of the base class the moment the commonality
> disappears.

I'll keep that in mind, but the commonality is based on the laws of
physics, so it's not a big risk.

> On the other hand, why is it that the two constructors happen to
> coincide? Is it an indication that the two classes have something deeper
> in common that the third one doesn't? If it is not a coincidence, go
> ahead and give the base class a name that expresses the commonality.

The code which all three load types share, which is the total content
of their parent, is as follows:

def __init__( self, xmlmodel, V, id ):

  try:
P_0s = xmlmodel.findall( 'RatedPower' )[0].text
self.P_0 = float( P_0s )
  except:
Utility.DataErr( "Power not specified for %s load" % (id) )
  if self.P_0<=0.0:
Utility.DataErr( "Power for %s load must be postive, not %s" \
  % (id,P_0s) )


The constant impedance loads then extend this by initializing a
duty cycle model. (Think of something thermostatically controlled,
such as an electric oven or electric space heating.)

The constant impedance loads then extend this by initializing a
duty cycle model. (Think of something thermostatically controlled,
such as an electric oven or electric space heating.)

The 3-foot[1] view of the data model is:







> Don't be afraid of "wasting your time"

If was was afraid of that, I wouldn't have tried refactoring the code
in the first place. I would have said "it works, don't bother."

>   or worry too much about whether
> something is a "good idea."

Well, if it turns out to be a bad idea, I'd rather learn that it's a
bad idea.

>   Be prepared to massage the code over time as
> your understanding and tastes evolve.

Exactly what I was doing, and the point of asking was to extend my
understanding.

Thanks for taking the time to respond.

-- 
Michael F. Stemper
What happens if you play John Cage's "4'33" at a slower tempo?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Rob Gaddi

On 09/06/2018 09:07 AM, Thomas Jollans wrote:

On 2018-09-06 17:40, Abdur-Rahmaan Janhangeer wrote:

Also, get someone, preferrable a python engineer to review your code.


Does anyone here know anyone who would refer to themselves as a "Python
engineer" with a straight face? I merely ask...

-- Thomas



Suddenly I'm filled with visions of pipe, fittings, and a herpetology 
degree.


--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order.  See above to fix.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Thomas Jollans
On 2018-09-06 17:40, Abdur-Rahmaan Janhangeer wrote:
> Also, get someone, preferrable a python engineer to review your code.

Does anyone here know anyone who would refer to themselves as a "Python
engineer" with a straight face? I merely ask...

-- Thomas
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Abdur-Rahmaan Janhangeer
Also, get someone, preferrable a python engineer to review your code.

yours,

Abdur-Rahmaan Janhangeer
https://github.com/Abdur-rahmaanJ
Mauritius
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Rhodri James

On 06/09/18 15:04, Michael F. Stemper wrote:

Net net is that the only thing that ended up being common was the
__init__ methods. Two of the classes have identical __init__
methods; the third has a superset of that method. The other methods
all have completely different implementations. This isn't due to
poor coding, but due to the fact that what these model have
different physical characteristics.

Not being that familiar with object-oriented programming (I grew up
on FORTRAN and c), I'm seeking opinions:

Is there really any benefit to this change? Yes, I've eliminated
some (a few lines per class) duplicate code. On the other hand,
I've added the parent class and the (probably small, but not
non-existent) overhead of invoking super().


What you've done is the work you would have to do in a statically-typed 
language such as C++.  You've been taking advantage of duck typing to 
have the rest of your code not have to care about what type of load you 
are modelling, but in C++ (say) you would need the superclass to supply 
the type information to let the rest of your code compile.


Is it worth creating the superclass in Python?  It sounds like it's a 
bit marginal in your case.  I'm not that seasoned in object-oriented 
design either, but my yardstick would be how much common code does it 
eliminate?  It's a very subjective measure, but basically it's the same 
subjective measure as for pulling any common code into a separate function.


--
Rhodri James *-* Kynesim Ltd
--
https://mail.python.org/mailman/listinfo/python-list


Re: Object-oriented philosophy

2018-09-06 Thread Marko Rauhamaa
"Michael F. Stemper" :

> Since the three classes all had common methods (by design), I
> thought that maybe refactoring these three classes to inherit from
> a parent class would be beneficial. I went ahead and did so.
> (Outlines of before and after are at the end of the post.)
>
> Net net is that the only thing that ended up being common was the
> __init__ methods. Two of the classes have identical __init__
> methods; the third has a superset of that method. The other methods
> all have completely different implementations. This isn't due to
> poor coding, but due to the fact that what these model have
> different physical characteristics.
>
> [...]
>
> Is there really any benefit to this change? Yes, I've eliminated
> some (a few lines per class) duplicate code. On the other hand,
> I've added the parent class and the (probably small, but not
> non-existent) overhead of invoking super().
>
> How does one judge when it's worthwhile to do this and when it's
> not? What criteria would somebody seasoned in OO and python use
> to say "good idea" vs "don't waste your time"?

Ultimately, a seasoned OO programmer might prefer one structure in the
morning and another structure in the afternoon.

Python's ducktyping makes it possible to develop classes to an interface
that is not spelled out as a base class. My opinion is that you should
not define base classes only to show pedigree as you would need to in,
say, Java.

Then, is it worthwhile to define a base class just to avoid typing the
same constructor twice? That's a matter of opinion. You can go either
way. Just understand that the base class doesn't serve a philosophical
role but is simply an implementation utility. Be prepared to refactor
the code and get rid of the base class the moment the commonality
disappears.

On the other hand, why is it that the two constructors happen to
coincide? Is it an indication that the two classes have something deeper
in common that the third one doesn't? If it is not a coincidence, go
ahead and give the base class a name that expresses the commonality.

Don't be afraid of "wasting your time" or worry too much about whether
something is a "good idea." Be prepared to massage the code over time as
your understanding and tastes evolve.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Object-oriented philosophy

2018-09-06 Thread Michael F. Stemper
Over the summer, I've been working on a simulation. After months
of design and redesign, I finally coded it up in two days over
Labor Day weekend. Works great.

The core of the simulation is a set of models of three different
types of electrical loads (characterized based on how they respond
to voltage changes), implemented as python classes.

Since the three classes all had common methods (by design), I
thought that maybe refactoring these three classes to inherit from
a parent class would be beneficial. I went ahead and did so.
(Outlines of before and after are at the end of the post.)

Net net is that the only thing that ended up being common was the
__init__ methods. Two of the classes have identical __init__
methods; the third has a superset of that method. The other methods
all have completely different implementations. This isn't due to
poor coding, but due to the fact that what these model have
different physical characteristics.

Not being that familiar with object-oriented programming (I grew up
on FORTRAN and c), I'm seeking opinions:

Is there really any benefit to this change? Yes, I've eliminated
some (a few lines per class) duplicate code. On the other hand,
I've added the parent class and the (probably small, but not
non-existent) overhead of invoking super().

How does one judge when it's worthwhile to do this and when it's
not? What criteria would somebody seasoned in OO and python use
to say "good idea" vs "don't waste your time"?

Other thoughts on this topic would also be appreciated.


Comparison follows:

= begin original 
class ConstantPower( ):
  def __init__( self, xmlmodel, V ):
  def Resistance( self, V ):
  def Power( self, V ):
  def FixedValue( self ):
class ConstantCurrent( ):
  def __init__( self, xmlmodel, V ):
  def Resistance( self, V ):
  def Power( self, V ):
  def FixedValue( self ):
class ConstantImpedance( ):
  def __init__( self, xmlmodel, V ):
  def Resistance( self, V ):
  def Power( self, V ):
  def FixedValue( self ):
  def Update( self, V ):
=== end original 

= begin revised =
class LoadModel( ):
  def __init__( self, xmlmodel, V, id ):
class ConstantPower( LoadModel ):
  def __init__( self, xmlmodel, V ):
super().__init__( xmlmodel, V, "constant power" )
  def Resistance( self, V ):
  def Power( self, V ):
  def FixedValue( self ):
class ConstantCurrent( LoadModel ):
  def __init__( self, xmlmodel, V ):
super().__init__( xmlmodel, V, "constant current" )
  def Resistance( self, V ):
  def Power( self, V ):
  def FixedValue( self ):
class ConstantImpedance( LoadModel ):
  def __init__( self, xmlmodel, V ):
super().__init__( xmlmodel, V, self.name )
  def Resistance( self, V ):
  def Power( self, V ):
  def FixedValue( self ):
  def Update( self, V ):
=== end revised =

-- 
Michael F. Stemper
This email is to be read by its intended recipient only. Any other party
reading is required by the EULA to send me $500.00.
-- 
https://mail.python.org/mailman/listinfo/python-list