1

I'm still learning Python, and I'd love to know a way to make the following work:

a_function(
  for n,item in enumerate(list):
    inside_function(code code code,
                    code code code,
                    code code code))

So there's a function nested inside another function, and I need to play out the inside function a number of times, but not the outside one. The code I'm working with is not mine so I can't change the way these functions work.

I can edit with the actual code if anyone needs it, it's something from PyChart.

Edit: actual code:

ar = area.T(y_coord = category_coord.T(data, 0),
            x_grid_style=line_style.gray50_dash1,
            x_grid_interval=chartlength/5, x_range = (0,chartlength),
            x_axis=axis.X(label="X label"),
            y_axis=axis.Y(label="Y label"))

chart_object.set_defaults(interval_bar_plot.T, direction="horizontal",
                          width=5, cluster_sep = 0, data=data)

ar.add_plot(
  for n,item in enumerate(compactlist):
    interval_bar_plot.T(line_styles = [None, None],
                    fill_styles = [fill_style.red, None],
                    label=compactlist[n], cluster=(n,len(compactlist)))
)

can = canvas.default_canvas()
can.set_title("Chromosome comparison")
can.set_author("Foo")
ar.draw()

The ar.add_plot function creates a working area in the canvas (as I understand it), while the interval_bar_plot function creates the bars, one by one. So I need multiple interval_bar_plot functions but only the one add_plot, or it simply repeats the first bar n times.

Edit: and the error:

  File "intvlbar.py", line 105
    for n,item in enumerate(compactlist):
      ^
SyntaxError: invalid syntax
lowercasename
  • 281
  • 4
  • 14
  • 5
    so what is the problem you are having? – jb. Jan 30 '12 at 00:36
  • Oh, sorry, yes. It comes out with an invalid syntax error at the beginning of the for loop. – lowercasename Jan 30 '12 at 00:38
  • 2
    The actual code might be useful. The pseudo-code that you posted doesn't make much sense to me. Does the a_function accept parameters? What is "code code code"? What does that code do? – Mark Byers Jan 30 '12 at 00:39
  • 1
    gotta be a little more specific. I assume `code code code, code code code...` aren't your actual parameters? Can you update your code example with what you actually have? And also give the error. – jb. Jan 30 '12 at 00:40
  • Edited with the error and actual code. – lowercasename Jan 30 '12 at 00:46
  • I think the error is in the surrounding code as the line you point to there is OK. You need to provide a bit more context than just that one line of Python :) – snim2 Jan 30 '12 at 00:48
  • More code would be helpful, are you trying to invoke ar.add_plot with an expression that evaluates to None? Or were you intending to pass it a collection or a lambda? Does interval_bar_plot.T return a new 'T' instance? – Cory Dolphin Jan 30 '12 at 00:53
  • There we go, I've edited with the entire block of code which creates the chart objects (the rest of the code gets data from a .csv file, edits it, and pops it in the data variable). Unfortunately I didn't write any of it, so I'm little help - I just copy-pasted the example code. I only really understand half of it. Thanks for your help! – lowercasename Jan 30 '12 at 01:04

2 Answers2

4

What you are trying to do is pass several bar plot objects to the add_plot method (documented in here). One way you can do this is to pass them each explicitly. For example:

ar.add_plot(bar1, bar2, bar3)

Examples of this are in the sample code sections of the PyChart documentation for bar plots and interval bar plots, for example.

You do not want to do this because your compactlist might be inconveniently long or of varying length between runs. Another option is to use argument unpacking. Create a list containing your bar plot objects:

bars = [interval_bar_plot.T(line_styles = [None, None],
                            fill_styles = [fill_style.red, None],
                            label=compactlist[n], cluster=(n,len(compactlist)))
        for n,item in enumerate(compactlist)]

Now call add_plot with your bars:

ar.add_plot(*bars)
David Alber
  • 17,624
  • 6
  • 65
  • 71
  • And because I don't see it in the question, the type of loop used in this answer is called a "list comprehension" – Izkata Jan 30 '12 at 01:15
  • That looked like exactly the sort of thing I needed, but there needs to be no third end paren after `cluster=(n,len(compactlist)`, because that way it only appears to iterate the first `interval_bar_plot` n times. When I delete that end paren, though, it comes up with a syntax error presumably because interval_bar_plot is incomplete. – lowercasename Jan 30 '12 at 01:25
  • @lowercasename I do not understand what you mean. The list comprehension is producing all `n` bar plot objects. Each call to `interval_bar_plot.T` has two variable pieces of information: `compactlist[n]` and `n`. If we take a simpler list comprehension as an example, we can see that it is producing the list with different items. I have no idea what `compactlist` is, but for the example let it be `compactlist = ['a', 'b', 'c']`. Now let `a = [(compactlist[n], n) for n,item in enumerate(compactlist)]`. Doing `print a` produces `[('a', 0), ('b', 1), ('c', 2)]`. – David Alber Jan 30 '12 at 01:40
  • Ah, no, my mistake! I've worked it out and your code works great. Thanks! – lowercasename Jan 30 '12 at 02:32
0

The error you are getting is because the for loop does not return anything in itself. But the for loop is placed inside the function call ar.add_plot() where the parameters should go. So python is telling you "ar.add_plot() needs parameters, but this for loop isn't going to give them to me"

What parameters does ar.add_plot() need?

You need something closer to this (though this probably isn't correct):

ar.add_plot()
for n,item in enumerate(compactlist):
  interval_bar_plot.T(line_styles = [None, None],
        fill_styles = [fill_style.red, None],
        label=compactlist[n], cluster=(n,len(compactlist)
jb.
  • 9,921
  • 12
  • 54
  • 90
  • Missing two closing parens on the last line there (one to close `cluster=(n` and on to close `plot.T(`) – snim2 Jan 30 '12 at 00:56
  • According to the PyChart documentation, `add_plot()` takes plot objects, which would be the `interval_bar_plot()` function. Would it be possible to approach this backwards, and first create a set of `interval_bar_plot`s, then fill `ar.add_plot` with them? – lowercasename Jan 30 '12 at 00:58