Need fresh eyes to see error

I have a wx.Notebook that adds panels to each of 5 tabs. Python does not
find a panel parameter in __init__().

   The traceback:

   File "./openEDMS.py", line 347, in __init__
     self.panel1 = SiteOLV(self, site_name, site_type, source, lat, lon,
NameError: name 'site_name' is not defined

   The notebook:

class MainNB(wx.Notebook):
     def __init__(self, parent, id):
         wx.Notebook.__init__(self, parent, id, style=wx.NB_TOP)

         self.panel1 = SiteOLV(self, site_name, site_type, source, lat, lon,
                               stream, basin, comment)
   ...

and the SiteOLV panel:

class SiteOLV(wx.Panel):
     def __init__(self, site_name, site_type, source, lat, lon, stream, basin, comment):
         wx.Panel.__init__(self, parent, id)

   I've looked at the wx.Notebook API and various examples and I don't see
what I've done incorrectly. Please show me what I've omitted or wrote
incorrectly.

Rich

Well, you never *define* site_name anywhere.

Ask yourself a question: What to you expect the value of
site_name to be in the line

  self.panel1 = ...

?

Same goes for site_type, source, lat, lon, stream, basin, comment.

Karsten

···

On Fri, May 04, 2018 at 12:44:53PM -0700, Rich Shepard wrote:

  The traceback:

  File "./openEDMS.py", line 347, in __init__
    self.panel1 = SiteOLV(self, site_name, site_type, source, lat, lon,
NameError: name 'site_name' is not defined

  The notebook:

class MainNB(wx.Notebook):
    def __init__(self, parent, id):
        wx.Notebook.__init__(self, parent, id, style=wx.NB_TOP)

        self.panel1 = SiteOLV(self, site_name, site_type, source, lat, lon,
                              stream, basin, comment)

--
GPG key ID E4071346 @ eu.pool.sks-keyservers.net
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346

Karsten,

   Oops! I forgot to put the panel init function in the message:

class SiteOLV(wx.Panel):
     def __init__(self, site_name, site_type, source, lat, lon, stream, basin, comment):
         wx.Panel.__init__(self, parent, id)

   That's where each variable is defined.

Rich

···

On Fri, 4 May 2018, Karsten Hilbert wrote:

Well, you never *define* site_name anywhere.

No, I did have it there and the module with the notebook imports that
module:

from sitePage import SiteOLV

or have I still missed something?

Rich

···

On Fri, 4 May 2018, Rich Shepard wrote:

Oops! I forgot to put the panel init function in the message:

class SiteOLV(wx.Panel):
   def __init__(self, site_name, site_type, source, lat, lon, stream, basin, comment):
       wx.Panel.__init__(self, parent, id)

> Well, you never *define* site_name anywhere.

Karsten,

  Oops! I forgot to put the panel init function in the message:

You did not, it was there.

class SiteOLV(wx.Panel):
    def __init__(self, site_name, site_type, source, lat, lon, stream, basin, comment):
        wx.Panel.__init__(self, parent, id)

  That's where each variable is defined.

No it is not.

Or else you would be able to answer the question I posted.

What _is_ the answer to my question ?

Once you have that answer ask yourself where in your code you
tell Python about that answer.

That is the reason for the exception.

Karsten

···

On Fri, May 04, 2018 at 12:58:43PM -0700, Rich Shepard wrote:
--

Karsten,

   The name or ID number of a sampling location in the sites database table.
If the database table is empty there is no instance or value for any of the
variables. That table is a SQLAlchemy class in models.py:

class Sites(Base):
     __tablename__ = 'locations'

     site_id = Column(Integer, Sequence('site_id_seq'), primary_key=True)
     site_name = Column(String(16), nullable=False)
     data_type = Column(String(12), nullable=False, CheckConstraint('Biogical', 'Chemical', 'Microbial', 'Physical', 'Multiple'))
     source = Column(String(64))
     lat = Column(String(9))
     lon = Column(String(9))
     stream = Column(String(32))
     basin = Column(String(32))
     comment = Column(String)

     def __repr__(self):
         return "<Locations(site_name='%s', site_description='%s', source='%s', lat='%s', lon='%s', comment='%s'>" % (
                                 self.site_name, self.site_desc, self.source, self.lat, self.lon, self.comment)

Rich

···

On Fri, 4 May 2018, Karsten Hilbert wrote:

Ask yourself a question: What to you expect the value of
site_name to be in the line
  self.panel1 = ...

OK, that says what site_name is *meant* to be, *conceptually*.

Where do you tell Python what site_name *actually*
stands for when you instantiate that panel ?

Karsten

···

On Fri, May 04, 2018 at 01:41:42PM -0700, Rich Shepard wrote:

> Ask yourself a question: What to you expect the value of
> site_name to be in the line
> self.panel1 = ...

Karsten,

  The name or ID number of a sampling location in the sites database table.
If the database table is empty there is no instance or value for any of the
variables. That table is a SQLAlchemy class in models.py:

class Sites(Base):
    __tablename__ = 'locations'

    site_name = Column(String(16), nullable=False)
    ....
    def __repr__(self):
        return "<Locations(site_name='%s', site_description='%s', source='%s', lat='%s', lon='%s', comment='%s'>" % (
                                self.site_name, self.site_desc, self.source, self.lat, self.lon, self.comment)

--

The scope of that "site_name" is restricted to __init__().
There's no magic for getting the value or definition of
site_name from anywhere else.

Karsten

···

On Fri, May 04, 2018 at 09:49:35PM +0200, Karsten Hilbert wrote:

> def __init__(self, parent, id):
> wx.Notebook.__init__(self, parent, id, style=wx.NB_TOP)
>
> self.panel1 = SiteOLV(self, site_name, site_type, source, lat, lon,
> stream, basin, comment)

Well, you never *define* site_name anywhere.

--

Karsten,

   Excellent question. This is my first SQLAlchemy application and I'm
stumbling along learning how to fit together all the pieces: the SA
controller with the wxPython views and the sqlite3 model. I've yet to find a
good example (other than a small one Mike Driscoll provided) and his comes
with a database having filled rows in the tables.

   When a new user of a SA application invokes it, the database is empty, but
they expect the UI to display so they can start adding data. Not (yet)
knowing how this works, I'm trying to have the UI display so I it's syntax
and logical error free, then I can test menu options and build the
application step-by-step.

   I intend to use data-factory to generate test data for each table, but
thought that could wait until the UI displayed.

   Given all this I'm open to all suggestions and recommendations.

Best regards,

Rich

···

On Fri, 4 May 2018, Karsten Hilbert wrote:

OK, that says what site_name is *meant* to be, *conceptually*.

Where do you tell Python what site_name *actually* stands for when you
instantiate that panel ?

The error is pretty self-explanatory, isn’t it? You are passing a variable called “site_name” here, but there is no variable called “site_name”.

···

On May 4, 2018, at 12:44 PM, Rich Shepard rshepard@appl-ecosys.com wrote:

class MainNB(wx.Notebook):
def init(self, parent, id):
wx.Notebook.init(self, parent, id, style=wx.NB_TOP)

   self.panel1 = SiteOLV(self, site_name, site_type, source, lat, lon,
                         stream, basin, comment)


Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Tim,

   Yes. As I wrote before, the variables come from rows in database tables.
The lack of a backend made no difference in the display of the UI when I
started development and used wx.grid.Grid as the data display wiedget.
Yesterday I replaced all grids with ObjectListViews and expected them to
display column titles and no rows as the grids did. That's why I didn't
recognize their dependence on existing data.

   My response to Karsten (and all list subscribers) explained that I'm
developing my first SQLAlchemy application and I've not before used OLVs so
I've no experience with how these affect development of the UI.

   Perhaps the SA mail list would be the more appropriate venue for learning
how to assemble all the pieces.

Regards,

Rich

···

On Fri, 4 May 2018, Tim Roberts wrote:

The error is pretty self-explanatory, isn't it? You are passing a variable
called "site_name" here, but there is no variable called "site_name".

Hi Rich,

···

On Sat, May 5, 2018 at 7:54 AM, Rich Shepard rshepard@appl-ecosys.com wrote:

The error is pretty self-explanatory, isn’t it? You are passing a variable

called “site_name” here, but there is no variable called “site_name”.
On Fri, 4 May 2018, Tim Roberts wrote:

Tim,

Yes. As I wrote before, the variables come from rows in database tables.

The lack of a backend made no difference in the display of the UI when I

started development and used wx.grid.Grid as the data display wiedget.

Yesterday I replaced all grids with ObjectListViews and expected them to

display column titles and no rows as the grids did. That’s why I didn’t

recognize their dependence on existing data.

My response to Karsten (and all list subscribers) explained that I’m

developing my first SQLAlchemy application and I’ve not before used OLVs so

I’ve no experience with how these affect development of the UI.

Perhaps the SA mail list would be the more appropriate venue for learning

how to assemble all the pieces.

Regards,

Rich

I think that the point Tim and Karsten were trying to make is that the problem here is not about wxPython, or about SQLAlchemy. It is a Python problem. Your code had

 self.panel1 = SiteOLV(self, site_name, site_type, source, lat, lon, stream, basin, comment)

which gave the exception of

NameError: name 'site_name' is not defined

That means that you use site_name in your call to SiteOLV(), and that site_name is not defined when that call is executed. The error does not come from SQLAlchemy or wxPython, it comes from the Python interpreter. It does not matter what you intend site_name to (eventually?) mean or what SiteOLV() does with site_name. It is a name error because there is not a variable named site_name at the time it is used. You will get the same exception with this:

~> python
Python X.XX …

a = site_name
Traceback (most recent call last):
File “”, line 1, in
NameError: name ‘site_name’ is not defined

Python gives exceptionally good exception messages. They tell you where Python was not able to understand your code or had a problem using it. They are written to help you find and fix the problem. If you are trying to write applications that are complicated enough to use SQLAlchemy and wxPython, you will have a much easier time if you learn how to interpret and respond to these messages.
You may also want to review python’s naming and scoping rules.

Hope that helps,

–Matt Newville

Matt, et al.:

   What set me in the wrong direction is being able to invoke the UI with the
wx.grid but not with the OLV. Late last evening I realized that with the
wx.grid the column header names were labels while the OLV needs data ... or
something I've yet to learn ... before loading.

Thanks all,

Rich

···

On Sat, 5 May 2018, Matt Newville wrote:

I think that the point Tim and Karsten were trying to make is that the
problem here is not about wxPython, or about SQLAlchemy. It is a Python
problem. Your code had

I think you need to more fully appreciate the difference
between values (constants or else the *content* of variables)
and variables (symbolic *names* for values).

Karsten

···

On Sat, May 05, 2018 at 12:31:24PM -0700, Rich Shepard wrote:

  What set me in the wrong direction is being able to invoke the UI with the
wx.grid but not with the OLV. Late last evening I realized that with the
wx.grid the column header names were labels while the OLV needs data ... or
something I've yet to learn ... before loading.

--

Hi Rich,

···

On Sat, May 5, 2018 at 2:31 PM, Rich Shepard rshepard@appl-ecosys.com wrote:

I think that the point Tim and Karsten were trying to make is that the

problem here is not about wxPython, or about SQLAlchemy. It is a Python

problem. Your code had
On Sat, 5 May 2018, Matt Newville wrote:

Matt, et al.:

What set me in the wrong direction is being able to invoke the UI with the

wx.grid but not with the OLV. Late last evening I realized that with the

wx.grid the column header names were labels while the OLV needs data … or

something I’ve yet to learn … before loading.

With all due respect and humility, I am not entirely sure that you actually understand the point that Karsten, or Tim, or I was trying to make. In a forum like this, it’s difficult to tell whether someone is an expert or a novice except from the questions and replies they give. Ignoring follow-up questions or suggestions, which you have done more than once, is usually not a good sign and makes people less eager to help you.

In your original question, and in all follow-up responses, you seem to assume that the problem is in some way related to how you are invoking routines from wxPython or from SQLAlchemy. It is not. The problem is simply, precisely, and only that you use a variable before it is defined. This is not in any way related to the APIs defined by wxPython or SQLAlchemy. We have tried to explain this a few different ways.

The very first response to your question was Karsten saying “well, you never define site_name anywhere.” That IS the answer. It is not at all clear from anything you have written since that you understand what NameError means. Instead, you keep responding (even here and now) with discussions about using different wxPython methods or how you initialize classes or how other objects are defined that are all completely irrelevant to the actual problem. The NameError does not come because “the OLV needs data”.

Once more, I recommend that you review the Python tutorials about scoping and naming variables and also read about how to read and deal with Exceptions.

–Matt