DRY question.

This may not make sense to anyone here, it’s late, and I’m really just using this as a sounding board for myself…

I spent some time reading the thread “problem with mass controls” which is similar to my own question. In my situation, trying

to follow “DRY” I have 6 panels, 12 box sizers, 18 static box sizers, 18 buttsons, 6 methods for 6 of the buttons, setting 6 sizers

and maybe even some stuff I forgot. I’m not finding any examples on setattr that will let me set attributes for all these widgets.

Here is new question on the same subject. The amount of dictionary keys, and multiple values probably isn’t assounding.

‘Panels’:[‘Container1P’, ‘Container2P’ …], ‘NextKey’:[‘val1’, ‘val2’] etc etc… and I think 2 for loops, and quite a bit of thinking

(atleast for me to wrap my mind around it all.)

When does the "need’ to write code in contortionist ways utilizing the “Don’t Repeat Yourself” priciple get outwayed by simple

cut / paste?

I think that the dictionairy keys/values may STILL be the way to go, because repeating 50+ lines of code per “container config”

multiplied by 6 would be work writing 1 time, and using a dictionairy to define it, and I even think it’s scalable… Maybe.

change the range, and add new values to the respective keys.

Say Panels for example… I’m not sure how it all is constructed, but from what I read, and what you guys have said to me already

I think it can be done. Panels for example:

The dictionary’s first key is for the wxPanels reference. as in “abc = wx.Panel(self, -1)”, “def = wx.Panel(self, -1)”, “ghi = wx.Panel(self, -1)”

etc. I think i’d have to throw in some box sizers though… but i think it’s doable…

···

----- Original Message -----

From:
Steve Freedenburg

To: wxpython-users@lists.wxwidgets.org

Sent: Monday, 21 July, 2008 00:24

Subject: Re: [wxpython-users] DRY question.

Cody

I’ll research the setattr construction more. I knew my way was wrong, it didn’t work when I tried it, but didn’t know

what to google to find out.

Thanks for the help

Steve

----- Original Message -----

From:
Cody Precord

To: wxpython-users@lists.wxwidgets.org

Sent: Sunday, 20 July, 2008 23:28

Subject: Re: [wxpython-users] DRY question.

Hello,

On Jul 20, 2008, at 10:10 PM, Steve Freedenburg wrote:

  self.Container"%i"P = wx.Panel(self, -1)
  self.Container%iSBS = wx.StaticBoxSizer(wx.StaticBox(self.Container%iP, -1, 'Container %i:'%i), wx.VERTICAL

so on and so forth…

No, this is incorrect syntax. Format statements only work with strings. If you want to do something like this you can do it in the following manner.

for i in range(1, 7):

setattr(self, "Container%iP" % i, wx.Panel(self, -1))

Cody



wxpython-users mailing list

wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users



wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

BINGO!

    ContListOfDicts = [{'Panel':'self.Cont1Pnl','SBS':'self.Cont1SBS','SBSLabel':'Container 1','Border':'self.Cont1Brdr'},\
                       {'Panel':'self.Cont2Pnl','SBS':'self.Cont2SBS','SBSLabel':'Container 2','Border':'self.Cont2Brdr'},\
                       {'Panel':'self.Cont3Pnl','SBS':'self.Cont3SBS','SBSLabel':'Container 3','Border':'self.Cont3Brdr'},\
                       {'Panel':'self.Cont4Pnl','SBS':'self.Cont4SBS','SBSLabel':'Container 4','Border':'self.Cont4Brdr'},\
                       {'Panel':'self.Cont5Pnl','SBS':'self.Cont5SBS','SBSLabel':'Container 5','Border':'self.Cont5Brdr'},\
                       {'Panel':'self.Cont6Pnl','SBS':'self.Cont6SBS','SBSLabel':'Container 6','Border':'self.Cont6Brdr'}]

    for Item in ContListOfDicts:
        Item['Panel'] = wx.Panel(self, -1)
        Item['SBS'] = wx.StaticBoxSizer(wx.StaticBox(Item['Panel'], -1, Item['SBSLabel']), wx.VERTICAL)
        Item['Border'] = wx.BoxSizer()
        Item['Border'].Add(Item['SBS'], 1, wx.EXPAND | wx.ALL, 2)
        Item['Panel'].SetSizer(Item['Border'])
        self.CDBS.Add(Item['Panel'], 0, wx.EXPAND)
        self.Fit()

This was just a test, but ultimately, the dictionairies are going to be alot larger for the host of other widgets that

need to be placed, and what not… This is what I was kinda’ asking, it almost seems that “Don’t Repeat Yourself”

really means you have to go out and invent new ways to code in order to not type the same thing more than

once. There may be 50+ ‘keys’ : ‘values’ per dictionary, and then having to keep it all sorted out in the code too.

The upshot is I can add one widget at a time, and one key at a time to make sure it’s all going to work.

In this case, i needed the panels, box sizers, and static box sizers so I could see it on the frame.

Well then again… someone is going to say there is a way to refine the list of dictionaries so it’s not as repetitive.

hmmm… maybe I’ll do it…

···

----- Original Message -----

From:
Steve Freedenburg

To: wxpython-users@lists.wxwidgets.org

Sent: Monday, 21 July, 2008 01:18

Subject: Re: [wxpython-users] DRY question.

This may not make sense to anyone here, it’s late, and I’m really just using this as a sounding board for myself…

I spent some time reading the thread “problem with mass controls” which is similar to my own question. In my situation, trying

to follow “DRY” I have 6 panels, 12 box sizers, 18 static box sizers, 18 buttsons, 6 methods for 6 of the buttons, setting 6 sizers

and maybe even some stuff I forgot. I’m not finding any examples on setattr that will let me set attributes for all these widgets.

Here is new question on the same subject. The amount of dictionary keys, and multiple values probably isn’t assounding.

‘Panels’:[‘Container1P’, ‘Container2P’ …], ‘NextKey’:[‘val1’, ‘val2’] etc etc… and I think 2 for loops, and quite a bit of thinking

(atleast for me to wrap my mind around it all.)

When does the "need’ to write code in contortionist ways utilizing the “Don’t Repeat Yourself” priciple get outwayed by simple

cut / paste?

I think that the dictionairy keys/values may STILL be the way to go, because repeating 50+ lines of code per “container config”

multiplied by 6 would be work writing 1 time, and using a dictionairy to define it, and I even think it’s scalable… Maybe.

change the range, and add new values to the respective keys.

Say Panels for example… I’m not sure how it all is constructed, but from what I read, and what you guys have said to me already

I think it can be done. Panels for example:

The dictionary’s first key is for the wxPanels reference. as in “abc = wx.Panel(self, -1)”, “def = wx.Panel(self, -1)”, “ghi = wx.Panel(self, -1)”

etc. I think i’d have to throw in some box sizers though… but i think it’s doable…

----- Original Message -----

From:
Steve Freedenburg

To: wxpython-users@lists.wxwidgets.org

Sent: Monday, 21 July, 2008 00:24

Subject: Re: [wxpython-users] DRY question.

Cody

I'll research the setattr construction more.  I knew my way was wrong, it didn't work when I tried it, but didn't know

what to google to find out.

Thanks for the help

Steve

----- Original Message -----

From:
Cody Precord

To: wxpython-users@lists.wxwidgets.org

Sent: Sunday, 20 July, 2008 23:28

Subject: Re: [wxpython-users] DRY question.

Hello,

On Jul 20, 2008, at 10:10 PM, Steve Freedenburg wrote:

    self.Container"%i"P = wx.Panel(self, -1)
    self.Container%iSBS = wx.StaticBoxSizer(wx.StaticBox(self.Container%iP, -1, 'Container %i:'%i), wx.VERTICAL

so on and so forth…

  No, this is incorrect syntax. Format statements only work with strings. If you want to do something like this you can do it in the following manner.

for i in range(1, 7):

  setattr(self, "Container%iP" % i, wx.Panel(self, -1))

Cody



  wxpython-users mailing list

wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users



wxpython-users mailing list

wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users



wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

You know it’s late, I’m replying to my own e-mails… I think I got the next answer to my own question,

and wanted to post it so you all don’t solve it for me. All these things I’m using are just examples you

all have given me before stacked together.

So this is the “right” way to do things… To the progression was first to code out, each widget and definition

6 times. As Tim said "wasteful’. The next step in the progression was to make a list of 6 dictionairies, and

code once. The last step in the progression is to do a range from 1 to X, with one dictionairy with all the

various keys, and one set of code. Like so:

for i in range(1,7):
ContDict = {‘Panel’:‘self.Cont%iPnl’%i,‘SBS’:‘self.Cont%iSBS’%i,‘SBSLabel’:‘Container %i’%i,‘Border’:‘self.Cont%iBrdr’%i}
ContDict[‘Panel’] = wx.Panel(self, -1)
ContDict[‘SBS’] = wx.StaticBoxSizer(wx.StaticBox(ContDict[‘Panel’], -1, ContDict[‘SBSLabel’]), wx.VERTICAL)
ContDict[‘Border’] = wx.BoxSizer()
ContDict[‘Border’].Add(ContDict[‘SBS’], 1, wx.EXPAND | wx.ALL, 2)
ContDict[‘Panel’].SetSizer(ContDict[‘Border’])
self.CDBS.Add(ContDict[‘Panel’], 0, wx.EXPAND)
self.Fit()

I think I’m getting it! There is code above and below this that establises other things that aren’t repeated, this just adds the

things that are. It’s still missing alot, but the gist is there.

Thanks to Time specifically for putting things in a way that made me feel ashamed of my code, and also showed me the

way to enlightenment. Unless of course there is something I can do to refine this more.

Steve

···

----- Original Message -----

From:
Steve Freedenburg

To: wxpython-users@lists.wxwidgets.org

Sent: Monday, 21 July, 2008 01:18

Subject: Re: [wxpython-users] DRY question.

This may not make sense to anyone here, it’s late, and I’m really just using this as a sounding board for myself…

I spent some time reading the thread “problem with mass controls” which is similar to my own question. In my situation, trying

to follow “DRY” I have 6 panels, 12 box sizers, 18 static box sizers, 18 buttsons, 6 methods for 6 of the buttons, setting 6 sizers

and maybe even some stuff I forgot. I’m not finding any examples on setattr that will let me set attributes for all these widgets.

Here is new question on the same subject. The amount of dictionary keys, and multiple values probably isn’t assounding.

‘Panels’:[‘Container1P’, ‘Container2P’ …], ‘NextKey’:[‘val1’, ‘val2’] etc etc… and I think 2 for loops, and quite a bit of thinking

(atleast for me to wrap my mind around it all.)

When does the "need’ to write code in contortionist ways utilizing the “Don’t Repeat Yourself” priciple get outwayed by simple

cut / paste?

I think that the dictionairy keys/values may STILL be the way to go, because repeating 50+ lines of code per “container config”

multiplied by 6 would be work writing 1 time, and using a dictionairy to define it, and I even think it’s scalable… Maybe.

change the range, and add new values to the respective keys.

Say Panels for example… I’m not sure how it all is constructed, but from what I read, and what you guys have said to me already

I think it can be done. Panels for example:

The dictionary’s first key is for the wxPanels reference. as in “abc = wx.Panel(self, -1)”, “def = wx.Panel(self, -1)”, “ghi = wx.Panel(self, -1)”

etc. I think i’d have to throw in some box sizers though… but i think it’s doable…

----- Original Message -----

From:
Steve Freedenburg

To: wxpython-users@lists.wxwidgets.org

Sent: Monday, 21 July, 2008 00:24

Subject: Re: [wxpython-users] DRY question.

Cody

I'll research the setattr construction more.  I knew my way was wrong, it didn't work when I tried it, but didn't know

what to google to find out.

Thanks for the help

Steve

----- Original Message -----

From:
Cody Precord

To: wxpython-users@lists.wxwidgets.org

Sent: Sunday, 20 July, 2008 23:28

Subject: Re: [wxpython-users] DRY question.

Hello,

On Jul 20, 2008, at 10:10 PM, Steve Freedenburg wrote:

    self.Container"%i"P = wx.Panel(self, -1)
    self.Container%iSBS = wx.StaticBoxSizer(wx.StaticBox(self.Container%iP, -1, 'Container %i:'%i), wx.VERTICAL

so on and so forth…

  No, this is incorrect syntax. Format statements only work with strings. If you want to do something like this you can do it in the following manner.

for i in range(1, 7):

  setattr(self, "Container%iP" % i, wx.Panel(self, -1))

Cody



  wxpython-users mailing list

wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users



wxpython-users mailing list

wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users



wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

[snipped]

When does the "need’ to write code in contortionist ways utilizing the “Don’t Repeat Yourself” priciple get outwayed by simple

cut / paste?

I’m an appalling pragmatist when it comes to writing code. If you can make it work and make it work quickly using cut-n-paste. Do it. The satisfaction of having something that works is quite often the boost one needs to keep a project going.

All that said, All that cut-n-pasted code is going to be a nightmare to read, to debug, and to extend. So once you have something that works, the next step is to go back and see the parts that can be refactored, and make it conform to some of the better coding practices that you’ve seen demonstrated here on the list.

I’m still incredibly grateful to a few of the people on this list who said “That’s horribly brittle code, try this…” I went back and refactored using those suggestions and I’m much happier for it.

My rule of thumb is that if I see similar code of three lines or more I look for a way to turn it into a function or a method.

···

On Sun, Jul 20, 2008 at 10:18 PM, Steve Freedenburg stevefreedenburg@charter.net wrote:


Stand Fast,
tjg. [Timothy Grant]

I'm glad Josiah pointed out the method of making a base panel class,
and subclassing it.

I find this methods works for me and produces clean, easier to
troubleshoot code.

As for xrange being faster than range: I understand 'range' creates
every object and returns the whole shebang as a list. xrange returns
an iterator which is smaller and works just the same way.

···

--
Josh English
Joshua.R.English@gmail.com
http://joshenglish.livejournal.com

Steve Freedenburg wrote:

So this is the "right" way to do things... To the progression was first to code out, each widget and definition
6 times. As Tim said "wasteful'. The next step in the progression was to make a list of 6 dictionairies, and
code once. The last step in the progression is to do a range from 1 to X, with one dictionairy with all the
various keys, and one set of code. Like so:
for i in range(1,7):
            ContDict = {'Panel':'self.Cont%iPnl'%i,'SBS':'self.Cont%iSBS'%i,'SBSLabel':'Container %i'%i,'Border':'self.Cont%iBrdr'%i}
            ContDict['Panel'] = wx.Panel(self, -1)
            ContDict['SBS'] = wx.StaticBoxSizer(wx.StaticBox(ContDict['Panel'], -1, ContDict['SBSLabel']), wx.VERTICAL)
            ContDict['Border'] = wx.BoxSizer()
            ContDict['Border'].Add(ContDict['SBS'], 1, wx.EXPAND | wx.ALL, 2)
            ContDict['Panel'].SetSizer(ContDict['Border'])
            self.CDBS.Add(ContDict['Panel'], 0, wx.EXPAND)
            self.Fit()
I think I'm getting it! There is code above and below this that establises other things that aren't repeated, this just adds the
things that are. It's still missing alot, but the gist is there.

Cody pointed out the problem with your first line, but since you immediately overwrite all of those elements anyway, it doesn't cause a bug. You should probably replace that first line with:

        ContDict = {}

The one step that I DON'T see here is storing this somewhere. This creates a ContDict dictionary, initializes it, then throws it away and creates another. You need to add this dictionary to a list somewhere, for example:
    self.Containers = # create empty list
    for i in range(1,7):
        ContDict = {}
        ...
        self.Containers.append( ContDict )

···

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

Steve Freedenburg wrote:

Hey Tim... so hold on a sec.... I need to start out with an empty dict? Ok so what I'm doing is
created a dict full of keys and values, and then rewriting all those values?

Yes, that is correct. You don't actually need to start out with an empty dict; you can start out with a partially populated dict, but in this particular case, you were immediately overwriting all the values you set.

As I was typing this, I began to see what you were thinking. I'll see if I can clear it up as I go along.

I thought i was creating
a dictionariy and the values of the dictionairy were populating the widgets various attributes and
names?

A dictionary is just a lookup table. It has keys, and it has values. The keys are inside the brackets. Every key has exactly one value. Let's take a close look at what you wrote, and what it actually did. Maybe it will be clearer.

            ContDict = {'Panel':'self.Cont%iPnl'%i,'SBS':'self.Cont%iSBS'%i,'SBSLabel':'Container %i'%i,'Border':'self.Cont%iBrdr'%i}

OK, here you have created a dictionary with 4 key/value pairs. All 4 keys are strings, and all 4 values are strings. Assuming this is the first time through the loop, the dictionary looks like this:

    Key Value

···

----------------------------
    "Panel" "self.Cont1Pnl"
    "SBS" "self.Cont1SBS"
    "SBSLabel" "Container1"
    "Border" "self.Cont1Brdr"

The values in this case are just character strings. They do not actually represent any variables. The string "self.Cont1Pnl" is just a string. It does not refer to the "self" object. Next, you wrote:

            ContDict['Panel'] = wx.Panel(self, -1)
            ContDict['SBS'] = wx.StaticBoxSizer(wx.StaticBox(ContDict['Panel'], -1, ContDict['SBSLabel']), wx.VERTICAL)

This first line creates a panel, and stores it in the dict. This REPLACES the character string "self.Cont1Pnl" that is currently stored there, with a panel object. The second line creates a StaticBoxSizer, and stores it in the dict, replacing the string "self.Cont1SBS. So, the dictionary now looks like this:

    Key Value
    ----------------------------
    "Panel" wx.Panel object
    "SBS" wx.StaticBoxSizer object
    "SBSLabel" "Container1"
    "Border" "self.Cont1Brdr"

Now that I've written this, I can see that YOU were thinking that this would kind of a macro facility, somehow being the same as this:
        self.Cont1Pnl = wx.Panel( self, -1 )

That's not the case. The panel is stored in the dictionary. (OK, a reference to the panel is stored in the dictionary.)

Now I'm a bit confused. What does putting the dictionary in a list do?

Because you thought this was creating names member variables, you thought you had a way to refer to these things later. That's not the way it works. You have stored the panel and the static box sizer in the dictionary. To access the first panel later on, you need to be able to find that dictionary. The only way to do that is to save it in some other container. I suggested a list called Containers. In that case, you would refer to the first panel by this:
    self.Containers[0]['Panel']

So, why is this better than self.Cont1Pnl and self.Cont1SBS and self.Cont1Brdr? Because it only creates ONE name in the "self" object, instead of 24 names, Because it allows you to extend this to 7, 8, 9, or even 100 strings later on simply by adding more dictionaries to the list. You don't have to repeat the same code 100 times.

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

Hey Bruce,
Thanks! As soon as I get some dinner and a shower, I'll open
up the attachment. It's really only been this week that I've
really started to absorb some of the critical things about this
OOP stuff, and refactoriing, and DRY, and the list goes
on.
Steve

···

----- Original Message ----- From: "FT" <chester_lab@fltg.net>
To: <wxpython-users@lists.wxwidgets.org>
Sent: Monday, 21 July, 2008 16:59
Subject: Re: Re: Re: [wxpython-users] DRY question.

Tim Roberts Wrote:
Steve Freedenburg wrote:

Hey Tim... so hold on a sec.... I need to start out with an empty
dict? Ok so what I'm doing is
created a dict full of keys and values, and then rewriting all those
values?

Yes, that is correct. You don't actually need to start out with an
empty dict; you can start out with a partially populated dict, but in
this particular case, you were immediately overwriting all the values
you set.
---snip---
So, why is this better than self.Cont1Pnl and self.Cont1SBS and
self.Cont1Brdr? Because it only creates ONE name in the "self" object,
instead of 24 names, Because it allows you to extend this to 7, 8, 9,
or even 100 strings later on simply by adding more dictionaries to the
list. You don't have to repeat the same code 100 times.

Hi!

   I attached the program I was asking about the spinctrl and I think I
have resolved that issue with just one more event directive, but also
attached and in the file is the code for using a dictionary for both making
menu's and binding methods. You can use this as a possible procedure in
making your dictionary list and so on. I use several key values which are
actually abreviations of the actual menu parms, such as Hot Key and Status
bar help, HK and KH respectively.

   In your program I guess you can come up with your own keys, or as I do
inside the making of the menu items I collect ID's and use them as actual
keys. So when an event call is made the ID is looked up with all the values
of the menu made inside that dictionary, under it's own ID.

   So, read it and see if you like my approach.

       Bruce

--------------------------------------------------------------------------------

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users