By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,537 Members | 1,416 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,537 IT Pros & Developers. It's quick & easy.

using names before they're defined

P: n/a
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

Jul 19 '06 #1
Share this Question
Share on Google+
34 Replies


P: n/a

daveho...@f2s.com wrote:
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

Jul 19 '06 #2

P: n/a
da*******@f2s.com wrote:
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
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Jul 19 '06 #3

P: n/a
What about something like:

supply = supply()
compressor = compressor(supply)
combuster = combuster(compressor)
compressor.append(combuster)
turbine = turbine(combuster)
combuster.append(turbine)
-Larry Bates
da*******@f2s.com wrote:
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
Jul 19 '06 #4

P: n/a
da*******@f2s.com wrote:
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
Jul 19 '06 #5

P: n/a
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

Jul 19 '06 #6

P: n/a
da*******@f2s.com wrote:
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...

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 19 '06 #7

P: n/a
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

da*******@f2s.com wrote:
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
Jul 19 '06 #8

P: n/a
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

Jul 19 '06 #9

P: n/a
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

Jul 19 '06 #10

P: n/a
Iain King wrote in news:1153323649.171612.74510
@s13g2000cwa.googlegroups.com in comp.lang.python:
>
daveho...@f2s.com 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.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '06 #11

P: n/a
da*******@f2s.com a écrit :
>>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?
Computed attributes. cf
http://www.python.org/doc/2.2.3/what...00000000000000


Jul 19 '06 #12

P: n/a

da*******@f2s.com wrote:
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.

Jul 19 '06 #13

P: n/a

Steve Holden wrote:
da*******@f2s.com wrote:
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!
regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden
Jul 19 '06 #14

P: n/a
da*******@f2s.com wrote:
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

Jul 20 '06 #15

P: n/a
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.

da*******@f2s.com wrote:
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
Jul 20 '06 #16

P: n/a
jo*********@gmail.com wrote:
Steve Holden wrote:
>>da*******@f2s.com wrote:
>>>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".
>
>>In short, your thinking about data representation might need to become a
little more sophisticated.


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
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Jul 20 '06 #17

P: n/a

da*******@f2s.com wrote:
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

Jul 20 '06 #18

P: n/a
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

Jul 20 '06 #19

P: n/a
da*******@f2s.com wrote:
(snip)
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?
Q&D possible solution, no error handling, etc
....just so you get an idea

# schema generated by a GUI
# or directly written in a .py config file
# or whatever

schema = {'turbine1': {'class': 'Turbine',
'upstream' : ('frobnicator2',),
'downstream' : () # nothing,
},
'frobnicator2' : {'class' : 'Frobnicator',
'upstream' : (),
'downstream' : ('frobnicator2',),
},
}

# code:

def get_class_by_name(name):
return globals()[name]

def chain_from_schema(schema):
objects = {}
for name, desc in schema:
klass = get_class_by_name(desc['class'])
objects[name] = klass()
for name, desc in schema:
target = objects[name]
ups = [objects[upname] for upname in desc['upstream']]
downs = [objects[downname] for downname in desc['downstream']]
target.links(upstream=ups, downstream=downs)
return objects
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 20 '06 #20

P: n/a
Hiya

Could you just talk me through this... is it:
schema = {'turbine1': {'class': 'Turbine',
'upstream' : ('frobnicator2',),
'downstream' : () # nothing,
},
'frobnicator2' : {'class' : 'Frobnicator',
'upstream' : (),
'downstream' : ('frobnicator2',),
},
}
ok, so schema is a dictionary of different components, defining what
class they are and what they're connected to.
def get_class_by_name(name):
return globals()[name]
what does this function do exactly?
def chain_from_schema(schema):
objects = {} # so objects is our list of objects ?
for name, desc in schema: # can you step through a dictionary like this?
klass = get_class_by_name(desc['class']) # does this create an object called klass?
objects[name] = klass()

sorry for being dim..
Dave

Jul 20 '06 #21

P: n/a
I don't know if you saw my earlier post but something like
this has worked for me.

What about something like:

supply = supply()
compressor = compressor(supply)
combuster1= combuster(compressor)
combuster2= combuster(compressor)
compressor.append(combuster1)
compressor.append(combuster2)

or perhaps

compressor.extend([combuster1, combuster2])
turbine = turbine(combuster)
combuster.append(turbine)
If you implement .append and .extend methods
on your classes they will allow you to append single
downstream objects or extend with a list of them.
Just keep a list self.downstream and append/extend
it. IMHO it makes what is going on intuitively obvious.

-Larry Bates

da*******@f2s.com wrote:
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
Jul 20 '06 #22

P: n/a
da*******@f2s.com a écrit :
Hiya

Could you just talk me through this... is it:

>>schema = {'turbine1': {'class': 'Turbine',
'upstream' : ('frobnicator2',),
'downstream' : () # nothing,
},
'frobnicator2' : {'class' : 'Frobnicator',
'upstream' : (),
'downstream' : ('frobnicator2',),
},
}


ok, so schema is a dictionary of different components, defining what
class they are and what they're connected to.
Yeps.

Note that it could as well be a list of tuple or anything like this, ie:
schema = [
('turbine1', 'Turbine', ('frobnicator2',), ()),
('frobnicator2', 'Frobnicator', (), ('frobnicator2',),
]

I choose a dict for readability.

Also, I gave the example using Python code as 'config' format, but any
structured enough text format could do, ie JSON, XML, or even ini-like:

# schema.ini
objects = turbine1, frobnicator2

[turbine1]
class=Turbine
upstream=frobnicator2
downstream=

[frobnicator2]
class=Frobnicator
upstream=
downstream=turbine
Now you just read the file with the standard config parser and build
your chain from it... (implementation left as an exercice...)

>>def get_class_by_name(name):
return globals()[name]


what does this function do exactly?
Q&D way to retrieve the class object (Python's classes are themselves
objects) known by it's name (as a string).

globals() returns the module's namespace as a dict object with
'name':object pairs. This code assume that the name is available in the
current module's namespace, but could be improved to handle needed
imports etc.
>>def chain_from_schema(schema):
objects = {} # so objects is our list of objects ?
for name, desc in schema:
# can you step through a dictionary like this?

Nope, sorry, it's a mistake I do over and over. It's of course:;
for name, desc in schema.items():

(note that you can iterate over a dict's keys with 'for k in thedict:' )
> klass = get_class_by_name(desc['class'])
# does this create an object called klass?

Nope, it binds the class object (retrieved by get_class_by_name()) to
the local name 'klass' ('class' is a reserved name).
> objects[name] = klass()

sorry for being dim..
Where ?

Jul 20 '06 #23

P: n/a
Hi
Also, I gave the example using Python code as 'config' format, but any
structured enough text format could do, ie JSON, XML, or even ini-like:

# schema.ini
objects = turbine1, frobnicator2

[turbine1]
class=Turbine
upstream=frobnicator2
downstream=
yes, I like the idea of using .ini type file format or XML, very much.
There are parser available which will automatically building python
objects from this, won't they (like configparser)? I'll have to get
reading over the weekend...
>def get_class_by_name(name):
return globals()[name]

Q&D way to retrieve the class object (Python's classes are themselves
objects) known by it's name (as a string).
ok, so it actually returns the class object itself.
One thing that confuses me is that objects have a name (self.name) but
object instances also have a name (e.g. myspecialturbine = turbine(...)
---- how do I discover the name 'myspecialturbine' ?). And object
instances have a class name too ('turbine'). Aaargh, too many names!
what if just want to know what the name of the instance is (in this
case 'myspecialturbine'?)

Right. I'll have a go at pulling all this together over the weekend
hopefully. Hurrah! Thanks for all the help, to everyone.
Dave

Jul 21 '06 #24

P: n/a
da*******@f2s.com wrote:
Hi

(snip)
>
>>>>def get_class_by_name(name):
return globals()[name]
Q&D way to retrieve the class object (Python's classes are themselves
objects) known by it's name (as a string).


ok, so it actually returns the class object itself.
One thing that confuses me is that objects have a name (self.name)
They dont - unless you give them one:
>>class Foo(object): pass
....
>>Foo.name
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: type object 'Foo' has no attribute 'name'
>>f = Foo()
f.name
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'Foo' object has no attribute 'name'
>>>
classes, functions and modules have a __name__ attribute, but that's
something else...
but
object instances also have a name (e.g. myspecialturbine = turbine(...)
Actually, this is the other way round: names refers ('are bound to')
objects. Think of namespaces (the global or local one...) as dicts
holding name:ref-to-object pairs (that's mostly what they are FWIW).
Different names can refer to the same object. The object itself doesn't
know anything about this.
---- how do I discover the name 'myspecialturbine' ?).
From within the object refered by this name ? Short answer : you can't.
And object
instances have a class name too ('turbine').
Nope, they have a class, which itself as a __name__ attribute, which is
the name that was used when "creating" the class object (ie: usually
when the 'class' statement is eval'd at module load time).
Aaargh, too many names!
what if just want to know what the name of the instance is (in this
case 'myspecialturbine'?)
you just named it so yourself, ie:
myspecialturbine = SpecialTurbine()

Else, no way. You can of course give a name when instanciating the object:

class Named(object):
def __init__(self, name):
self.name = name

n1 = Named('n1')
print n1.name
=n1

But this doesn't mean there's any correspondance between this name and a
name in the current (or any other) namespace:

toto = n1
n1 = "lalala"
print toto.name
=n1

locals()[toto.name] is toto
=False
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 21 '06 #25

P: n/a
Dave,

Sometimes generating classes from .ini or XML files is not the best
way. You are just translating one language into another and are making
bigger headaches for your self. It is certainly cool and bragable to
say that "my classes get generated on the fly from XML" but Python is
terse and reasonable enough to just write it in Python. In other words
instead of saying <turbine<power>2MW</power></turbinejust write
some Python code that instantiates a turbine with a 2MW power based on
your class. Then you can evaluate Python code in Python and you even
got your on-the-fly generation.
As a general rule, I would say to think 3 times before touching XML in
Python unless you are absolutely forced to. Config .ini files can be
more acceptable but Python is still best. Why write
;;My turbine class
[turbine]
power=2MW
speed=800rpm
....
when you can just say:
#my turbine class
t=Turbine( power="2MW", \
speed="800rpm", \
...
First case is a little shorter but then you have to use a parser for it
while in the second case you just execute the file, and besides, you
can edit it with any Python editor.

Hope this helps,
Nick V.
da*******@f2s.com wrote:
Hi
Also, I gave the example using Python code as 'config' format, but any
structured enough text format could do, ie JSON, XML, or even ini-like:

# schema.ini
objects = turbine1, frobnicator2

[turbine1]
class=Turbine
upstream=frobnicator2
downstream=

yes, I like the idea of using .ini type file format or XML, very much.
There are parser available which will automatically building python
objects from this, won't they (like configparser)? I'll have to get
reading over the weekend...
>>def get_class_by_name(name):
> return globals()[name]
>
Q&D way to retrieve the class object (Python's classes are themselves
objects) known by it's name (as a string).

ok, so it actually returns the class object itself.
One thing that confuses me is that objects have a name (self.name) but
object instances also have a name (e.g. myspecialturbine = turbine(...)
---- how do I discover the name 'myspecialturbine' ?). And object
instances have a class name too ('turbine'). Aaargh, too many names!
what if just want to know what the name of the instance is (in this
case 'myspecialturbine'?)

Right. I'll have a go at pulling all this together over the weekend
hopefully. Hurrah! Thanks for all the help, to everyone.
Dave
Jul 22 '06 #26

P: n/a

da*******@f2s.com wrote:
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 have done similar things in the past. One useful trick is to define
a special class for connections, create a single instance of this
class, and make all your connections as attributes of this instance.
For example:

world = Simulation()

world.supply = Supply()
world.compressor = Compressor(downstream=world.cumbustor,
upstream=world.supply)
world.cumbuster = Combuster(downstream=world.turbine,
upstream=world.compressor)

Because Python lets you control attribute access to your simulation
world object, it is relatively easy to make proxy objects for
attributes which don't yet exist via __getattr__, and then to insert
the real object into the proxy via __setattr__.

Alternatively, the script (using the same syntax as shown above!) can
simply collect all the connection information when it is run, then make
a "real" structure later. This works best if your simulation objects
(Supply, Compressor, Cumbuster) allow setting of the connection
attributes after instantiation.

Regards,
Pat

Jul 23 '06 #27

P: n/a
Nick Vatamaniuc wrote:
Dave,

Sometimes generating classes from .ini or XML files is not the best
way. You are just translating one language into another and are making
bigger headaches for your self. It is certainly cool and bragable to
say that "my classes get generated on the fly from XML" but Python is
terse and reasonable enough to just write it in Python. In other words
instead of saying <turbine<power>2MW</power></turbinejust write
some Python code that instantiates a turbine with a 2MW power based on
your class. Then you can evaluate Python code in Python and you even
got your on-the-fly generation.
As a general rule, I would say to think 3 times before touching XML in
Python unless you are absolutely forced to. Config .ini files can be
more acceptable but Python is still best. Why write
;;My turbine class
[turbine]
power=2MW
speed=800rpm
...
when you can just say:
#my turbine class
t=Turbine( power="2MW", \
speed="800rpm", \
...
First case is a little shorter but then you have to use a parser for it
There's one builtin.
while in the second case you just execute the file, and besides, you
can edit it with any Python editor.
This is certainly nice when the users are able to write python code, but
that's not always the case. Also, it can be dangerous to directly
execute user's python code...
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 24 '06 #28

P: n/a
First case is a little shorter but then you have to use a parser for it
>
There's one builtin.
do you mean 'configparser'? I'm just trying to figure out how this
works. Does it generate objects from the config file automatically?

Dave

Jul 24 '06 #29

P: n/a
da*******@f2s.com a écrit :
>>>First case is a little shorter but then you have to use a parser for it

There's one builtin.


do you mean 'configparser'?
Yes.
I'm just trying to figure out how this
works.
One nice thing with Python is the interactive python shell. It makes
exploring a package a breeze.
Does it generate objects from the config file automatically?
It generates a representation of the config file as a Python object
composed of sections and options. The documentation should get you started.

Jul 24 '06 #30

P: n/a
do you mean 'configparser'?

Yes.
Does it generate objects from the config file automatically?

It generates a representation of the config file as a Python object
composed of sections and options. The documentation should get you started.
Hiya, you might be interested in this alternative config parsing
program:
http://www.voidspace.org.uk/python/configobj.html

seems to offer a bit more than configparser

Dave

Jul 26 '06 #31

P: n/a
Suppose I have inherited the structure

PackageFolder/
__init__.py
mod1.py
SubPackageFolder/
__init__.py
mod2.py
mod3.py

When mod1 is run as a script,
I desire to import either mod2 or mod3 but not both
conditional on an option detected by the 'main()' function
in mod1.

Whichever is imported will be imported as, say, 'use_mod',
and code in mod1 will refer to use_mod.

Problem:
classes in mod1 that refer to 'use_mod' of course
raise a NameError, since the import does not take
place until 'main()' is run.

So, what is the right way to implement my desire?

Thanks,
Alan Isaac
Jul 26 '06 #32

P: n/a
da*******@f2s.com wrote:
>>>do you mean 'configparser'?

Yes.

>>>Does it generate objects from the config file automatically?

It generates a representation of the config file as a Python object
composed of sections and options. The documentation should get you started.


Hiya, you might be interested in this alternative config parsing
program:
http://www.voidspace.org.uk/python/configobj.html
Yes, I know it. But I don't like it. Either a simple ini file do the
trick, or I need a full blown app-specific DSL - which can be as simple
as a Python file with dicts, lists, etc !-)

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 27 '06 #33

P: n/a
Hiya, you might be interested in this alternative config parsing
program:
http://www.voidspace.org.uk/python/configobj.html

Yes, I know it. But I don't like it. Either a simple ini file do the
trick, or I need a full blown app-specific DSL - which can be as simple
as a Python file with dicts, lists, etc !-)

What do you mean? I don't really understand. I had a blast with
configobj and seems to be ok - quite straightfoward for the type of ini
file I'm using. configparser prob the same... it's kind of 'much over
muchness' as they say

Dave

Jul 27 '06 #34

P: n/a
da*******@f2s.com a écrit :
>>>Hiya, you might be interested in this alternative config parsing
program:
http://www.voidspace.org.uk/python/configobj.html

Yes, I know it. But I don't like it. Either a simple ini file do the
trick, or I need a full blown app-specific DSL - which can be as simple
as a Python file with dicts, lists, etc !-)



What do you mean? I don't really understand.
It's not a criticism of configobj - which is a quite nice package -,
it's just a matter of personal tastes (I don't like configobj's
[[[some-nested-sub-sub-section]]] syntax) and specific needs.

Most of the time, I don't need nothing more than a plain ini file - and
in this case, I prefer to use configparser because it's in the standard
lib (so I avoid a dependency on a 3rd part package).

When an ini file won't do, it's usually because what the app need is
really complex and specific enough to justify a "domain specific language".

And sometimes, this DSL can be expressed with Python's syntax, like for
example:

schema = {'turbine1': {'class': 'Turbine',
'upstream' : ('frobnicator2',),
'downstream' : () # nothing,
},
'frobnicator2' : {'class' : 'Frobnicator',
'upstream' : (),
'downstream' : ('frobnicator2',),
},
}

FWIW, the package's end user is not even supposed to know this is in
fact Python code !-)

FWIW, JSON can be a good candidate for this kind of stuff too.
Jul 28 '06 #35

This discussion thread is closed

Replies have been disabled for this discussion.