abscissa
abscissa

Reputation: 245

How to share variable between multiple functions in Python, i.e., globally?

In the code below, I have two functions: func1 and gillespie. I have defined p_tot_stoch as a global variable, within func1. (The reason for placing it inside a function is to allow Numba's @jit wrapper to work properly... Numba is used for code optimization.)

But when I try to print p_tot_stoch at the very end of the code, I get the following error message:

Traceback (most recent call last):
  File "C:/Users/dis_YO_boi/Documents/Programming/Python/CodeReview.py", line 85, in <module>
    p_tot_stoch = gillespie()
NameError: global name 'p_tot_stoch' is not defined

I declared it as global, but it looks like the main function gillespie cannot access it. How can I fix this?

My code is below, thanks for any help.

from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
from numba import jit
import math
random = np.random

DELTA = 1e-3
SIM_NUM = 100
K_MINUS = 1e-3
K_CAT = 1 - 1e-3
ZETA = 1e-4
D = 10000
QP_VEC = np.logspace(-2, 1, 101, 10)
KAPPA_M = (K_CAT + K_MINUS) / ZETA
P0_VEC = QP_VEC / DELTA
QP_DEG = np.true_divide(1000*D*QP_VEC*K_CAT,1000*QP_VEC+KAPPA_M)

@jit
def func1():
    global p_tot_stoch
    p_tot_stoch = np.empty((SIM_NUM, len(QP_VEC)))

@jit
def gillespie(max_time=1000):
    for len_qp_ind in range(len(QP_VEC)):
        qp = QP_VEC[len_qp_ind]
        p0 = math.ceil(P0_VEC[len_qp_ind])
        for sim_num_ind in range(SIM_NUM):
            p = p0
            d = D
            dp = time = 0

            while True:
                tot = [qp, ZETA * p * d, K_MINUS * dp, K_CAT * dp]
                for i in range(3):
                    tot[i + 1] += tot[i]
                p_tot = p + dp
                kt = tot[-1]
                time += -np.log(1 - random.random()) / kt
                if time > max_time:
                    p_tot_stoch[sim_num_ind, len_qp_ind] = p_tot
                    break

                event_kt = random.random() * kt
                if event_kt < tot[0]:
                    p += 1
                elif event_kt < tot[1]:
                    p -= 1
                    dp += 1
                    d -= 1
                elif event_kt < tot[2]:
                    p += 1
                    dp -= 1
                    d += 1
                elif event_kt < tot[3]:
                    dp -= 1
                    d += 1
    return p_tot_stoch

if __name__ == '__main__':
        p_tot_stoch = gillespie()
        p_mean = p_tot_stoch.mean(axis=0)
        p_std = p_tot_stoch.std(axis=0)
        print(p_tot_stoch)

Upvotes: 1

Views: 4452

Answers (2)

Muposat
Muposat

Reputation: 1506

I modified @haifzhan's example because it is simple. Python benefits from OOP tremendously and it is a sin not to use it:

#!/usr/bin/env python3

class Stoch:
    def __init__(self):
        self.my_variable = 0

    def __str__(self):
        return str(self.my_variable)

    def func1(self):
        self.my_variable = -1
        print ("func1:", self)

    def gillespie(self):
        self.my_variable = 4
        print ("gillespie:", self)

    @classmethod
    def main(cls):
        stoch = Stoch()
        print ("before:", stoch)    
        stoch.func1()
        stoch.gillespie()
        print ("after:", stoch)

if __name__ == '__main__':
    Stoch.main()

Upvotes: 0

Haifeng Zhang
Haifeng Zhang

Reputation: 31885

cat test.py

my_variable = 0


def func1():
    global my_variable
    my_variable = -1
    print "func1:{0}".format(my_variable)


def gillespie():
    global my_variable
    my_variable = 4
    print "gillespie:{0}".format(my_variable)


# Starts testing... 
print "before:{0}".format(my_variable)
func1()
gillespie()
print "after:{0}".format(my_variable)

python test.py

before:0
func1:-1
gillespie:4
after:4

You can declare your variable p_tot_stoch(in my test.py I declared a variable named my_varialble it is used in func1() and gillespie()) on the top of your script and outside of your functions. Each time you want to modify it you have to declare it is a global variable and then assign a new value to it.

Im using python2.7

Upvotes: 1

Related Questions