using names before they're defined

D

davehowey

I have a problem. I'm writing a simulation program with a number of
mechanical components represented as objects. When I create instances
of objects, I need to reference (link) each object to the objects
upstream and downstream of it, i.e.

supply = supply()
compressor = compressor(downstream=combustor, upstream=supply)
combuster = combuster(downstream=turbine, upstream=compressor)
etc.

the problem with this is that I reference 'combustor' before is it
created. If I swap the 2nd and 3rd lines I get the same problem
(compressor is referenced before creation).


aargh!!! any ideas on getting around this?

Dave
 
I

Iain King

I have a problem. I'm writing a simulation program with a number of
mechanical components represented as objects. When I create instances
of objects, I need to reference (link) each object to the objects
upstream and downstream of it, i.e.

supply = supply()
compressor = compressor(downstream=combustor, upstream=supply)
combuster = combuster(downstream=turbine, upstream=compressor)
etc.

the problem with this is that I reference 'combustor' before is it
created. If I swap the 2nd and 3rd lines I get the same problem
(compressor is referenced before creation).


aargh!!! any ideas on getting around this?

Dave

At the top of your code you could put:

supply = None
compressor = None
combuster = None
turbine = None

It might be better, though, to arrange your code like:
supply = Supply()
compressor = Compressor()
combuster = Combuster()
turbine = Turbine()
compressor.setStreams(down=combuster, up=supply)
combuster.setStreams(down=turbine, up=compressor)

Do the streams reflect each other? That is, if supply.down is
compressor, is compressor.up supply? In that case you probably want to
do something like:

class Component():

upstream = None
downstream = None

def setUpstream(self, c):
self.upstream = c
if c.downstream != self:
c.setDownstream(self)

def setDownstream(self, c):
self.downstream = c
if c.upstream != self:
c.setUpstream(self)

class Supply(Component):
pass

etc.

Iain
 
S

Steve Holden

I have a problem. I'm writing a simulation program with a number of
mechanical components represented as objects. When I create instances
of objects, I need to reference (link) each object to the objects
upstream and downstream of it, i.e.

supply = supply()
compressor = compressor(downstream=combustor, upstream=supply)
combuster = combuster(downstream=turbine, upstream=compressor)
etc.

the problem with this is that I reference 'combustor' before is it
created. If I swap the 2nd and 3rd lines I get the same problem
(compressor is referenced before creation).


aargh!!! any ideas on getting around this?
Yes. You are building a generic data structure, so you shouldn't really
be trying to store individual objects in variables like that. You need a
data structure that's appropriate to your problem.

For example, you could consider storing them in a list, so you have

components = [supply(), compressor(), combuster()]

Then components[n] is upstream of components[n-1] and downstream of
components[n+1].

In short, your thinking about data representation might need to become a
little more sophisticated.

regards
Steve
 
L

Larry Bates

What about something like:

supply = supply()
compressor = compressor(supply)
combuster = combuster(compressor)
compressor.append(combuster)
turbine = turbine(combuster)
combuster.append(turbine)


-Larry Bates
 
D

Diez B. Roggisch

I have a problem. I'm writing a simulation program with a number of
mechanical components represented as objects. When I create instances
of objects, I need to reference (link) each object to the objects
upstream and downstream of it, i.e.

supply = supply()
compressor = compressor(downstream=combustor, upstream=supply)
combuster = combuster(downstream=turbine, upstream=compressor)
etc.

the problem with this is that I reference 'combustor' before is it
created. If I swap the 2nd and 3rd lines I get the same problem
(compressor is referenced before creation).


aargh!!! any ideas on getting around this?

the only thing you can do is to either use a name to identify the component

supply = supply('supply')
compressor = compressor(downstream='combustor', upstream='supply')
combuster = combuster(downstream='turbine', upstream='compressor')

or to use some shallow objects that you then fill with information later

supply = supply()
combustor = combustor()
compressor = compressor()
turbine = turbine()
combuster.attach(downstream=turbine' upstream=compressor)


Diez
 
D

davehowey

Iain, thanks - very helpful.

Really I'm trying to write a simulation program that goes through a
number of objects that are linked to one another and does calculations
at each object. The calculations might be backwards or fowards (i.e.
starting at the supply or demand ends of the system and then working
through the objects). And also, I might have multiple objects linked to
a single object (upstream or downstream) - e.g. compressor -- multiple
combusters - turbine

I like your idea of using something like a setStreams method to
establish the linking. The streams do reflect each other, although
having many-to-one and vice versa will complicate that. I have not
quite got my head around having multiple links. In C++ I would be
thinking about something like a linked-list but I'm not sure that's the
right approach here.

Dave
 
B

Bruno Desthuilliers

I have a problem. I'm writing a simulation program with a number of
mechanical components represented as objects. When I create instances
of objects, I need to reference (link) each object to the objects
upstream and downstream of it, i.e.

supply = supply()

NB : Python convention is to use CamelCase for non-builtin types. FWIW,
the above line will rebind name 'supply', so it won't reference the
supply class anymore...
compressor = compressor(downstream=combustor, upstream=supply)
combuster = combuster(downstream=turbine, upstream=compressor)
etc.

the problem with this is that I reference 'combustor' before is it
created. If I swap the 2nd and 3rd lines I get the same problem
(compressor is referenced before creation).


aargh!!! any ideas on getting around this?

Solution 1: do a two-stages initialisation


supply = Supply()
compressor = Compressor()
combuster = Combuster()
turbine = Turbine()

compressor.chain(downstream=combustor, upstream=supply)
combuster.chain(downstream=turbine, upstream=compressor)

etc...

Tedious and error-prone... Unless you use a conf file describing the
chain and a function building it, so you're sure the 2-stage init is
correctly done.


Solution 2: 'implicit' chaining

if I understand the problem correctly, your objects are chained, ie:
supply <- compressor <- combuster <- turbine...

If yes, what about:

class Chainable(object):
def __init__(self, upstream):
self.upstream = upstream
if upstream is not None:
upstream.downstream = self

class Supply(Chainable):
#

# etc

then:

supply = Supply()
compressor = Compressor(upstream=supply)
combuster = Combuster(upstream=compressor)
turbine = Turbine(upstream=combuster)


Or if you don't need to keep direct references to all elements of the chain:


class Chainable(object):
def __init__(self, downstream=None):
self.downstream = downstream
if downstream is not None:
downstream.upstream = self


supply = Supply(
downstream=Compressor(
downstream=Combuster(
downstream=Turbine()
)
)
)

or more simply:
supply = Supply(Compressor(Combuster(Turbine())))


FWIW, you could then make Chainable class an iterable, allowing:
for item in supply:
# will yield supply, then compressor, then combuster, then turbine
but I don't know if it makes any sens wrt/ your app !-)

Now there can of course be a lot of other solutions...
 
N

Nick Vatamaniuc

Your can of course initialize the components first:

compr=Compressor(...),
comb=Combuster(...),
sup=Supply(...) ,
tur=Turbine(...).

Then do:

compr.up, compr.down =sup, comb
comb.up, comb.down =compr, tur

Even if you need to do something during attachment of components it is
more Pythonic to use properties. So you will write a method in your
class name something like _set_up(self,upstream_obj) an _get_up(self).
And then at the end of your class put up=property(_get_up, _set_up).
You can still use the compr.up=... format.

Also, you might want to re-think your OO design. It seem that all of
your components do a lot of things in common already. For one they all
are connected to other components like themselves, they also propably
will have method to do some computing, perhaps send or receive stuff
from other components, or they all will implement somekind of an event
model. In that case you could create a generic component class and
sublass the specific implementations from it. For example:
class Component(object):
send(...)
recv(...)
up
down
print_data(...)
...

Then do:
class Turbine(Component):
method_specific_to_turbine(...)
send(...) #override some methods
...
and so on. Of course I am not familiar with your problem in depth all
this might not work for you, just use common sense.

Hope this helps,
Nick Vatamaniuc
 
D

davehowey

Bruno,

Thanks. An issue is that I need to be able to link multiple objects to
a single object etc.
Say for example using the previous wording, I might have compressor -
multiple combustors - turbine

this complicates things slightly.

my current thought is to do a two stage initialisation

1. create the objects
compressor = compressor()
combuster1 = combuster()
combuster2 = combuster()

etc

2. link them
compressor.link(downstream = [combuster1, combuster2])
combuster1.link(upstream = compressor)
etc.

hmmmm I need to give it some more though, particularly how I solve all
the linked objects (which is the point)

Dave
 
D

davehowey

Even if you need to do something during attachment of components it is
more Pythonic to use properties. So you will write a method in your
class name something like _set_up(self,upstream_obj) an _get_up(self).
And then at the end of your class put up=property(_get_up, _set_up).
You can still use the compr.up=... format.

sorry, I don't quite follow. what are properties?
Also, you might want to re-think your OO design. It seem that all of
your components do a lot of things in common already. For one they all
are connected to other components like themselves, they also propably
will have method to do some computing, perhaps send or receive stuff
from other components, or they all will implement somekind of an event
model. In that case you could create a generic component class and
sublass the specific implementations from it.

yes, I already do this - I have a component class and then the other
components inherit from it.

Dave
 
D

Dennis Lee Bieber

I like your idea of using something like a setStreams method to
establish the linking. The streams do reflect each other, although
having many-to-one and vice versa will complicate that. I have not

Shouldn't be that difficult; store a list of the "many" end and
cycle through the list...

Silly example, but visualize a water tank feeding irrigation
fields...

tank => [north_pipe, east_pipe, south_pipe, west_pipe]
<= None

north_pipe => [north_north_40, north_east_40, north_south_40,
north_west_40]
<= [tank]

north_north_40 => None
<= [north_pipe]
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
R

Rob Williscroft

Iain King wrote in @s13g2000cwa.googlegroups.com in comp.lang.python:
(e-mail address removed) wrote:
[...] I need to reference (link) each object to the objects
upstream and downstream of it, i.e.

supply = supply()
compressor = compressor(downstream=combustor, upstream=supply)
combuster = combuster(downstream=turbine, upstream=compressor)
etc.

the problem with this is that I reference 'combustor' before is it
created. [...]
At the top of your code you could put:

supply = None
compressor = None
combuster = None
turbine = None

That doesn't help.

The variable names will be rebound when assigned to the result of
the contructor calls, but only after the previous binding (None) has
been passed to some other objects constructor.

IOW the second line of the OP's code would effectively be:

compressor = Compressor(downstream=None, upstream=supply)

Rob.
 
P

Paddy

I have a problem. I'm writing a simulation program with a number of
mechanical components represented as objects. When I create instances
of objects, I need to reference (link) each object to the objects
upstream and downstream of it, i.e.

supply = supply()
compressor = compressor(downstream=combustor, upstream=supply)
combuster = combuster(downstream=turbine, upstream=compressor)
etc.

the problem with this is that I reference 'combustor' before is it
created. If I swap the 2nd and 3rd lines I get the same problem
(compressor is referenced before creation).


aargh!!! any ideas on getting around this?

Dave
Hi Dave,
In Digital electronics we have what are called netlists, (and also
component lists)

We have component types (map them to component objects); named
instances of components (instances); then we have net types (you could
probably get away with one net type) which models connections between
ports on a component.


class Port:
def __init__(self, direction):
self.direction = direction
class Comp:
def __init__(self,compType,name):
self.upstream = Port("U")
self.downstream = Port("D")
self.name = name
self.compType = compType
class Link:
def __init__(self, name, *connections):
self.connections = connections
self.name = name

# Instantiate your components
supply1 = Comp("supply", "supply1")
supply2 = Comp("supply", "supply2")
compressor1 = Comp("compressor", "compressor1")

# Instantiate Links and link in ports of component intances
supply2comp = Link("supply2comp", supply1.downstream,
compressor1.upstream)
# ...

With a bit more effort you can create component and link factories
that will name instances with the variable they are assigned to
without having to put that information in twice.

- Paddy.
 
J

jordan.nick

Steve said:
I have a problem. I'm writing a simulation program with a number of
mechanical components represented as objects. When I create instances
of objects, I need to reference (link) each object to the objects
upstream and downstream of it, i.e.

supply = supply()
compressor = compressor(downstream=combustor, upstream=supply)
combuster = combuster(downstream=turbine, upstream=compressor)
etc.

the problem with this is that I reference 'combustor' before is it
created. If I swap the 2nd and 3rd lines I get the same problem
(compressor is referenced before creation).


aargh!!! any ideas on getting around this?
Yes. You are building a generic data structure, so you shouldn't really
be trying to store individual objects in variables like that. You need a
data structure that's appropriate to your problem.

For example, you could consider storing them in a list, so you have

components = [supply(), compressor(), combuster()]

Then components[n] is upstream of components[n-1] and downstream of
components[n+1].

Unfortunately, if he wanted to make the topology more complicated, for
instance having two components downstream, it would be much more
cumbersome to inherit the list object and implement this.
In short, your thinking about data representation might need to become a
little more sophisticated.

That sounds a little arrogant. sorry!
 
P

Paul McGuire

I have a problem. I'm writing a simulation program with a number of
mechanical components represented as objects.

Have you looked at SimPy? This may simplify much of your data
structure anguish (probably only need forward refs, without the back
refs), plus it will do all the discrete event scheduling for you.

-- Paul
 
N

Nick Vatamaniuc

Dave,

Python properties allow you to get rid of methods like c.getAttr(),
c.setAttr(v), c.delAttr() and replace them with simple constructs like
c.attr, c.attr=v and del c.attr.

If you have been using Java or C++ you know that as soon as you code
your class you have to start filling in the get() set()
delete()/reset() methods for each attribute. Some IDE tools like
Netbeans will to it for you with code refactoring and such. But for 10
attributes you will end up having another 20 or so
accessors/setters/and erase methods.

In Python not too long ago they introduced properties. With properties
you just access you attributes as attributes c.attr and c.attr=value if
you don't need to do anything special during getting and setting. Then
you can safely publish your API for everyone to use. If one day you
find a off-by-1 bug and you need to change one of the attributes when
it is accessed or set, you use properties. You create a method like
_get_attr(self) or _set_attr(self,v) in your class and at the end of
the class definition you write:
attr=property(_get_attr, _set_attr). From then on, when someone
accesses the attribute of your class c.attr the function _get_attr()
will be automatically called, in there you can do whatever you need and
return the value.

Check out this page:
http://www.python.org/download/releases/2.2/descrintro/
Look further down in the page for "properties".

Also take a look at "Python Is Not Java" article, it was interesting
for me to read. Properties getters and setters are mentioned there too
under the "getter and setters are Evil!" section ;) Here is the link:
http://dirtsimple.org/2004/12/python-is-not-java.html

Nick V.
 
S

Steve Holden

Steve said:
I have a problem. I'm writing a simulation program with a number of
mechanical components represented as objects. When I create instances
of objects, I need to reference (link) each object to the objects
upstream and downstream of it, i.e.

supply = supply()
compressor = compressor(downstream=combustor, upstream=supply)
combuster = combuster(downstream=turbine, upstream=compressor)
etc.

the problem with this is that I reference 'combustor' before is it
created. If I swap the 2nd and 3rd lines I get the same problem
(compressor is referenced before creation).


aargh!!! any ideas on getting around this?

Yes. You are building a generic data structure, so you shouldn't really
be trying to store individual objects in variables like that. You need a
data structure that's appropriate to your problem.

For example, you could consider storing them in a list, so you have

components = [supply(), compressor(), combuster()]

Then components[n] is upstream of components[n-1] and downstream of
components[n+1].


Unfortunately, if he wanted to make the topology more complicated, for
instance having two components downstream, it would be much more
cumbersome to inherit the list object and implement this.
I quite agree. That was why I began with "for example".
That sounds a little arrogant. sorry!
Hmm, maybe it does, in which case I apologise retrospectively. But all
the more appropriate suggestions have definitely been pointing that way.

Circuit design is a complex problem. I was merely trying to indicate
that the naive approach was unlikely to succeed. Sure enough, a few
posts later the OP admitted that there needed to be sub-chains for
sub-circuits, and so on.

regards
Steve
 
I

Iain King

Iain, thanks - very helpful.

Really I'm trying to write a simulation program that goes through a
number of objects that are linked to one another and does calculations
at each object. The calculations might be backwards or fowards (i.e.
starting at the supply or demand ends of the system and then working
through the objects). And also, I might have multiple objects linked to
a single object (upstream or downstream) - e.g. compressor -- multiple
combusters - turbine

I like your idea of using something like a setStreams method to
establish the linking. The streams do reflect each other, although
having many-to-one and vice versa will complicate that. I have not
quite got my head around having multiple links. In C++ I would be
thinking about something like a linked-list but I'm not sure that's the
right approach here.

Dave

You don't need linked-lists : python has a list type built in.
Example:

class Component():

upstream = []
downstream = []

def addUpstream(self, c):
self.upstream.append(c)
if not self in c.downstream:
c.addDownstream(self)

def addDownstream(self, c):
self.downstream.append(c)
if not self in c.upstream:
c.addUpstream(self)

def remUpstream(self, c):
c.downstream.remove(self)
self.upstream.remove(c)

def remDownstream(self, c):
c.upstream.remove(self)
self.downstream.remove(c)

def cascadeDownTest(self):
print self
# this could run forever if you connect components in a circle:
for c in self.downstream:
c.cascadeDownTest()

Iain
 
D

davehowey

Paddy,

thanks for your mail.
In Digital electronics we have what are called netlists, (and also
component lists)

yes, years back I did a 3rd year project on a 'logic simulator' which
used the kind of thing you are talking about. I think spice does as
well. Fortunately my problem is a little simpler, phew. [by the way, as
an aside, check out modelia/dymola for some really powerful simulation
stuff http://www.dynasim.se/ - it uses powerful symoblic algebra
algorithms to derive system equations and the solve them numerically]
With a bit more effort you can create component and link factories
that will name instances with the variable they are assigned to
without having to put that information in twice.

sorry - could you explain a bit more? sounds interesting and also
brings me onto another question that has been bugging me, which is, if
I want to create components (as object instances) at run time (rather
than through a python code imported in), how do I do this? i.e. if I
hardcoded something like
turbine1 = turbine(...)
then python knows that turbine1 is a turbine. but if I had say some
kind of user interface and I want to create turbine1 (or suchlike) on
the fly, how do I actually do that? how do I create objects after run
time?

Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top