Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #94542 > unrolled thread

Re: scalar vs array and program control

Started byLaura Creighton <lac@openend.se>
First post2015-07-25 13:01 +0200
Last post2015-07-26 12:35 +0200
Articles 8 — 2 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: scalar vs array and program control Laura Creighton <lac@openend.se> - 2015-07-25 13:01 +0200
    Re: scalar vs array and program control Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-25 14:57 +0200
      Re: scalar vs array and program control Laura Creighton <lac@openend.se> - 2015-07-25 15:43 +0200
        Re: scalar vs array and program control Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-25 18:53 +0200
          Re: scalar vs array and program control Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-25 18:56 +0200
          Re: scalar vs array and program control Laura Creighton <lac@openend.se> - 2015-07-25 19:45 +0200
            Re: scalar vs array and program control Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-26 12:26 +0200
              Re: scalar vs array and program control Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-26 12:35 +0200

#94542 — Re: scalar vs array and program control

FromLaura Creighton <lac@openend.se>
Date2015-07-25 13:01 +0200
SubjectRe: scalar vs array and program control
Message-ID<mailman.973.1437822101.3674.python-list@python.org>
You have a bit of a problem, in that "functional" and "object-oriented"
are two different styles of programming.  You really cannot make your
code 'more functional' and 'more object-oriented' at the same time --
more in one style implies less in the other.  I think you may have
got the mistaken idea that 'object-orientated' means 'well-written'
or 'professional' or some such.

However, if your intuition was telling you that it would be bad to
write code that goes:

if type(x) is str:
   do_something()
elif type(x) is float:
   do_something_else()
elif type(x) is int:
   do_another_thing()
else:
   scream_loudly_and_dont_do_anything()

then your intuition is working perfectly.  Don't stick typechecks in all
over your code.  It makes it fragile and hard to maintain.  It also means
that you have to anticipate all the perfectly good input you might have,
and nobody can do that.

For instance, might somebody want to feed your functions complex numbers
one day?  Or, here is a good one -- python has a Decimal datatype
which does Decimal floating point arithmetic.  You don't want your code
to not work for people using Decimal numbers just because you didn't
put in a check for
>>> type(Decimal(10.5))
<class 'decimal.Decimal'>

If you find you need to check the type of something, it is better to use
the isinstance function.

if isinstance(x, str):
   do something()
else:
   do_something_else()

The python builtin types are all included here.  For the sort of work
you do it is useful to know about

from numbers import Number
     isinstance(x, Number)

which will happily return True for all sorts of numbers, complex,
Decimal numbers even number classes which you define yourself.

So if you need to do this sort of 'look before you leap' checking,
isinstance is the way to do it.  And sometimes this _is_ the sort of
checking you want to do.  But, aside from when you are writing test
code, where it happens all over the place, most of the type in writing
Python code we don't do this either.

We don't look before we leap.  We leap, and then if there are any
problems, we deal with it.

Instead we do something like this:

consider a function that converts a string to a number

def string_to_number(s):
   try:
      return int(s)
   except ValueError:
      return float(s)

If all your input is guaranteed to be ints or floats this will work fine.
It also works if you feed it things that are already ints and floats
(not strings).  And this is nice .

How did I know to look for ValueErrors?

>>> int("1.2")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  ValueError: invalid literal for int() with base 10: '1.2'

Cause that is what Python gives you.  If it had given you a TypeError
instead -- which is what I expected it to do, but so it goes -- I
would have said except TypeError.

You can stack these things.

>>>
def string_to_number(x):
   try:
     return int(x)
   except ValueError:
      try:
         return float(x)
      except ValueError:
         return complex(x)

So now it handles complex numbers as well.

So this is, quite likely, the pattern that you are looking for:

try:
	all_your_code_which_is_happy_with_non_scalars
except WhateverErrorPythonGivesYouWhenYouTryThisWithScalars:
       whatever_you_want_to_do_when_this_happens

This is the usual way to do things.

If you find that your try/except pairs are walking themselves all the
way to the right hand side of the screen it is time to consider
restructuring your code.

The great advantage of this approach is that you don't have to
pretend to omniscience about the sort of input you will get.  If I
decide to call your code with an array of Decimal floating point
integers instead of regular floats, it's great if it just works,
whether or not you had the idea of Decimal floating point in mind
when you wrote the code.

Sorry to be so longwinded.  I need to go now and don't have time to
revise it, though it probably should be made a whole bunch less
preachy.

Hope it helps,
Laura






  

[toc] | [next] | [standalone]


#94547

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-25 14:57 +0200
Message-ID<1619647.1FW7hyz6Jq@PointedEars.de>
In reply to#94542
Laura Creighton wrote:

> […]  You really cannot make your code 'more functional' and 'more object-
> oriented' at the same time -- more in one style implies less in the other.

How did you get that idea?

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#94550

FromLaura Creighton <lac@openend.se>
Date2015-07-25 15:43 +0200
Message-ID<mailman.978.1437831852.3674.python-list@python.org>
In reply to#94547
In a message of Sat, 25 Jul 2015 14:57:14 +0200, "Thomas 'PointedEars' Lahn" wr
ites:
>Laura Creighton wrote:
>
>> […]  You really cannot make your code 'more functional' and 'more object-
>> oriented' at the same time -- more in one style implies less in the other.
>
>How did you get that idea?

Because pure object oriented techniques are best when you have
a fixed set of operations on things, and as your code evolves
you primarily add new things.  Things written in a functional style
work best when you have a fixed set of things, and your code evolves
you add new operations for the existing things.

Laura

[toc] | [prev] | [next] | [standalone]


#94559

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-25 18:53 +0200
Message-ID<1757573.rN60lcJNyZ@PointedEars.de>
In reply to#94550
Laura Creighton wrote:

> […] "Thomas 'PointedEars' Lahn" [writes]:
>> Laura Creighton wrote:
>>> […]  You really cannot make your code 'more functional' and 'more
>>> object-oriented' at the same time -- more in one style implies less
>>> in the other.
>> How did you get that idea?
> 
> Because pure object oriented techniques are best when you have
> a fixed set of operations on things, and as your code evolves
> you primarily add new things.  Things written in a functional style
> work best when you have a fixed set of things, and your code evolves
> you add new operations for the existing things.

Your logic is flawed.  “*Pure* object oriented” is your raising the bar.  
First of all, object-oriented programming and functional programming are 
programming *paradigms*, not merely techniques.  Second, they are _not_ 
mutually exclusive paradigms.  Third, Python supports both because in 
Python, functions are first-class objects.  (In fact, if I am not mistaken, 
everything except None is an object in Python.)

For example, let us make this original Python code more object-oriented and 
more functional at the same time:

#------------------------------------------------------------------------
def foo (a, b):
    return a + b

print(foo(42, 23))
#------------------------------------------------------------------------

First, more functional: 

#------------------------------------------------------------------------
def foo (f, a, b):
    return f(a, b)

print(foo(lambda a, b: return a + b, 42, 23))
#------------------------------------------------------------------------

Instead of hard-coding the “+” operation, (a reference to) a function 
(object) can be passed that is passed the remaining arguments, and the 
return value of the function is returned instead (you could overload the 
operator, and the “foo” call here could be inlined, of course; this is just 
an example).

Second, more object-oriented:

#------------------------------------------------------------------------
class A:
    def __init__ (self, v=0):
        self._value = v

    def foo (self, f, b):
        return f(f, self._value, b)

print(A(42).foo(lambda a, b: return a + b, 23)) 
#------------------------------------------------------------------------

The first operand now is an object, an instance of a class, and the former 
“foo” function has become a method of that class that the object inherits.  
The method could be further inherited from a superclass, or overwritten by a 
subclass, for polymorphism.  The callback could also be a public method 
provided by a class.

There are probably better examples.  In any case it should be possible for 
you to see that you are mistaken: One *can* make code more functional and 
more object-oriented at the same time, and more in one "style" does _not_ 
imply less in the other.

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#94560

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-25 18:56 +0200
Message-ID<3271934.brgO5pjKeM@PointedEars.de>
In reply to#94559
Thomas 'PointedEars' Lahn wrote:

> #------------------------------------------------------------------------
> class A:
>     def __init__ (self, v=0):
>         self._value = v
> 
>     def foo (self, f, b):
>         return f(f, self._value, b)

I mean

        return f(self._value, b)

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#94566

FromLaura Creighton <lac@openend.se>
Date2015-07-25 19:45 +0200
Message-ID<mailman.989.1437846349.3674.python-list@python.org>
In reply to#94559
In a message of Sat, 25 Jul 2015 18:53:33 +0200, "Thomas 'PointedEars' Lahn" wr
ites:
>Laura Creighton wrote:
>
>> […] "Thomas 'PointedEars' Lahn" [writes]:
>>> Laura Creighton wrote:
>>>> […]  You really cannot make your code 'more functional' and 'more
>>>> object-oriented' at the same time -- more in one style implies less
>>>> in the other.
>>> How did you get that idea?
>> 
>> Because pure object oriented techniques are best when you have
>> a fixed set of operations on things, and as your code evolves
>> you primarily add new things.  Things written in a functional style
>> work best when you have a fixed set of things, and your code evolves
>> you add new operations for the existing things.
>
>Your logic is flawed.  “*Pure* object oriented” is your raising the bar.

Yes.  But I could have said, and probably should have said 'pure
functional style' as well.

>First of all, object-oriented programming and functional programming are 
>programming *paradigms*, not merely techniques.  Second, they are _not_ 
>mutually exclusive paradigms.  Third, Python supports both because in 
>Python, functions are first-class objects.  (In fact, if I am not mistaken, 
>everything except None is an object in Python.)

Ah, digression here.  I generalise  between paradigms that generate
useful techniques, (functional programming and object oriented programming
both do this) and those that do not (the Marxist paradigm of the
labour theory of value).  It still may be very useful and instructive
to think on the Marxist Labour Theory of value, and it may have new
utility if we can replace all labour with computer/robotic/IT
... but for now, do not run your economy on this theory, ok, because
it does not work.)

Second digression:  that a thing uses objects does not make the thing
more object oriented.

>For example, let us make this original Python code more object-oriented and 
>more functional at the same time:
>
>#------------------------------------------------------------------------
>def foo (a, b):
>    return a + b
>
>print(foo(42, 23))
>#------------------------------------------------------------------------
>
>First, more functional: 
>
>#------------------------------------------------------------------------
>def foo (f, a, b):
>    return f(a, b)
>
>print(foo(lambda a, b: return a + b, 42, 23))
>#------------------------------------------------------------------------
>
>Instead of hard-coding the “+” operation, (a reference to) a function 
>(object) can be passed that is passed the remaining arguments, and the 
>return value of the function is returned instead (you could overload the 
>operator, and the “foo” call here could be inlined, of course; this is just 
>an example).
>Second, more object-oriented:
>
>#------------------------------------------------------------------------
>class A:
>    def __init__ (self, v=0):
>        self._value = v
>
>    def foo (self, f, b):
>        return f(f, self._value, b)
>
>print(A(42).foo(lambda a, b: return a + b, 23)) 
>#------------------------------------------------------------------------
>
>The first operand now is an object, an instance of a class, and the former 
>“foo” function has become a method of that class that the object inherits.  
>The method could be further inherited from a superclass, or overwritten by a 
>subclass, for polymorphism.  The callback could also be a public method 
>provided by a class.
>
>There are probably better examples.  In any case it should be possible for 
>you to see that you are mistaken: One *can* make code more functional and 
>more object-oriented at the same time, and more in one "style" does _not_ 
>imply less in the other.

Okay, I give.  It's possible, and I overstated things.

But I suspect that it is only possible in things that are in
the behavioural middle. You needed a lambda to make the thing more
functional, and to create a class where none was before to make it
more object-oriented.  But this means that the thing wasn't all that
functional nor object-oriented -- most likely procedural -- to start with.

So, very clever.  But still the general rule in refactoring, is that
you want to go more oo or more functional, not both at the same time.

Laura


[toc] | [prev] | [next] | [standalone]


#94615

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-26 12:26 +0200
Message-ID<1852361.ZT26voajJO@PointedEars.de>
In reply to#94566
Laura Creighton wrote:

> […] "Thomas 'PointedEars' Lahn" writes:
>> Laura Creighton wrote:
>>> […] "Thomas 'PointedEars' Lahn" [writes]:
>>>> Laura Creighton wrote:
>>>>> […]  You really cannot make your code 'more functional' and 'more
>>>>> object-oriented' at the same time -- more in one style implies less
>>>>> in the other.
>>>> How did you get that idea?
>>> Because pure object oriented techniques are best when you have
>>> a fixed set of operations on things, and as your code evolves
>>> you primarily add new things.  Things written in a functional style
>>> work best when you have a fixed set of things, and your code evolves
>>> you add new operations for the existing things.
>> Your logic is flawed.  “*Pure* object oriented” is your raising the bar.
> 
> Yes.  But I could have said, and probably should have said 'pure
> functional style' as well.

That would not have changed anything.  It is the “pure” that makes your 
argument fallacious.  The “pure” falsely implies that you cannot have both 
at the same time, that you can have either function or object-oriented code. 
And ISTM that you are extending on the questionable idea that only “pure” is 
“good” to say that it would be inadvisable to have both at the same time.  
That is circular, for *that* property alone fallacious, logic.

>>First of all, object-oriented programming and functional programming are
>>programming *paradigms*, not merely techniques.  Second, they are _not_
>>mutually exclusive paradigms.  Third, Python supports both because in
>>Python, functions are first-class objects.  (In fact, if I am not
>>mistaken, everything except None is an object in Python.)
> 
> Ah, digression here.  I generalise  between paradigms that generate
> useful techniques, (functional programming and object oriented programming
> both do this) and those that do not (the Marxist paradigm of the
> labour theory of value).

You may not find them useful; several other people do.

> It still may be very useful and instructive to think on the Marxist Labour
> Theory of value, and it may have new utility if we can replace all labour 
> with computer/robotic/IT ... but for now, do not run your economy on this 
> theory, ok, because it does not work.)

Trollish nonsense.  Leave politics outside the door, it has nothing to do 
with this.
 
> Second digression:  that a thing uses objects does not make the thing
> more object oriented.

Yes, it does.  That is the very definition of *object*-*oriented*.
 
> But I suspect that it is only possible in things that are in
> the behavioural middle.

Now you are making up terminology.

> You needed a lambda to make the thing more functional,

I did not; it was merely a better visible shortcut, for a lambda expression 
is obviously a part of functional programming.  I could have defined a 
function instead and used the function identifier, and AISB I could also 
have used a reference to a method of an object.  The functional aspect of it 
was not the “lambda” but that I passed (a reference to) a function (a lambda 
expression is an inline function definition).

That is only possible if functions are first-class objects, meaning that 
they can be rvalues [sic] (“object” is not necessarily to be understood as 
the “object” in OOP, but for several programming languages, including 
Python, the other meaning applies as well; I used the term too loosely in my 
previous followup).

> and to create a class where none was before to make it more object-
> oriented. 

I did not need to, but, again, it was more obvious that way.  I could also 
have used an existing class, and its existing or newly added method.  AISB, 
almost everything in Python is an object; therefore, almost everything in 
Python has a class (try “print((42)).__class__)” in Py3k).  And Python is 
not the only object-oriented programming language for which this is true.  
Other object-oriented programming languages, for example ECMAScript 
implementations (which are my primary research topic), still have primitive 
values as well, but those are implicitly converted into object values when 
OOP patterns are used, and then those objects inherit properties as well.

> But this means that the thing wasn't all that> functional nor object-
> oriented -- most likely procedural -- to start with.

Obviously nonsense.  The procedural programming paradigm is neither the 
antithesis of the functional nor of the object-oriented programming one.

> So, very clever.  But still the general rule in refactoring, is that
> you want to go more oo or more functional, not both at the same time.

Nonsense.  You are projecting your misconceptions and ignorance (of Python, 
and programming paradigms in general) onto others.

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#94617

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-26 12:35 +0200
Message-ID<2035096.cBO6vpb5vr@PointedEars.de>
In reply to#94615
Thomas 'PointedEars' Lahn wrote:

> Laura Creighton wrote:
>> and to create a class where none was before to make it more object-
>> oriented.
> 
> I did not need to, but, again, it was more obvious that way.  I could also
> have used an existing class, and its existing or newly added method. 
> AISB, almost everything in Python is an object; therefore, almost
> everything in Python has a class (try “print((42)).__class__)” in Py3k). 
                                                   ^
> […]

| >>> print((42).__class__)
| <class 'int'>

Most interesting (but understandable):

| >>> print(42..__class__)
| <class 'float'>

BTW, another common misconception that I read from your argument is that 
“object-oriented” would be synonymous with “class-based”; that one needs a 
class for OOP.  In fact, however, there are several object-oriented 
programming languages, again for example most ECMAScript implementations, 
that are prototype-based: one object/instance inherits from another, its 
prototype.

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web