473,396 Members | 1,738 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

oo problem

Hi,
I've got a simple but difficult problem :

Suppose I've got a Paper class, on wich I can draw i.e a rectangle, a
circle or whatever.

class Paper(...):
def __init__(self, paperx, papery):
self.paperx = paperx
self.papery = papery
....
def draw(self, Primitive_Object):
....
class Rectangle( ): <--- a Primitive_Object
...

Now, inside my Rectangle class, I need to recover the Paper instance
who called it (because I need the paper sizes to calculate something).
I now I can use a global variable, say " _paper" and then, inside my
Paper.__init__() write something like this :

global _paper
_paper = [paperx,papery]

But it has drawbacks : what if I've got several Paper instances ?

I don't know if I'm clear enought,
Thanks for your help :
6TooL9

Dec 10 '06 #1
11 1320
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

many class libraries use a parent attribute for this purpose:

class Rectangle (object):
__init__(self, parent):
#Use the parent as "private": nobody except your own #class should
mess around with it ...
self._parent = parent

The parent of course needs to be an existing Paper instance.

You might check whether the given value for parent is indeed a Paper
instance in your Rectangle's __init__, otherwise you might get strange
AttributeError exceptions when using the parent later.

Hope that helps!

Nils
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFFe+SyRQeuB6ws8wERAuTOAKCPKe8m9BNP7Vf/aFpJSWTfOkF8pQCgvkxG
+xmcU+UB7fT0fi8/Jz+o15E=
=pW+u
-----END PGP SIGNATURE-----
Dec 10 '06 #2
Tool69 schrieb:
Hi,
I've got a simple but difficult problem :

Suppose I've got a Paper class, on wich I can draw i.e a rectangle, a
circle or whatever.

class Paper(...):
def __init__(self, paperx, papery):
self.paperx = paperx
self.papery = papery
....
def draw(self, Primitive_Object):
....
class Rectangle( ): <--- a Primitive_Object
...

Now, inside my Rectangle class, I need to recover the Paper instance
who called it (because I need the paper sizes to calculate something).
You can simply pass a paper reference to a rectangle object. But better
you pass only the information to the rectangle that is necessary,
because you decouple the objects this way:

class Rectangle:
def __init__(self):
self.paper_coordinates = [0,0] # default value

class Paper:
...
def draw(self, shape):
shape.paper_coordinates = self.x, self.y
shape.draw()
...

Dec 10 '06 #3
Thanks for your answers,
I though about the first solution too, but I've redundant code, say ie:
p = Paper(100,200)
p.draw( Rectangle(p,10,20,50,60) ) <-- we're forced to write 'p' two
times.

But that maybe the best solution, as I cannot see anything else.

For the second one, I need to make some calculus on the shape to be
drawn, so if I write:

shape.paper_coordinates = self.x, self.y
shape.draw()

It's too late, the calculus have already been done with the default
values, right or not?

Thanks,
6TooL9

Dec 10 '06 #4
Tool69 wrote:
Hi,
I've got a simple but difficult problem :

Suppose I've got a Paper class, on wich I can draw i.e a rectangle, a
circle or whatever.

class Paper(...):
def __init__(self, paperx, papery):
self.paperx = paperx
self.papery = papery
....
def draw(self, Primitive_Object):
....
class Rectangle( ): <--- a Primitive_Object
...

Now, inside my Rectangle class, I need to recover the Paper instance
who called it (because I need the paper sizes to calculate something).
I now I can use a global variable, say " _paper" and then, inside my
Paper.__init__() write something like this :

global _paper
_paper = [paperx,papery]

But it has drawbacks : what if I've got several Paper instances ?

I don't know if I'm clear enought,
Thanks for your help :
6TooL9
I think you may not be thinking about your problem in the most
object-oriented way. For example, the Paper.draw() method will already
have a reference to the "calling" Paper instance accessible via the name
"self". E.g.:

class Paper(...
def draw(self, primitive):
do_something_with(self.paperx, self.papery)
# etc

Now, if the draw() method were in the primitive and not the paper, then
a reference to the paper should be kept in the primitive. But, as you
will see below, this seems to make little sense (to me, at least).

If you find that you need to access the primitive's "parent" paper
attributes from within the primitive, then you might want to check
whether you have structured your code in the most sensible manner.
Conceptually, children shouldn't be overly concerned with the workings
of their parents, lest they be a bit too presumptuous and risk a good
scolding.

The thought process I always go through is "why does this object need to
have this particular reference?" Do primitives really need to know
anything about the paper on which they are drawn?

I try not to make objects overly reflexive. For example, should a
primitive really be drawing itself? Perhaps something else should bring
a primitive into existence based on the attributes contained in a
primitive's data structure and the properties of the medium in which or
on which it will exist.

What if some creator had asked of you: "Embed Thyself unto the 3-D
Manifold Known as the Universe." Your first requirement before any steps
toward physical existence would, of course, be a reference to the
Universe--so that you could see if you would actually fit.

Perhaps it would be better for a 3rd party to manage the process of
person creation, like, say, a mother? Children would then not be
required to ponder the extent of the Universe before their own physical
manifestation and could focus on things more meaningful to themselves,
like whether they are hungry or need to go potty.

By this thought process, I propose that it makes more sense to create a
Drawing object that has references to both the primitives and the paper
and then manage drawing through that object.

class Drawing(object):
def __init__(self, paper, primitives):
self._paper = paper
self._primitives = primitives

my_primitives = [Square(5), Circle(10), DoubleEndedArrow(5,5,5,1,2,1,2)]
my_paper = Paper()
my_drawing = Drawing(my_paper, my_primitives)

Now the paper can just worry about its paper specific attributes (which
might be its dimensions, border, bond weight, etc), the primitives can
worry about primitive specific attributes (size, line-width,
fill-color), and the drawing can manage everything required to make a
drawing (paper, primitives, color model, etc.).

I think that this is the what you were getting at with your global
"_paper" variable, except now "global" is the context of the Drawing class.

James

Dec 10 '06 #5
Thanks James,

It was a matter of choice : in my earlier version, all primitives know
how to draw themselves, but they needed to have a parent and I found it
was not good for aesthetic reasons.

but I think I've been misunderstood. Let's take a concrete sample :

I've got a Paper instance(-5,5,5,5) (the coordinates of lower-left and
upper-right rectangle: xlowleft, ylowlef, xupright, yupright) of my
paper.
I want now to draw an x-axis on it with some ticks and maybe lables, I
need to catch the xlowleft and xupright variables of the Paper inside
my primitive, ok ?
The problem lies inside my primitive, not on the draw method.
Here's a simplified example, I need to retrieve paper.xll and
paper.xur:

class Graduate_x( primitive ):
def __init__(self, orient = 'se', xorigin = 0, yorigin=0, xunit=
1.0, yunit=1.0):
primitive.__init__(self)
for k in range( int(math.floor(( paper.xll - xorigin)/xun)),
int(math.floor((paper.xur-xorigin)/yun)) ):
...something to construct my path

Dec 10 '06 #6
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Tool69 wrote:
It was a matter of choice : in my earlier version, all primitives know
how to draw themselves, but they needed to have a parent and I found it
was not good for aesthetic reasons.
Why should a parent reference not be aesthetic? OOD is all about Objects
and their relationships.

I want now to draw an x-axis on it with some ticks and maybe lables, I
need to catch the xlowleft and xupright variables of the Paper inside
my primitive, ok ?
This sentence describes the relationship between the paper and your
Rectangle (to stick to your first example) as an association:

The Rectangle needs to access information from the Paper. Moreover, the
relationship could be named "Rectangle lies on Paper" this is perfect
OOD in my opinion.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFFfGPmRQeuB6ws8wERAgBgAKCiNlNU5vuVmUQQWy/Trqv2/hfd2gCg39Sh
WC2+yoWA+lpJ4PNQ1sfiFTU=
=UIww
-----END PGP SIGNATURE-----
Dec 10 '06 #7
Tool69 wrote:
Thanks James,

It was a matter of choice : in my earlier version, all primitives know
how to draw themselves, but they needed to have a parent and I found it
was not good for aesthetic reasons.

but I think I've been misunderstood. Let's take a concrete sample :

I've got a Paper instance(-5,5,5,5) (the coordinates of lower-left and
upper-right rectangle: xlowleft, ylowlef, xupright, yupright) of my
paper.
I want now to draw an x-axis on it with some ticks and maybe lables, I
need to catch the xlowleft and xupright variables of the Paper inside
my primitive, ok ?
The problem lies inside my primitive, not on the draw method.
Here's a simplified example, I need to retrieve paper.xll and
paper.xur:

class Graduate_x( primitive ):
def __init__(self, orient = 'se', xorigin = 0, yorigin=0, xunit=
1.0, yunit=1.0):
primitive.__init__(self)
for k in range( int(math.floor(( paper.xll - xorigin)/xun)),
int(math.floor((paper.xur-xorigin)/yun)) ):
...something to construct my path
You can simply pass the paper to the __init__ method and even store a
reference to the paper there if you have to re-construct the path later,
say if the paper size changes or the origins of the primitive change. I
wouldn't advise storing references to the primitives in the paper as
well, because you would get circular references.

Global variables are probably not the way to handle this. For OO, if you
feel like you need a global variable, try to think up an object that can
sensibly contain all the objects that would be global.

James
Dec 10 '06 #8

Dennis Lee Bieber a écrit :
On 10 Dec 2006 03:47:21 -0800, "Tool69" <ki****************@gmail.com>
declaimed the following in gmane.comp.python.general:
Thanks for your answers,
I though about the first solution too, but I've redundant code, say ie:
p = Paper(100,200)
p.draw( Rectangle(p,10,20,50,60) ) <-- we're forced to write 'p' two
times.

I'd suggest not passing an instance initialization to your "Paper"
draw() method...

p = Paper(100, 200)
p.add(Rectangle(10, 20, 50, 60))
p.add(OtherPrimitives())
p.draw()

where p.draw() (Paper.draw(self) really) does something like:

self.whatever_is_needed_for_Paper_itself
for prm = self.primitives: #list of stuff from p.add(...) calls
prm.draw(self) #pass current paper to the primitive
#which draws itself on the paper
#and can do whatever calculations
#(CLIPPING perhaps) needed
Thanks for all your comments and suggestions.
Denis, I would like to know how I can made a draw method for a
primitive without a Paper instance inside ...that's always the same
problem as only my Paper instance knows the Paper sizes !

Dec 12 '06 #9

Dennis Lee Bieber a écrit :
>
Perhaps you missed that the loop (in Paper) that invokes each
primitive's draw() is passing itself (the Paper instance)...
Oops, sorry I missed it in fact.

But I still have a problem with my the primitives (some pathes I had to
build ):
i.e a mathematical ray is infinite, so I must draw a segment on screen
and need the paper sizes to calculate the segments starts and ends (
I've got a lot of objects like this ). I don't know how to build them
without passing a paper instance.
The actual implementation of some primitives uses :

def __init__(self, paper_instance, etc. ):
do something

But I as mentioned before, I'm not satisfied with it since I shall
write this do draw a Line :*
paper.draw( Line( paper, x1, y1, x2, y2) This is what I don't find
aesthetic : the repetition of "paper" calls.

Dec 12 '06 #10
Tool69 a écrit :
Hi,
I've got a simple but difficult problem :

Suppose I've got a Paper class, on wich I can draw i.e a rectangle, a
circle or whatever.

class Paper(...):
def __init__(self, paperx, papery):
self.paperx = paperx
self.papery = papery
....
def draw(self, Primitive_Object):
....
class Rectangle( ): <--- a Primitive_Object
...

Now, inside my Rectangle class, I need to recover the Paper instance
who called it (because I need the paper sizes to calculate something).
I now I can use a global variable, say " _paper" and then, inside my
Paper.__init__() write something like this :

global _paper
_paper = [paperx,papery]

But it has drawbacks :
Indeed...
what if I've got several Paper instances ?
class Paper(...):
....
def draw(self, drawable):
drawable.draw(self)

class Rectangle( ): <--- a drawable
...
def draw(self, drawing_surface):
...

Now consider whether you really need Paper.draw...

HTH
Dec 12 '06 #11
Hi,
First, let me thanks you for all your clear comments.

>
This is, in my mind, both a usage and a design flaw.

You are creating (and throwing away) instances of drawable
objects to the draw method of a paper instance. But what does
paper.draw() actually do with the drawable object? Call a draw method
within it?
No, actually the paper instance is a subclass of a canvas from an
external module. And this one have a stroke() method.
In reading your comments, I think it's now clear that I must get back
and let any primitive have an inner draw() method ( a subclass of
Drawable object in our case).
If so, that is when you should pass the paper instance (or
just the part needed -- clipping rectangle perhaps?).
In fact, my approach was a bad one : in initialising the paper instance,
I was already clipping it.
If I wrote : p = Paper(-5,-5,5,5), all drawings made on that paper will
be clipped inside a rectangle with lower-left corner (-5,-5) and
upper-right corner (5,5).
Now, I think it's better to clip after all primitives have been added to
the paper.
>
The actual implementation of draw() for each primitive will have
to handle clipping to the boundaries of the Canvas object that is passed
to it.

You'll notice that the only place the primitive needs to know
about the canvas is in its specific draw method. And only at that time
is the canvas (paper) passed to it.

Instead of the concept;

Paper, draw a line from x to y

(and having to pass the "paper" to the initializer of the line
primitive), you have to think in terms of:

Line, draw yourself on this paper

Or, if you consider the last example above… Compare that to your
example:

-=-=-=-=-
paper.draw( Line( paper, x1, y1, x2, y2) )
-=-=-=-=-=-

Here, you are telling the paper to do the drawing, and passing
it a Line instance (and passing it the paper it is supposed to be drawn
on). Why? The paper isn't drawing the line on itself… While

-=-=-=-=-
Line(Point(x1, y1), Point(x2, y2)).draw(paper)
-=-=-=-=-

initializes a Line instance, then asks it to draw itself using paper as
the surface to be drawn upon.
Yes I was wrong, that's all clear now.
Thanks again, this was very helpfull.

6TooL9
Dec 13 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Kostatus | last post by:
I have a virtual function in a base class, which is then overwritten by a function of the same name in a publically derived class. When I call the function using a pointer to the derived class...
117
by: Peter Olcott | last post by:
www.halting-problem.com
18
by: Ian Stanley | last post by:
Hi, Continuing my strcat segmentation fault posting- I have a problem which occurs when appending two sting literals using strcat. I have tried to fix it by writing my own function that does the...
28
by: Jon Davis | last post by:
If I have a class with a virtual method, and a child class that overrides the virtual method, and then I create an instance of the child class AS A base class... BaseClass bc = new ChildClass();...
6
by: Ammar | last post by:
Dear All, I'm facing a small problem. I have a portal web site, that contains articles, for each article, the end user can send a comment about the article. The problem is: I the comment length...
16
by: Dany | last post by:
Our web service was working fine until we installed .net Framework 1.1 service pack 1. Uninstalling SP1 is not an option because our largest customer says service packs marked as "critical" by...
2
by: Mike Collins | last post by:
I cannot get the correct drop down list value from a drop down I have on my web form. I get the initial value that was loaded in the list. It was asked by someone else what the autopostback was...
0
by: =?Utf-8?B?am8uZWw=?= | last post by:
Hello All, I am developing an Input Methop (IM) for PocketPC / Windows Mobile (PPC/WM). On some devices the IM will not start. The IM appears in the IM-List but when it is selected from the...
1
by: sherifbk | last post by:
Problem description ============== - I have 4 clients and 1 server (SQL server) - 3 clients are Monitoring console 1 client is operation console - Monitoring console collects some data from...
9
by: AceKnocks | last post by:
I am working on a framework design problem in which I have to design a C++ based framework capable of solving three puzzles for now but actually it should work with a general puzzle of any kind and I...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.