Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Ideal way to separate GUI and logic?

2,345 views
Skip to first unread message

fron...@gmail.com

unread,
Jul 13, 2013, 7:07:21 AM7/13/13
to
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.)

Steven D'Aprano

unread,
Jul 13, 2013, 7:43:25 AM7/13/13
to
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

Roland Koebler

unread,
Jul 13, 2013, 9:56:20 AM7/13/13
to pytho...@python.org
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

Dave Cook

unread,
Jul 13, 2013, 1:40:49 PM7/13/13
to
On 2013-07-13, fron...@gmail.com <fron...@gmail.com> wrote:
> I'm wondering what is the best, 'most pythonic' way

I recommend PyPubsub:

http://pubsub.sourceforge.net/

Dave Cook

Wayne Werner

unread,
Jul 13, 2013, 3:03:24 PM7/13/13
to fron...@gmail.com, pytho...@python.org
On Sat, 13 Jul 2013, fron...@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

fron...@gmail.com

unread,
Jul 14, 2013, 8:24:40 PM7/14/13
to
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?

fron...@gmail.com

unread,
Jul 14, 2013, 8:25:32 PM7/14/13
to

Joel Goldstick

unread,
Jul 14, 2013, 9:02:00 PM7/14/13
to fron...@gmail.com, pytho...@python.org
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.



--

Roy Smith

unread,
Jul 14, 2013, 9:30:52 PM7/14/13
to
In article <mailman.4706.1373850...@python.org>,
Joel Goldstick <joel.go...@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.

Steven D'Aprano

unread,
Jul 14, 2013, 9:44:19 PM7/14/13
to
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

asim...@gmail.com

unread,
Jul 15, 2013, 1:06:30 PM7/15/13
to
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

fron...@gmail.com

unread,
Jul 15, 2013, 8:25:57 PM7/15/13
to
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?)

Owen Marshall

unread,
Jul 15, 2013, 8:42:34 PM7/15/13
to
Small functions are _always_ encouraged for every language. This is best
practice for everything, not just Python. Has nothing to do with
overhead.

--
-owen

Asim Jalis

unread,
Jul 15, 2013, 9:02:03 PM7/15/13
to fron...@gmail.com, pytho...@python.org
On Mon, Jul 15, 2013 at 5:25 PM, <fron...@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.

Chris Angelico

unread,
Jul 15, 2013, 11:18:56 PM7/15/13
to pytho...@python.org
On Tue, Jul 16, 2013 at 10:25 AM, <fron...@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
0 new messages