|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
I'm trying to improve myself in this area. I use objects, but there are some
things I think I just haven't wrapped my head around. I don't personally know
any programmers, so my though process has evolved, for the most part, in
isolation.
OK, starting with the basics. I want to add two vectors. The OO way ...
(as I understand it. Please include "as I understand it" as a standard
disclaimer for anything I write here.)
..... is to make a vector object and define an addition method. My vector would
be
an instance of a Vector class. That would look like:
a = Vector(1, 2, 3)
b = Vector(4, 5, 6)
and I would add them together with
c = a.add(b)
Well, not if I want to keep my sanity, because nothing else in Python works that
way. In Python (and I assume every other language), things that look like
instance.method()
return None and change the state of instance. I don't want to return None OR
change the state of instance, but if I want to avoid bleeding from my eyeballs
in the future, I'd better make sure I stick to that convention. (Sure, there's
also a + b possible, but I want to expand this logic to more complex
operations).
So, I make a function and end up with
c = vector_addition([1, 2, 3], [4, 5, 6])
And then I realize that vector_addition is "good" for other things as well:
c = vector_addition(([1], [2], [3]], [[4], [5], [6]])
is an ugly, sloppy way to get the transverse of a 2xwhatever matrix.
And that could be improved. Instead of the ugly [[1], [2], [3]] stuff, I could
define another functions which add numbers like lists
list_addition(a, b) => [a, b]
Now I can use
c = vector_addition(number_addition, a, b)
or
c = vector_addition(list_addition, a, b)
or functools.partial into vector_like_list_addition(a, b)
And this all works out, because many times there will be no 'a' and 'b'. The
arguments will be used once and never assigned to a variable, much less
instanced into a user-defined class.
Actually that's most of the time. When I want the distance between a point and a
plane, I may have a point object, but I won't have a plane object. I'll just
have a bunch of other data that can be used to describe a plane. The only thing
I need to know about the plane is that it happens to be the plane one of my
triangles is sitting on. I don't need a plane, I need to treat a triangle like a
plane.
Or, there may be tens of thousands of 'a's and 'b's, and they'll be in a file
somewhere which doesn't require my importing an object definition.
So, my thinking is: sometimes I want to stack bricks like bricks, but it's often
handy to stack bricks like rocks or marbles or bananas. And if my banana_stack
function can't handle it, then I've probably poorly (not abstractly enough)
described my bricks.
I get(?) that this is what inheritance is for, but I feel like I'm forcing a
round peg through a square hole when I try it. I've made too many assumptions
before I get to implementation. I'm trying to look at these problems in a
different way FROM THE BEGINNING.
Not every problem can be solved as elegantly as the one above, so I try to use
OO, but my classes turn into monsters. My objects have attributes which are
objects themselves, which have their own attributes which ...
I end up with
A.attr.attr = A.attr.attr.method(A.attr.attr.attr.method(arg))
From the above, it's obvious I'm breaking the instance.method()=>None convention
as well. If I don't, I end up with a module full of object-specific functions
and an object that doesn't do much more than a dictionary. I could do a cleaner
job with an actual dictionary or struct-like class, but I'm /trying/ to learn.
Guidance welcome.
-Shay
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Le 13/10/2012 19:49, Shay nous fit lire :
> In Python (and I assume every other language), things that look like
>
> instance.method()
>
> return None and change the state of instance.
Well, stop. Stay away of python if you are hoping to learn OO with it:
it's a snake that would swallow you and as such hide the sun.
For instance, your addition in C++ would probably something along:
// Untested, typo might be there too
class Vector {
private:
double internal_storage[3];
public:
Vector(); // allow unspecified value
Vector(double a, double b, double c);
// constructors are implemented elsewhere to protect the innocent
Vector & operator +(const Vector &v2) const
{
return Vector(
this.internal_storage[0]+v2.internal_storage[0],
this.internal_storage[1]+v2.internal_storage[1],
this.internal_storage[2]+v2.internal_storage[2] );
}
};
(should rather be name Vector3d... )
Usage
Vector c = Vector(1,2,3)+Vector(4,5,6);
(Bad, I should have also a copy constructor to allow:
Vector c(Vector(1,2,3)+Vector(4,5,6));
)
Or
Vector c;
Vector a(1,2,3);
Vector b(4,5,6);
c = a+b;
Caveat: there is place for more code, and optimisations too.
(especially with move constructor and copy constructor, but first
understanding reference and const is recommended)
About inheritance, do not try to use it everywhere. A thumb is a finger,
but not all fingers are thumbs, and there is something called head which
is neither. Not talking about the tank of the car.
The importance of OO: it's like a cell from your body, there is an outer
interface and there is the inner content. The inner content must not be
visible from outsiders so that a radical change of it does not propagate
to an overhaul rewrite of all others pieces. If you can keep the outer
interface, there should be very low impact.
(but sometimes you need to nevertheless tie two or more objects... as a
pack of close friends, for efficiency purpose; If you tie everything,
you loose the OO game)
Hint: instead of python, have a look at Java or C++
(they differs: Java has only single inheritance in a row, with interface
to glue additional branches, and C++ allows the dreaded diamond shape,
not for the children)
Holy war java vs C++: fight!
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Le_Forgeron <jgr### [at] freefr> wrote:
> Vector & operator +(const Vector &v2) const
> {
> return Vector(
> this.internal_storage[0]+v2.internal_storage[0],
> this.internal_storage[1]+v2.internal_storage[1],
> this.internal_storage[2]+v2.internal_storage[2] );
> }
You are returning a reference to a temporary. Kaboom.
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Le 13/10/2012 20:38, Warp nous fit lire :
> Le_Forgeron <jgr### [at] freefr> wrote:
>> Vector & operator +(const Vector &v2) const
>> {
>> return Vector(
>> this.internal_storage[0]+v2.internal_storage[0],
>> this.internal_storage[1]+v2.internal_storage[1],
>> this.internal_storage[2]+v2.internal_storage[2] );
>> }
>
> You are returning a reference to a temporary. Kaboom.
>
Yes. I do not know why I did that (nor put a space before the +).
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Le_Forgeron <jgr### [at] freefr> wrote:
> Le 13/10/2012 20:38, Warp nous fit lire :
> > Le_Forgeron <jgr### [at] freefr> wrote:
> >> Vector & operator +(const Vector &v2) const
> >> {
> >> return Vector(
> >> this.internal_storage[0]+v2.internal_storage[0],
> >> this.internal_storage[1]+v2.internal_storage[1],
> >> this.internal_storage[2]+v2.internal_storage[2] );
> >> }
> >
> > You are returning a reference to a temporary. Kaboom.
> >
> Yes. I do not know why I did that (nor put a space before the +).
Or use "this." instead of "this->". (Or using "this" in the first place...)
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Adding two objects of class vector:
[begin code]
class vector(object):
def __init__(self,x,y,z):
self.__x=x
self.__y=y
self.__z=z
@property
def x(self):
return self.__x
@property
def y(self):
return self.__y
@property
def z(self):
return self.__z
def __add__(self,b):
"""this overloads the + operator"""
return vector(self.x + b.x, self.y + b.y, self.z + b.z)
def __sub__(self,b):
"""this overloads the - operator"""
return vector(self.x - b.x, self.y - b.y, self.z - b.z)
a = Vector(1, 2, 3)
b = Vector(4, 5, 6)
c = a + b
[end code]
in python there's no distinction between method and function.
And for python just like any other OO language:
Every function call can return anything. Any class function/method can but need
not modify the instance. It's all up to you.
Regards
Aydan
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Aydan <hes### [at] hendrik-sachsenet> wrote:
> [begin code]
> class vector(object):
> def __init__(self,x,y,z):
> self.__x=x
> self.__y=y
> self.__z=z
Is that really how you write OO code in Python? Is it just me, or does it
look like Python hasn't actually been specifically designed to be an OO
language?
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Shay <nomail@nomail> wrote:
> I'm trying to improve myself in this area. I use objects, but there are some
> things I think I just haven't wrapped my head around. I don't personally know
> any programmers, so my though process has evolved, for the most part, in
> isolation.
I think that you might get more responses from the numerous programmers
here if you ask something more concrete in a more concise and clear manner.
I'm not saying this as any kind of criticism or attack. It's just that
your post is a bit long and vague, which makes it difficult to discern
what exactly is it that you have a problem with and what is it that you
are looking for.
Btw, where have you got the idea that methods shouldn't return anything?
I have never heard of such a thing.
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Warp <war### [at] tagpovrayorg> wrote:
> Aydan <hes### [at] hendrik-sachsenet> wrote:
> > [begin code]
> > class vector(object):
> > def __init__(self,x,y,z):
> > self.__x=x
> > self.__y=y
> > self.__z=z
>
> Is that really how you write OO code in Python? Is it just me, or does it
> look like Python hasn't actually been specifically designed to be an OO
> language?
>
> --
> - Warp
What do you mean?
Python doesn't have private variables per se and is completely dynamic.
Everything in Python is an object. Functions, classes, modules even integers are
objects.
So python is very much designed for OO.
if you define a variable with "__" it won't be acessible from outside it's scope
without difficulty. For example you can't see it with introspection and you
can't access it even if you know it's declaration. I think it gets prepended
with a hash value on instantiation.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
On 15/10/2012 07:56 PM, Aydan wrote:
> Everything in Python is an object. Functions, classes, modules even integers are
> objects.
> So python is very much designed for OO.
Everything in JavaScript is an object. However, JavaScript does not have
the concepts of "classes" or "inheritance" or "encapsulation". Whether
you consider JavaScript to be "object-oriented" or not depends on what
you consider "object-oriented" to actually mean...
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|