using names before they're defined

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • davehowey@f2s.com

    #1

    using names before they're defined

    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(down stream=combusto r, upstream=supply )
    combuster = combuster(downs tream=turbine, upstream=compre ssor)
    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

  • Iain King

    #2
    Re: using names before they're defined


    daveho...@f2s.c om 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(down stream=combusto r, upstream=supply )
    combuster = combuster(downs tream=turbine, upstream=compre ssor)
    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.setS treams(down=com buster, up=supply)
    combuster.setSt reams(down=turb ine, 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(sel f, c):
    self.upstream = c
    if c.downstream != self:
    c.setDownstream (self)

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

    class Supply(Componen t):
    pass

    etc.

    Iain

    Comment

    • Steve Holden

      #3
      Re: using names before they're defined

      davehowey@f2s.c om 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(down stream=combusto r, upstream=supply )
      combuster = combuster(downs tream=turbine, upstream=compre ssor)
      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

      Comment

      • Larry Bates

        #4
        Re: using names before they're defined

        What about something like:

        supply = supply()
        compressor = compressor(supp ly)
        combuster = combuster(compr essor)
        compressor.appe nd(combuster)
        turbine = turbine(combust er)
        combuster.appen d(turbine)


        -Larry Bates


        davehowey@f2s.c om 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(down stream=combusto r, upstream=supply )
        combuster = combuster(downs tream=turbine, upstream=compre ssor)
        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
        >

        Comment

        • Diez B. Roggisch

          #5
          Re: using names before they're defined

          davehowey@f2s.c om 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(down stream=combusto r, upstream=supply )
          combuster = combuster(downs tream=turbine, upstream=compre ssor)
          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(down stream='combust or', upstream='suppl y')
          combuster = combuster(downs tream='turbine' , upstream='compr essor')

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

          supply = supply()
          combustor = combustor()
          compressor = compressor()
          turbine = turbine()
          combuster.attac h(downstream=tu rbine' upstream=compre ssor)


          Diez

          Comment

          • davehowey@f2s.com

            #6
            Re: using names before they're defined

            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

            Comment

            • Bruno Desthuilliers

              #7
              Re: using names before they're defined

              davehowey@f2s.c om 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(down stream=combusto r, upstream=supply )
              combuster = combuster(downs tream=turbine, upstream=compre ssor)
              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.chai n(downstream=co mbustor, upstream=supply )
              combuster.chain (downstream=tur bine, upstream=compre ssor)

              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(objec t):
              def __init__(self, upstream):
              self.upstream = upstream
              if upstream is not None:
              upstream.downst ream = self

              class Supply(Chainabl e):
              #

              # etc

              then:

              supply = Supply()
              compressor = Compressor(upst ream=supply)
              combuster = Combuster(upstr eam=compressor)
              turbine = Turbine(upstrea m=combuster)


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


              class Chainable(objec t):
              def __init__(self, downstream=None ):
              self.downstream = downstream
              if downstream is not None:
              downstream.upst ream = self


              supply = Supply(
              downstream=Comp ressor(
              downstream=Comb uster(
              downstream=Turb ine()
              )
              )
              )

              or more simply:
              supply = Supply(Compress or(Combuster(Tu rbine())))


              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 'onurb@xiludom. gro'.split('@')])"

              Comment

              • Nick Vatamaniuc

                #8
                Re: using names before they're defined

                Your can of course initialize the components first:

                compr=Compresso r(...),
                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,up stream_obj) an _get_up(self).
                And then at the end of your class put up=property(_ge t_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(objec t):
                send(...)
                recv(...)
                up
                down
                print_data(...)
                ...

                Then do:
                class Turbine(Compone nt):
                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

                davehowey@f2s.c om 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(down stream=combusto r, upstream=supply )
                combuster = combuster(downs tream=turbine, upstream=compre ssor)
                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

                Comment

                • davehowey@f2s.com

                  #9
                  Re: using names before they're defined

                  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

                  Comment

                  • davehowey@f2s.com

                    #10
                    Re: using names before they're defined

                    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,up stream_obj) an _get_up(self).
                    And then at the end of your class put up=property(_ge t_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

                    Comment

                    • Rob Williscroft

                      #11
                      Re: using names before they're defined

                      Iain King wrote in news:1153323649 .171612.74510
                      @s13g2000cwa.go oglegroups.com in comp.lang.pytho n:
                      >
                      daveho...@f2s.c om wrote:
                      > [...] I need to reference (link) each object to the objects
                      >upstream and downstream of it, i.e.
                      >>
                      >supply = supply()
                      >compressor = compressor(down stream=combusto r, upstream=supply )
                      >combuster = combuster(downs tream=turbine, upstream=compre ssor)
                      >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(down stream=None, upstream=supply )

                      Rob.
                      --

                      Comment

                      • Bruno Desthuilliers

                        #12
                        Re: using names before they're defined

                        davehowey@f2s.c om 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,up stream_obj) an _get_up(self).
                        >And then at the end of your class put up=property(_ge t_up, _set_up).
                        >>You can still use the compr.up=... format.
                        >
                        >
                        sorry, I don't quite follow. what are properties?
                        >
                        Computed attributes. cf





                        Comment

                        • Paddy

                          #13
                          Re: using names before they're defined


                          davehowey@f2s.c om 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(down stream=combusto r, upstream=supply )
                          combuster = combuster(downs tream=turbine, upstream=compre ssor)
                          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,c ompType,name):
                          self.upstream = Port("U")
                          self.downstream = Port("D")
                          self.name = name
                          self.compType = compType
                          class Link:
                          def __init__(self, name, *connections):
                          self.connection s = connections
                          self.name = name

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

                          # Instantiate Links and link in ports of component intances
                          supply2comp = Link("supply2co mp", supply1.downstr eam,
                          compressor1.ups tream)
                          # ...

                          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.

                          Comment

                          • jordan.nick@gmail.com

                            #14
                            Re: using names before they're defined


                            Steve Holden wrote:
                            davehowey@f2s.c om 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(down stream=combusto r, upstream=supply )
                            combuster = combuster(downs tream=turbine, upstream=compre ssor)
                            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

                            Comment

                            • Paul McGuire

                              #15
                              Re: using names before they're defined

                              davehowey@f2s.c om 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

                              Comment

                              Working...