# [graph-tool] Variable scoping for collect_vertex_marginals

Davide Cittaro cittaro.davide at gmail.com
Thu Jan 16 13:00:53 CET 2020

```Thanks, for the time being I've solved with a try/except within the function, so that

def foo():
global pv
[…]
try:
pv = [sl.collect_vertex_marginals(pv[l]) for l, sl in enumerate(s.get_levels())]
except NameError:
pv =  [None] * len(state.get_levels())

(in fact I've tried to delete the post from the nabble interface...)
Best,

d

> On 16 Jan 2020, at 12:57, Tiago de Paula Peixoto <tiago at skewed.de> wrote:
>
> Am 16.01.20 um 11:11 schrieb Davide Cittaro:
>> Hi again,
>> This is more a python related question, but I'm asking here hoping somebody had a similar issue and worked it out.
>> I need to collect vertex marginals during equilibrate and when I do it in my python console everything works just fine (as in the cookbook):
>>
>> pv = [None] * len(state.get_levels())
>>
>> def collect_marginals(s):
>>  global pv
>>  pv = [sl.collect_vertex_marginals(pv[l]) for l, sl in enumerate(s.get_levels())]
>>
>> gt.mcmc_equilibrate(state, force_niter=10000, mcmc_args=dict(niter=10), callback=collect_marginals)
>>
>> as far as understand, every time sl.collect_vertex_marginals is called, it takes as argument the histogram calculated in the previous iterations.
>> My problem is that when I put this code into a function that is imported as a module, scoping is broken and I get an error like
>>
>> NameError: name 'pv' is not defined
>>
>> Shortly, I have the function nsbm in file _nsbm.py:
>>
>> def nsbm(…):
>>  […]
>>  pv = [None] * len(state.get_levels())
>>
>>  def collect_marginals(s):
>>    global pv
>>    pv = [sl.collect_vertex_marginals(pv[l]) for l, sl in enumerate(s.get_levels())]
>>
>>  gt.mcmc_equilibrate(state, force_niter=10000, mcmc_args=dict(niter=10), callback=collect_marginals)
>>
>> which is imported
>>
>> from ._nsbm import nsbm
>>
>> by the __init__.py of the package module (named tools), then imported by the main
>>
>> from . import tools as tl
>>
>> the directory structure of the package is (among others)
>>
>> scanpy/tools/_nsbm.py
>> scanpy/tools/__init__.py
>> scanpy/__init__.py
>>
>> as far as I understand callback function passed to mcmc_equilibrate is not supposed to return anything, collect_vertex_marginals returns the histogram summing the current to the previous. I think I can't pass pv as an argument to the callback as it becomes local to the function.
>> Of course, I'm now reading about variable scoping in python, but if you have any hint it would be greatly appreciated.
>> Thanks
>
>
> You're looking for the nonlocal keyword, instead of global. See here:
>
> https://docs.python.org/3/reference/simple_stmts.html#grammar-token-nonlocal-stmt
>
> --
> Tiago de Paula Peixoto <tiago at skewed.de>
> _______________________________________________
> graph-tool mailing list
> graph-tool at skewed.de
> https://lists.skewed.de/mailman/listinfo/graph-tool

```