question: parameters for create_polygon() method

S

SeeBelow

Tkinter's canvas object has the method create_polygon().

The docs say the parameters should be like:
(x1, y1, x2, y2, x3, y3, .....)

But it's often much better programming practice to have a list of
tuples, each point being a tuple, like this:
[(x1, y1), (x2, y2), (x3, y3),......]

Is there a good way to manipulate my polygons in the latter form, but
still use create_polygon() to draw them?

Thanks,

Mitchell Timin

--
"Many are stubborn in pursuit of the path they have chosen, few in
pursuit of the goal." - Friedrich Nietzsche

http://annevolve.sourceforge.net is what I'm into nowadays.
Humans may write to me at this address: zenguy at shaw dot ca
 
A

Andrew Bennetts

Tkinter's canvas object has the method create_polygon().

The docs say the parameters should be like:
(x1, y1, x2, y2, x3, y3, .....)

But it's often much better programming practice to have a list of
tuples, each point being a tuple, like this:
[(x1, y1), (x2, y2), (x3, y3),......]

Is there a good way to manipulate my polygons in the latter form, but
still use create_polygon() to draw them?

create_polygon(*list_of_points)

-Andrew.
 
S

SeeBelow

Andrew said:
Tkinter's canvas object has the method create_polygon().

The docs say the parameters should be like:
(x1, y1, x2, y2, x3, y3, .....)

But it's often much better programming practice to have a list of
tuples, each point being a tuple, like this:
[(x1, y1), (x2, y2), (x3, y3),......]

Is there a good way to manipulate my polygons in the latter form, but
still use create_polygon() to draw them?

create_polygon(*list_of_points)

-Andrew.

Thanks Andrew, but I don't understand it. What's that * thing?

Is there a * operator that converts a list of tuples into one big tuple?

Mitchell Timin

--
"Many are stubborn in pursuit of the path they have chosen, few in
pursuit of the goal." - Friedrich Nietzsche

http://annevolve.sourceforge.net is what I'm into nowadays.
Humans may write to me at this address: zenguy at shaw dot ca
 
A

Andrew Bennetts

Andrew said:
Tkinter's canvas object has the method create_polygon().

The docs say the parameters should be like:
(x1, y1, x2, y2, x3, y3, .....)

But it's often much better programming practice to have a list of
tuples, each point being a tuple, like this:
[(x1, y1), (x2, y2), (x3, y3),......]

Is there a good way to manipulate my polygons in the latter form, but
still use create_polygon() to draw them?

create_polygon(*list_of_points)

-Andrew.

Thanks Andrew, but I don't understand it. What's that * thing?

Is there a * operator that converts a list of tuples into one big tuple?

Sorry, I misinterpreted the problem slightly; I just checked the docs for
create_polygon and realised it takes an argument that is a sequence of
co-ords, rather than a variable number of args that are the co-ords.

I also realised that I wasn't thinking clearly anyway.

You really just need a flatten function, e.g.:

def flatten(iterable):
for elem in iterable:
for subelem in elem:
yield subelem

You can then use this like so:

create_polygon(tuple(flatten(list_of_points)))

(There are more complex flatten recipes out there, such as
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/118845, but this one
is sufficient for your needs).

-Andrew.
 
G

Greg Krohn

Thanks Andrew, but I don't understand it. What's that * thing?
Is there a * operator that converts a list of tuples into one big tuple?

Mitchell Timin

It treats the list (i.e. list_of_points) as if each element was passed
as an argument to the function. In other words:

l = [1, 2, 3]
create_polygon(*l)

is the same as

create_polygon(1, 2, 3)


greg
 
P

Peter Otten

Andrew said:
Sorry, I misinterpreted the problem slightly; I just checked the docs for
create_polygon and realised it takes an argument that is a sequence of
co-ords, rather than a variable number of args that are the co-ords.

I just tried it - it may not be in the docs, but it does work.
For example

import Tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack()
points = [(20, 20), (50, 150), (200, 50)]

canvas.create_polygon(fill="blue", *points)
root.mainloop()

will draw a blue triangle.

Peter
 
A

Andrew Bennetts

Andrew said:
Sorry, I misinterpreted the problem slightly; I just checked the docs for
create_polygon and realised it takes an argument that is a sequence of
co-ords, rather than a variable number of args that are the co-ords.

I just tried it - it may not be in the docs, but it does work.
For example
[...]
points = [(20, 20), (50, 150), (200, 50)]

canvas.create_polygon(fill="blue", *points)
[...]

Heh. I guess either the docs I found with google were wrong, or I misread
them :)

Odd, though -- I thought that calls that put non-keyword args after keyword
args were a syntax error, but using varargs syntax seems to workaround that
-- e.g. try:
canvas.create_polygon(fill="blue", (20, 20), (50, 150), (200, 50))

Or without Tk:
>>> def f(*args, **kw): print args, kw ...
>>> f(x=1, 2) SyntaxError: non-keyword arg after keyword arg
>>> f(x=1, *[2])
(2,) {'x': 1}

Interesting.

-Andrew.
 
P

Peter Finlayson

Andrew said:
> Odd, though -- I thought that calls that put non-keyword args after
> keyword args were a syntax error

I thing that is because the standard form for the calls are:
def mydef(arg1, arg2, *args, **keywords)
ie with the arbitrary argument lists after the formal args.

Peter Finlayson
 
G

Greg Ewing

Peter said:
I thing that is because the standard form for the calls are:
def mydef(arg1, arg2, *args, **keywords)
ie with the arbitrary argument lists after the formal args.

Yes. Syntactically, the * args don't count
as positional args; they're in a category of
their own.
 
S

SeeBelow

Peter Otten wrote:
I just tried it - it may not be in the docs, but it does work.
For example

import Tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack()
points = [(20, 20), (50, 150), (200, 50)]

canvas.create_polygon(fill="blue", *points)
root.mainloop()

will draw a blue triangle.

Surprisingly, it works! I tested it also. It never occurred to me to
simply try the list of tuples in place of the normal arguments as
explained in the docs. I just assumed that the docs were the full
story.

Yours is the best suggestion.

The suggestion about a flatten() function is also a good one, but it
turns out not to be needed.

Mitchell Timin

--
"Many are stubborn in pursuit of the path they have chosen, few in
pursuit of the goal." - Friedrich Nietzsche

http://annevolve.sourceforge.net is what I'm into nowadays.
Humans may write to me at this address: zenguy at shaw dot ca
 
P

Peter Otten

The suggestion about a flatten() function is also a good one, but it
turns out not to be needed.

Looking into the source it turns out that Tkinter has its own flattening
function (implemented in C, with a Python fallback), which ignores None and
processes both tuples and lists:
Tkinter._flatten([((0, 0), (100, 0)), None, ((100, 100), (0, 100)), 50,
70, (50, 30)])
(0, 0, 100, 0, 100, 100, 0, 100, 50, 70, 50, 30)
So you are not limited to tuples when constructing your polygons:

import Tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack()

line1 = (0, 0), (100, 0)
line2 = (100, 100), (0, 100)
points = [line1, None, line2, 50, 70, (50, 30)]
canvas.create_polygon(fill="red", *points)
root.mainloop()

Peter
 
M

Michael Hudson

Andrew Bennetts said:
Odd, though -- I thought that calls that put non-keyword args after keyword
args were a syntax error, but using varargs syntax seems to workaround that
-- e.g. try:
canvas.create_polygon(fill="blue", (20, 20), (50, 150), (200, 50))

Or without Tk:
def f(*args, **kw): print args, kw ...
f(x=1, 2) SyntaxError: non-keyword arg after keyword arg
f(x=1, *[2])
(2,) {'x': 1}

Interesting.

And even documented in all its tortuosity:

http://docs.python.org/ref/calls.html

(I know, I wrote that bit...)

Cheers,
mwh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top