title: Using for loop to define multiple functions in Python?
body: <p>I need to create 8 functions looking like <code>fcXX_at_this_z(r)</code>, where <code>XX</code> ranges from <code>47</code> to <code>54</code> in integer steps of 1.</p>
  <p>So the first function shall have its protoype: <code>def fc47_at_this_z(r):</code>, the second function shall have its prototype <code>def fc48_at_this_z(r):</code> ... and the last function shall have its prototype <code>def fc54_at_this_z(r):</code>.</p>
  <p>The body of these functions shall read:</p>
  <pre><code>return upgrade_interpolator_cXX(r)
  </code></pre>
  <p>where again XX ranges from 47 to 54.</p>
  <p>So I need to be able to use the function name inside the body of the function, for each function.</p>
  <p>How could I define these functions and their bodies using a for-loop in Python?</p>
  <p>Moreover, I will need to use these functions, after I defined them, as following:</p>
  <pre><code>use_it(fc54_at_this_z, ...)
  </code></pre>
  <p>or</p>
  <pre><code>use_it(fc47_at_this_z, ...)
  </code></pre>
  <p>So again I need to be able to somehow insert that index 47, 48, ..., 54 inside that function call <code>use_it(f)</code>.</p>
  <p>This would be my second question about these functions, how can I use in the way above, after I defined them using the for-loop?
  Ideally, I need to use these inside a for loop, that is in pseudocode:</p>
  <pre><code>for idx in range(7):
      use_it(fc+(47+idx)+_at_this_z)
  </code></pre>
  <h1>The bigger picture</h1>
  <p>The bigger picture is as following:</p>
  <p>I need to perform a 2Dim integral across z and r. The r limit is a function of z. So it's not a square, not a rectangle, it's a strange shape in 2Dims across which I need to integrate.
  I partition the z using N_z as:</p>
  <pre><code>N_z = 10**3
  z_is = (-zrange) + (np.arange(N_z) + 0.5) * (2.*zrange/N_z) # shall be shape(N_z,)
  </code></pre>
  <p>and perform adaptive gaussian integrals at each value of <code>z</code> from <code>z_is</code>. I store results in a matrix shaped <code>(N_z, 8)</code>.</p>
  <p>The integrations at each value of <code>z</code> from <code>z_is</code> happen as:</p>
  <pre><code>results = np.zeros((N_z, 8))
  errs = np.zeros((N_z,8))
  for i in range(N_z):
  # ideally a for loop with index idx shall appear here!
  # that idx dictates which fcXX we work with. I need to work with all of them, so I need this additional for-loop to integrate all the fc_XX's across r, and store results in the matrices `results, err`
  # now this code doesn't work, in particular the integrate_adaptive() below cannot populate the columns of the results and errs matrices!
  # it doesn't know understand the 2nd dimension of the results matrices, it just integrates f_c54, rather than all the f_cXX's!
      def fc54_at_this_z(r): # depenedent only on r
          I_to_query_at = get_I_at_this_z_and_r(z_is[i], r)
          return (2 * pi * r * interpolator_c54(I_to_query_at))
      r_thresh_of_z = get_r_thr(z_is[i])
      results[i, idx], errs[i, idx] = quadpy.c1.integrate_adaptive(fc54_at_this_z, [0., r_thresh_of_z ])
  </code></pre>