Search code examples
pythonnumpymatplotlibscipyodeint

Updation of Old Python Code


Pretty noob question so please bear with me because I am new to Python. Below given code is about Ordinary Differential Equation generating automatic combinations of ODE. I tried to execute this code on Python 3.6.3 and on Spider(Pyton 3.6) but no outcomes. I spent many days to make it executable on new version of Python but I am unable to execute it because more errors are generating. So I copied the code as it was.

from scipy import* 
from scipy.integrate import odeint
from operator import itemgetter
import matplotlib
matplotlib.use('Agg')
from matplotlib.ticker import FormatStrFormatter
from pylab import *
from itertools import product, islice
from numpy import zeros_like
from string import ascii_lowercase
import operator

import sys


t_range = arange(0.0, 20.0, 0.1)
# initial_condi = []
# VarList = []
# ParamsList = []
ops = "+-"
opsdict = { "+": operator.add, "-": operator.sub }

# if len(initial_condi)!=len(VarList):
    # sys.exit('error: the number of initional conditions do not equal to the number of variables')


def odeFunc(Y, t, model, K):
    return GenModel(Y, model, K)


def GenModel(Y, model, K):
    # New array of floating-point zeros the size of Y
    dydt = zeros_like(Y)
    for i, derivative in enumerate(model):
        for j, operator in enumerate(derivative):
            # Sequentially compute dy/dt for each variable in Y
            dydt[i] = opsdict[operator](dydt[i],K[j]*Y[j])
    return dydt

# Returns a nicer-looking string for a derivative expression given the encoding
def derivString(vars, deriv):
    result = ""
    for i, v in enumerate(vars):
        if i == 0 and deriv[i] == '+':
            result += v
        else:
            result += deriv[i]+v
    return result

# main
numvars = int(raw_input("Enter number of variables\n> "))
VarList = ascii_lowercase[:numvars]
nummodels = (2**numvars)**numvars

# begin looping
input = ""
while input != "quit":
    print "\n%d possible models" % nummodels
    input = raw_input("Enter model ID (zero-indexed) or 'quit'\n> ")
    # Basic input filtering
    if input == "quit":
        continue
    elif not input.isdigit():
        print "Input must be a non-negative integer"
        continue
    ID = int(input)
    if ID >= nummodels or ID < 0:
        print "Invalid ID"
        continue

    # itertools.product creates a generator for all possible combinations of +-
    derivatives = product(ops, repeat=numvars)
    # We take the product again to generate all models
    models = product(derivatives, repeat=numvars)
    # islice takes the specified model
    model = next(islice(models, ID, None))

    # Display dy/dt for each variable
    print "Model %d:" % ID
    IDtitle = []
    for i, variable in enumerate(VarList):
        tempstring = "d%c/dt = %s" % (variable, derivString(VarList, model[i]))
        IDtitle.append(tempstring)
        print "\t" + tempstring

    # User specifies the initial values of all variables.
    # This process can be automated but this is to demonstrate that the progam
    # accepts any input
    init_cons = []
    params = []

    confirm = ""
    while confirm not in ("y", "n"):
        confirm = raw_input("Run this model? (y/n)\n> ")
    if confirm == "n":
        continue

    print "\nEnter <initial value, parameter> pairs separated by ','"
    for i, variable in enumerate(VarList):
        iv_param = map(float, raw_input("> %c: " % variable).split(','))
        init_cons.append(iv_param[0])
        params.append(iv_param[1])

    print "\nRunning ODEint...",
    result = odeint(odeFunc, init_cons, t_range, args=(model,params))
    print " done."

    print "Plotting results...",
    f = figure(ID)
    title(", ".join(IDtitle))
    for i, variable in enumerate(VarList):
        plot(t_range, result[:,i], label=variable)
    legend()
    axhline(0, color='k')
    savefig("model"+str(ID))
    close(f)
    print "done."

print " -- Bye --"

Solution

  • raw_input is now called input in Python3. You also had a variable called input, which may have caused confusion.

    from scipy import * 
    from scipy.integrate import odeint
    from operator import itemgetter
    import matplotlib
    matplotlib.use('Agg')
    from matplotlib.ticker import FormatStrFormatter
    from pylab import *
    from itertools import product, islice
    from numpy import zeros_like
    from string import ascii_lowercase
    import operator
    import sys
    
    t_range = arange(0.0, 20.0, 0.1)
    # initial_condi = []
    # VarList = []
    # ParamsList = []
    ops = "+-"
    opsdict = { "+": operator.add, "-": operator.sub }
    
    # if len(initial_condi)!=len(VarList):
        # sys.exit('error: the number of initional conditions do not equal to the number of variables')
    
    def odeFunc(Y, t, model, K):
        return GenModel(Y, model, K)
    
    def GenModel(Y, model, K):
        # New array of floating-point zeros the size of Y
        dydt = zeros_like(Y)
        for i, derivative in enumerate(model):
            for j, operator in enumerate(derivative):
                # Sequentially compute dy/dt for each variable in Y
                dydt[i] = opsdict[operator](dydt[i],K[j]*Y[j])
        return dydt
    
    # Returns a nicer-looking string for a derivative expression given the encoding
    def derivString(vars, deriv):
        result = ""
        for i, v in enumerate(vars):
            if i == 0 and deriv[i] == '+':
                result += v
            else:
                result += deriv[i]+v
        return result
    
    # main
    numvars = int(input("Enter number of variables\n> "))
    VarList = ascii_lowercase[:numvars]
    nummodels = (2**numvars)**numvars
    
    # begin looping
    input_ = ""
    while input_ != "quit":
        print("\n%d possible models" % nummodels)
        input_ = input("Enter model ID (zero-indexed) or 'quit'\n> ")
        # Basic input filtering
        if input_ == "quit":
            continue
        elif not input_.isdigit():
            print("Input must be a non-negative integer")
            continue
        ID = int(input_)
        if ID >= nummodels or ID < 0:
            print("Invalid ID")
            continue
    
        # itertools.product creates a generator for all possible combinations of +-
        derivatives = product(ops, repeat=numvars)
        # We take the product again to generate all models
        models = product(derivatives, repeat=numvars)
        # islice takes the specified model
        model = next(islice(models, ID, None))
    
        # Display dy/dt for each variable
        print("Model %d:" % ID)
        IDtitle = []
        for i, variable in enumerate(VarList):
            tempstring = "d%c/dt = %s" % (variable, derivString(VarList, model[i]))
            IDtitle.append(tempstring)
            print("\t" + tempstring)
    
        # User specifies the initial values of all variables.
        # This process can be automated but this is to demonstrate that the progam
        # accepts any input
        init_cons = []
        params = []
    
        confirm = ""
        while confirm not in ("y", "n"):
            confirm = input("Run this model? (y/n)\n> ")
        if confirm == "n":
            continue
    
        print("\nEnter <initial value, parameter> pairs separated by ','")
        for i, variable in enumerate(VarList):
            iv_param = list(map(float, input("> %c: " % variable).split(',')))
            init_cons.append(iv_param[0])
            params.append(iv_param[1])
    
        print("\nRunning ODEint...", end='')
        result = odeint(odeFunc, init_cons, t_range, args=(model,params))
        print(" done.")
    
        print("Plotting results...", end='')
        f = figure(ID)
        title(", ".join(IDtitle))
        for i, variable in enumerate(VarList):
            plot(t_range, result[:,i], label=variable)
        legend()
        axhline(0, color='k')
        savefig("model"+str(ID))
        close(f)
        print("done.")
    
    print(" -- Bye --")