Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #50590 > unrolled thread

Ideal way to separate GUI and logic?

Started byfronagzen@gmail.com
First post2013-07-13 04:07 -0700
Last post2013-07-16 13:18 +1000
Articles 15 — 12 participants

Back to article view | Back to comp.lang.python


Contents

  Ideal way to separate GUI and logic? fronagzen@gmail.com - 2013-07-13 04:07 -0700
    Re: Ideal way to separate GUI and logic? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-13 11:43 +0000
    Re: Ideal way to separate GUI and logic? Roland Koebler <r.koebler@yahoo.de> - 2013-07-13 15:56 +0200
    Re: Ideal way to separate GUI and logic? Dave Cook <davecook@nowhere.net> - 2013-07-13 17:40 +0000
    Re: Ideal way to separate GUI and logic? Wayne Werner <wayne@waynewerner.com> - 2013-07-13 14:03 -0500
      Re: Ideal way to separate GUI and logic? fronagzen@gmail.com - 2013-07-14 17:24 -0700
      Re: Ideal way to separate GUI and logic? fronagzen@gmail.com - 2013-07-14 17:25 -0700
        Re: Ideal way to separate GUI and logic? Joel Goldstick <joel.goldstick@gmail.com> - 2013-07-14 21:02 -0400
          Re: Ideal way to separate GUI and logic? Roy Smith <roy@panix.com> - 2013-07-14 21:30 -0400
        Re: Ideal way to separate GUI and logic? Steven D'Aprano <steve@pearwood.info> - 2013-07-15 01:44 +0000
    Re: Ideal way to separate GUI and logic? asimjalis@gmail.com - 2013-07-15 10:06 -0700
      Re: Ideal way to separate GUI and logic? fronagzen@gmail.com - 2013-07-15 17:25 -0700
        Re: Ideal way to separate GUI and logic? Owen Marshall <o@owenmarshall.invalid> - 2013-07-16 00:42 +0000
        Re: Ideal way to separate GUI and logic? Asim Jalis <asimjalis@gmail.com> - 2013-07-15 18:02 -0700
        Re: Ideal way to separate GUI and logic? Chris Angelico <rosuav@gmail.com> - 2013-07-16 13:18 +1000

#50590 — Ideal way to separate GUI and logic?

Fromfronagzen@gmail.com
Date2013-07-13 04:07 -0700
SubjectIdeal way to separate GUI and logic?
Message-ID<b8d83518-77f9-4b09-8b6b-f8e6c84efa50@googlegroups.com>
Well, I'm a newcome to Python, but I'm developing a program with a GUI in tkinter, and I'm wondering what is the best, 'most pythonic' way of doing this?

I could, obviously, write a monolithic block of code.

I can define the logic and the GUI as two separate classes and then call from those classes within a single script.

Those are probably less than ideal.

But how then do I separate out the logic and the GUI? Because the GUI needs to have commands defined for button presses and so forth, and those have to come from the logic section. Do I write the logic in a separate file and then import those to the GUI, and then run it there? Wouldn't it be better to have one file for the GUI, one for the logic, and then a third one that imports from both and then executes the app? How do I do that? (Examples would be nice, if possible.)

[toc] | [next] | [standalone]


#50591

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-07-13 11:43 +0000
Message-ID<51e13d5d$0$9505$c3e8da3$5496439d@news.astraweb.com>
In reply to#50590
On Sat, 13 Jul 2013 04:07:21 -0700, fronagzen wrote:

> Well, I'm a newcome to Python, but I'm developing a program with a GUI
> in tkinter, and I'm wondering what is the best, 'most pythonic' way of
> doing this?
> 
> I could, obviously, write a monolithic block of code.
> 
> I can define the logic and the GUI as two separate classes and then call
> from those classes within a single script.
> 
> Those are probably less than ideal.
> 
> But how then do I separate out the logic and the GUI? Because the GUI
> needs to have commands defined for button presses and so forth, and
> those have to come from the logic section. Do I write the logic in a
> separate file and then import those to the GUI, and then run it there?
> Wouldn't it be better to have one file for the GUI, one for the logic,
> and then a third one that imports from both and then executes the app?
> How do I do that? (Examples would be nice, if possible.)

The important thing is that the application logic is separate from the 
user interface. It doesn't matter whether than means "two functions in 
the same module", or "two modules". Whether you decide to split your code 
into two modules depends on how complex your code is.

For example, if you are writing a "Hello World" application, you would be 
nuts to split this into two files.


=== cut ===

def greet(name):
    return "Hello, %s!" % name

def do_greet(name=None):
    if name is None:
        name = raw_input("What is your name? ").strip()
    print greet(name)


do_greet()

=== cut ===


Only you know how big and complex your application is, so only you know 
whether or not you should separate the GUI interface from the internal 
logic. But, my guess is that for anything non-trivial, you probably 
should have one main module handling the UI, and a second (and possibly 
more) modules handling the implementation, plus at least one other module 
for testing.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#50594

FromRoland Koebler <r.koebler@yahoo.de>
Date2013-07-13 15:56 +0200
Message-ID<mailman.4678.1373724118.3114.python-list@python.org>
In reply to#50590
Hi,

> But how then do I separate out the logic and the GUI?
I usually write a library (C library, Python module, ...) which contains
the logic.

Then, I write a GUI (in a separate file), which imports and uses the library.
If I need another UI (e.g. GUI with an other toolkit, or a text-based or
HTML5-based interface), I simply write another UI (in a separate file), and
import+use the library again.

That's the cleanest way to separate user-interface and logic in my
opinion. (But keep in mind that it's not always obvious which parts
belong to the library and which belong to the GUI, and you sometimes
have to carefully think about it.)

Oh, and yes, you can do nice things then, e.g. remote-GUIs by transparently
tunneling all calls from the GUI to the library through RPC over a network
(like I have done with a GTK+-GUI for Raspberry Pi; the GUI runs on the PC,
uses JSON-RPC over TCP-sockets and calls functions on the RPi).


regards,
Roland

[toc] | [prev] | [next] | [standalone]


#50603

FromDave Cook <davecook@nowhere.net>
Date2013-07-13 17:40 +0000
Message-ID<51e19121$0$1844$c3e8da3$f017e9df@news.astraweb.com>
In reply to#50590
On 2013-07-13, fronagzen@gmail.com <fronagzen@gmail.com> wrote:
> I'm wondering what is the best, 'most pythonic' way 

I recommend PyPubsub:

http://pubsub.sourceforge.net/

Dave Cook

[toc] | [prev] | [next] | [standalone]


#50612

FromWayne Werner <wayne@waynewerner.com>
Date2013-07-13 14:03 -0500
Message-ID<mailman.4685.1373742210.3114.python-list@python.org>
In reply to#50590
On Sat, 13 Jul 2013, fronagzen@gmail.com wrote:

> Well, I'm a newcome to Python, but I'm developing a program with a GUI in tkinter, and I'm wondering what is the best, 'most pythonic' way of doing this?
>
> I could, obviously, write a monolithic block of code.
  True, you could, but don't do that.

  You should investigate strategies like model view presenter, and test or
  behavior driven development.


  My recommendation echos the other advice you've been given. Basically you
  think of your application in terms of two problems or domains. One is the what
  that you want no do. What information do you need?

  The other problem is how do you get that information from the user and retun
  to them information than they need?

  Regardless of which side you have driving, UI or Presenter, having a design
  such as this allows for much cleaner code.

  HTH
  -W

[toc] | [prev] | [next] | [standalone]


#50651

Fromfronagzen@gmail.com
Date2013-07-14 17:24 -0700
Message-ID<9a364049-f80a-49e0-89be-e8a2c645a1dd@googlegroups.com>
In reply to#50612
Thanks for all the responses!

So as a general idea, I should at the very least separate the GUI from the program logic by defining the logic as a function, correct? And the next level of separation is to define the logic as a class in one or more separate files, and then import it to the file with the GUI, correct?

My next question is, to what degree should I 'slice' my logic into functions? How small or how large should one function be, as a rule of thumb?

[toc] | [prev] | [next] | [standalone]


#50652

Fromfronagzen@gmail.com
Date2013-07-14 17:25 -0700
Message-ID<bc883a02-1db9-4428-ac19-838606dd866d@googlegroups.com>
In reply to#50612
Thanks for all the responses!

So as a general idea, I should at the very least separate the GUI from the program logic by defining the logic as a function, correct? And the next level of separation is to define the logic as a class in one or more separate files, and then import it to the file with the GUI, correct?

My next question is, to what degree should I 'slice' my logic into functions? How small or how large should one function be, as a rule of thumb?

[toc] | [prev] | [next] | [standalone]


#50653

FromJoel Goldstick <joel.goldstick@gmail.com>
Date2013-07-14 21:02 -0400
Message-ID<mailman.4706.1373850127.3114.python-list@python.org>
In reply to#50652

[Multipart message — attachments visible in raw view] — view raw

On Sun, Jul 14, 2013 at 8:25 PM, <fronagzen@gmail.com> wrote:

> Thanks for all the responses!
>
> So as a general idea, I should at the very least separate the GUI from the
> program logic by defining the logic as a function, correct? And the next
> level of separation is to define the logic as a class in one or more
> separate files, and then import it to the file with the GUI, correct?
>
> My next question is, to what degree should I 'slice' my logic into
> functions? How small or how large should one function be, as a rule of
> thumb?
> --
> http://mail.python.org/mailman/listinfo/python-list
>


Others may differ.  I think you should just write the code.  In actually
doing that you will learn the pitfalls of how you have divided up your
logic.  Writing code isn't all theory.  It takes practice, and since the
days of The Mythical Man-Month, it has been well understood that you always
end up throwing away the first system anyway.  It has to be built to truly
understand what you think you want to create, but in the learning, you
realize that its easier and better to start more or less from scratch
rather than try to fix the first concept.



-- 
Joel Goldstick
http://joelgoldstick.com

[toc] | [prev] | [next] | [standalone]


#50654

FromRoy Smith <roy@panix.com>
Date2013-07-14 21:30 -0400
Message-ID<roy-0426C4.21305214072013@70-1-84-166.pools.spcsdns.net>
In reply to#50653
In article <mailman.4706.1373850127.3114.python-list@python.org>,
 Joel Goldstick <joel.goldstick@gmail.com> wrote:

> Writing code isn't all theory.  It takes practice, and since the days 
> of The Mythical Man-Month, it has been well understood that you 
> always end up throwing away the first system anyway.

If I may paraphrase Brooks, "Plan to throw the first one away, because 
it's going to suck.  Then, the next one you write to replace it will 
also suck because it's going to suffer from Second System Effect" :-)

BTW, anybody who enjoyed The Mythical Man-Month should also read Ed 
Yourdon's Death March.

[toc] | [prev] | [next] | [standalone]


#50655

FromSteven D'Aprano <steve@pearwood.info>
Date2013-07-15 01:44 +0000
Message-ID<51e353f3$0$29866$c3e8da3$5496439d@news.astraweb.com>
In reply to#50652
On Sun, 14 Jul 2013 17:25:32 -0700, fronagzen wrote:

> My next question is, to what degree should I 'slice' my logic into
> functions? How small or how large should one function be, as a rule of
> thumb?

I aim to keep my functions preferably below a dozen lines (excluding the 
doc string), and definitely below a page.

But more important than size is functionality. Every function should do 
*one thing*. If that thing can be divided into two or more "sub-things" 
then they should be factored out into separate functions, which I then 
call. Possibly private, internal only functions.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#50704

Fromasimjalis@gmail.com
Date2013-07-15 10:06 -0700
Message-ID<22e50125-633a-4bae-a317-a83a748be225@googlegroups.com>
In reply to#50590
fron...@gmail.com wrote:
> So as a general idea, I should at the very least separate the GUI from the program logic by defining the logic as a function, correct? And the next level of separation is to define the logic as a class in one or more separate files, and then import it to the file with the GUI, correct? 
> 
> My next question is, to what degree should I 'slice' my logic into functions? How small or how large should one function be, as a rule of thumb? 

The way I do this is to write unit tests against the class and the functions (take a look at the unittest module). The functions methods (take a look at the unittest module). Each function should contain the smallest bit of testable logic.

Another way to think about this is that each function should contain the smallest piece of logic that you can describe as one action.

-
Asim Jalis

[toc] | [prev] | [next] | [standalone]


#50717

Fromfronagzen@gmail.com
Date2013-07-15 17:25 -0700
Message-ID<8152b57e-5ff3-4024-9de1-d0a20b5c14b6@googlegroups.com>
In reply to#50704
On Tuesday, July 16, 2013 1:06:30 AM UTC+8, asim...@gmail.com wrote:
> fron...@gmail.com wrote:
> 
> > So as a general idea, I should at the very least separate the GUI from the program logic by defining the logic as a function, correct? And the next level of separation is to define the logic as a class in one or more separate files, and then import it to the file with the GUI, correct? 
> 
> > 
> 
> > My next question is, to what degree should I 'slice' my logic into functions? How small or how large should one function be, as a rule of thumb? 
> 
> 
> 
> The way I do this is to write unit tests against the class and the functions (take a look at the unittest module). The functions methods (take a look at the unittest module). Each function should contain the smallest bit of testable logic.
> 
> 
> 
> Another way to think about this is that each function should contain the smallest piece of logic that you can describe as one action.
> 
> 
> 
> -
> 
> Asim Jalis

Again, thanks for all the responses. I'm curious, though, what exactly is the rationale for making functions so small? (I've heard that the function calling of Python has relatively high overhead?)

[toc] | [prev] | [next] | [standalone]


#50719

FromOwen Marshall <o@owenmarshall.invalid>
Date2013-07-16 00:42 +0000
Message-ID<slrnku95nq.c0v.o@owen-marshall-4.local>
In reply to#50717
On 2013-07-16, fronagzen@gmail.com <fronagzen@gmail.com> wrote:
> On Tuesday, July 16, 2013 1:06:30 AM UTC+8, asim...@gmail.com wrote:
>> fron...@gmail.com wrote:
>>
>> > So as a general idea, I should at the very least separate the GUI
>> > from the program logic by defining the logic as a function,
>> > correct? And the next level of separation is to define the logic as
>> > a class in one or more separate files, and then import it to the
>> > file with the GUI, correct?
>>
>> >
>>
>> > My next question is, to what degree should I 'slice' my logic into
>> > functions? How small or how large should one function be, as a rule
>> > of thumb?
>>
>>
>>
>> The way I do this is to write unit tests against the class and the
>> functions (take a look at the unittest module). The functions methods
>> (take a look at the unittest module). Each function should contain
>> the smallest bit of testable logic.
>>
>>
>>
>> Another way to think about this is that each function should contain
>> the smallest piece of logic that you can describe as one action.
>>
>>
>>
>> -
>>
>> Asim Jalis
>
> Again, thanks for all the responses. I'm curious, though, what exactly
> is the rationale for making functions so small? (I've heard that the
> function calling of Python has relatively high overhead?)

Small functions are _always_ encouraged for every language. This is best
practice for everything, not just Python. Has nothing to do with
overhead.

--
                        -owen

[toc] | [prev] | [next] | [standalone]


#50722

FromAsim Jalis <asimjalis@gmail.com>
Date2013-07-15 18:02 -0700
Message-ID<mailman.4752.1373936531.3114.python-list@python.org>
In reply to#50717

[Multipart message — attachments visible in raw view] — view raw

On Mon, Jul 15, 2013 at 5:25 PM, <fronagzen@gmail.com> wrote:

> Again, thanks for all the responses. I'm curious, though, what exactly is
> the rationale for making functions so small? (I've heard that the function
> calling of Python has relatively high overhead?)
>

There is a small overhead, but it makes the code easier to read and
understand. You can look at the function name and get and idea of _what_
the function is doing instead of having to figure out _how_ it is doing it.

Regarding optimization, after you have written your application if you see
performance issues you can surgically optimize the spots that have the
issues and leave most of the code untouched.

To quote Don Knuth, "premature optimization is the root of all evil". Also
the article at http://en.wikipedia.org/wiki/Program_optimization makes some
good points.

[toc] | [prev] | [next] | [standalone]


#50725

FromChris Angelico <rosuav@gmail.com>
Date2013-07-16 13:18 +1000
Message-ID<mailman.4754.1373944739.3114.python-list@python.org>
In reply to#50717
On Tue, Jul 16, 2013 at 10:25 AM,  <fronagzen@gmail.com> wrote:
> Again, thanks for all the responses. I'm curious, though, what exactly is the rationale for making functions so small? (I've heard that the function calling of Python has relatively high overhead?)

A function should be as long as it needs to be - neither longer nor
shorter. If you can name a function appropriately, and it's doing
exactly what its name suggests, it's the right length. This generally
produces short functions rather than long ones, but if the right
length for a function exceeds some arbitrary limit, let the function
be longer. For instance, I have a single function that's a bit over a
page in length, because it's one big switch block (this isn't in
Python, obviously), doing one thing fairly cleanly. Larger than that
would have to be called code smell, but there's certainly nothing
wrong with having the odd function here or there that's over Steven's
dozen-line estimate. There'll also be plenty of really short functions
- even one-liners.

The largest single function in any of my code, I think, is a gigantic
double-nested switch block in PHP .In any decent language, that would
be divided up not just into functions but into files, but PHP has some
stupid restrictions on its include directive that make that
impractical. So syntactically it's one massive function, but logically
it's about seven or eight separate sub-blocks, and the code is laid
out in those blocks. It's just that the technical nesting level never
actually hits zero in between them :) Have to confess, though, I've
had some fairly large functions in C++ (not as big as the
aforementioned, but still fairly large - what's the next one down from
gigantic, megantic? [1] would suggest so), which in some cases could
be split if I felt like putting in the time to do it.

ChrisA

[1] http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=370794

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web