在tkinter图形用户界面中解决简单的ODE系统

2022-04-15 00:00:00 python tkinter bioinformatics ode

问题描述

我有一个用于SIR疾病模型的简单的ODE系统,它工作得很好,并产生了一个图形化的情节。但是,我正在尝试使用tkinter创建一个简单的弹出框,该框接受参数值,而不必通过脚本将参数值放入其中。

以下是原始代码。

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt

#three compartments, Susceptible S, infected I, recovered R
#dS/dt, dI/dt, dR/dt
#susceptible sees birth rate coming in, deaths leaving and force of infection leaving
#infected sees FOI coming in, deaths leaving and recovery rates
#recovered sees recovery rate coming in, deaths leaving
#beta is tranmission coefficient, FOI is beta * (I/N) where N is total pop
#initially consider a model not accounting for births and deaths




# Total population, N.
N = 1000
# Initial number of infected and recovered individuals, I0 and R0.
I0, R0 = 1, 0
# Everyone else, S0, is susceptible to infection initially.
S0 = N - I0 - R0
# Contact rate, beta, and mean recovery rate, gamma, (in 1/days).
beta, gamma = 2/7, 1/7
# A grid of time points (in days)
t = np.linspace(0, 160, 160)

# The SIR model differential equations.
def deriv(y, t, N, beta, gamma):
    S, I, R = y
    dS = ((-beta * S * I) / N)
    dI = ((beta * S * I) / N) - (gamma * I)
    dR = (gamma * I)
    return dS, dI, dR

# Initial conditions are S0, I0, R0
# Integrate the SIR equations over the time grid, t.
solve = odeint(deriv, (S0, I0, R0), t, args=(N, beta, gamma))
S, I, R = solve.T

# Plot the data on three separate curves for S(t), I(t) and R(t)
fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
ax.plot(t, S/1000, 'b', alpha=1, lw=2, label='Susceptible')
ax.plot(t, I/1000, 'r', alpha=1, lw=2, label='Infected')
ax.plot(t, R/1000, 'black', alpha=1, lw=2, label='Recovered')
ax.set_xlabel('Time in days')
ax.set_ylabel('Number (1000s)')
ax.set_ylim(0,1.1)
#ax.yaxis.set_tick_params(length=0)
#ax.xaxis.set_tick_params(length=0)
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
#for spine in ('top', 'right', 'bottom', 'left'):
#    ax.spines[spine].set_visible(False)
plt.show()

现在是带有一些图形用户界面的

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import IntVar

###############################################################################


def mainwindow():
    mainwindow = tk.Tk()
    mainwindow.geometry('350x350')
    
    tk.Label(mainwindow, text="enter parameters below").grid(row=1)
    
    getN = IntVar()
    geti0 = IntVar()
    getr0 = IntVar()
    getbeta = IntVar()
    getgamma = IntVar()

    
    tk.Label(mainwindow, text="N").grid(row=2)
    tk.Label(mainwindow, text="i0").grid(row=3)
    tk.Label(mainwindow, text="r0").grid(row=4)
    tk.Label(mainwindow, text="beta").grid(row=5)
    tk.Label(mainwindow, text="gamma").grid(row=6)
    
    e1 = tk.Entry(mainwindow,textvariable = getN).grid(row=2, column=1)
    e2 = tk.Entry(mainwindow,textvariable = geti0).grid(row=3, column=1)
    e3 = tk.Entry(mainwindow,textvariable = getr0).grid(row=4, column=1)
    e4 = tk.Entry(mainwindow,textvariable = getbeta).grid(row=5, column=1)
    e5 = tk.Entry(mainwindow,textvariable = getgamma).grid(row=6, column=1)
    
    solve = tk.Button(mainwindow, text='solve!', command=lambda: [values()]).grid(row=7, column=1, sticky=tk.W, pady=4)
    
    
    
    def values():
        
        readN = getN.get()
        readi0 = geti0.get()
        readr0 = getr0.get()
        readbeta = getbeta.get()
        readgamma = getgamma.get()
        
        intN = int(readN)
        inti0 = int(readi0)
        intr0 = int(readr0)
        intbeta = int(readbeta)
        intgamma = int(readgamma)
        
        
        # Total population, N.
        N = readN
        # Initial number of infected and recovered individuals, I0 and R0.
        I0, R0 = readi0, readr0
        # Everyone else, S0, is susceptible to infection initially.
        S0 = N - I0 - R0
        # Contact rate, beta, and mean recovery rate, gamma, (in 1/days).
        beta, gamma = readbeta, readgamma
        # A grid of time points (in days)
        t = np.linspace(0, 160, 160)

        # The SIR model differential equations.
        def deriv(y, t, N, beta, gamma):
            S, I, R = y
            dS = ((-beta * S * I) / N)
            dI = ((beta * S * I) / N) - (gamma * I)
            dR = (gamma * I)
            return dS, dI, dR
        
        # Initial conditions are S0, I0, R0
        # Integrate the SIR equations over the time grid, t.
        solve = odeint(deriv, (S0, I0, R0), t, args=(N, beta, gamma))
        S, I, R = solve.T
        
        # Plot the data on three separate curves for S(t), I(t) and R(t)
        fig = plt.figure(facecolor='w')
        ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
        ax.plot(t, S/1000, 'b', alpha=0.5, lw=2, label='Susceptible')
        ax.plot(t, I/1000, 'r', alpha=0.5, lw=2, label='Infected')
        ax.plot(t, R/1000, 'g', alpha=0.5, lw=2, label='Recovered with immunity')
        ax.set_xlabel('Time /days')
        ax.set_ylabel('Number (1000s)')
        ax.set_ylim(0,1.2)
        ax.yaxis.set_tick_params(length=0)
        ax.xaxis.set_tick_params(length=0)
        ax.grid(b=True, which='major', c='w', lw=2, ls='-')
        legend = ax.legend()
        legend.get_frame().set_alpha(0.5)
        for spine in ('top', 'right', 'bottom', 'left'):
            ax.spines[spine].set_visible(False)
        plt.show()



    mainwindow.mainloop()
    
mainwindow()

第一个给出预期的曲线图:

,但是对于图形用户界面,它提供了以下功能:

我的代码哪里出错了?解算系统的代码没有改变,我只是设置了它,以便参数采用我在弹出框中输入的值。Lambda函数是否出错?


解决方案

我尝试使用Beta和Gamma作为2/7的代码,1/7无法使其工作。

使用:

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import IntVar,StringVar,DoubleVar

###############################################################################


def mainwindow():
    mainwindow = tk.Tk()
    mainwindow.geometry('350x350')
    
    tk.Label(mainwindow, text="enter parameters below").grid(row=1)
    
    getN = IntVar()
    geti0 = IntVar()
    getr0 = IntVar()
    # getbeta = StringVar()
    # getgamma = StringVar()
    
    getbeta = DoubleVar()
    getgamma = DoubleVar()

    
    tk.Label(mainwindow, text="N").grid(row=2)
    tk.Label(mainwindow, text="i0").grid(row=3)
    tk.Label(mainwindow, text="r0").grid(row=4)
    tk.Label(mainwindow, text="beta").grid(row=5)
    tk.Label(mainwindow, text="gamma").grid(row=6)
    
    e1 = tk.Entry(mainwindow,textvariable = getN).grid(row=2, column=1)
    e2 = tk.Entry(mainwindow,textvariable = geti0).grid(row=3, column=1)
    e3 = tk.Entry(mainwindow,textvariable = getr0).grid(row=4, column=1)
    e4 = tk.Entry(mainwindow,textvariable = getbeta).grid(row=5, column=1)
    e5 = tk.Entry(mainwindow,textvariable = getgamma).grid(row=6, column=1)
    
    solve = tk.Button(mainwindow, text='solve!', command=lambda: [values()]).grid(row=7, column=1, sticky=tk.W, pady=4)
    
    
    
    def values():
        
        readN = getN.get()
        readi0 = geti0.get()
        readr0 = getr0.get()
        # readbeta = float(getbeta.get())
        # readgamma = float(getgamma.get())
        readbeta = (getbeta.get())
        readgamma =(getgamma.get())
        
        print('ppppppppppppp', readbeta,readgamma)
        
        intN = int(readN)
        inti0 = int(readi0)
        intr0 = int(readr0)
        intbeta = float(readbeta)
        intgamma = float(readgamma)
        
        
        # Total population, N.
        N = readN
        # Initial number of infected and recovered individuals, I0 and R0.
        I0, R0 = readi0, readr0
        # Everyone else, S0, is susceptible to infection initially.
        S0 = N - I0 - R0
        # Contact rate, beta, and mean recovery rate, gamma, (in 1/days).
        beta, gamma = readbeta, readgamma
        # A grid of time points (in days)
        t = np.linspace(0, 160, 160)

        # The SIR model differential equations.
        def deriv(y, t, N, beta, gamma):
            S, I, R = y
            dS = ((-beta * S * I) / N)
            dI = ((beta * S * I) / N) - (gamma * I)
            dR = (gamma * I)
            return dS, dI, dR
        
        # Initial conditions are S0, I0, R0
        # Integrate the SIR equations over the time grid, t.
        solve = odeint(deriv, (S0, I0, R0), t, args=(N, beta, gamma))
        S, I, R = solve.T
        
        # Plot the data on three separate curves for S(t), I(t) and R(t)
        fig = plt.figure(facecolor='w')
        ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
        ax.plot(t, S/1000, 'b', alpha=0.5, lw=2, label='Susceptible')
        ax.plot(t, I/1000, 'r', alpha=0.5, lw=2, label='Infected')
        ax.plot(t, R/1000, 'g', alpha=0.5, lw=2, label='Recovered with immunity')
        ax.set_xlabel('Time /days')
        ax.set_ylabel('Number (1000s)')
        ax.set_ylim(0,1.2)
        ax.yaxis.set_tick_params(length=0)
        ax.xaxis.set_tick_params(length=0)
        ax.grid(b=True, which='major', c='w', lw=2, ls='-')
        legend = ax.legend()
        legend.get_frame().set_alpha(0.5)
        for spine in ('top', 'right', 'bottom', 'left'):
            ax.spines[spine].set_visible(False)
        plt.show()



    mainwindow.mainloop()
    
mainwindow()

和0.28,0.14作为Beta和Gamma I:

希望知道如何使用分数作为输入的人会出现,

我尝试使用getbeta = StringVar()getgamma = StringVar()

readbeta = float(getbeta.get())readgamma =float(getgamma.get())

intbeta = float(readbeta)intgamma = float(readgamma)

但收到ValueError: could not convert string to float: '2/7'

对于readbeta = float(getbeta.get())

遇到eval要允许输入‘2/7’和‘1/7’作为beta和Gamma,请参阅How can I get the data from Entry in tkinter that can be used as function?

此处代码更新:

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import IntVar,StringVar,DoubleVar

###############################################################################


def mainwindow():
    mainwindow = tk.Tk()
    mainwindow.geometry('350x350')
    
    tk.Label(mainwindow, text="enter parameters below").grid(row=1)
    
    getN = IntVar()
    geti0 = IntVar()
    getr0 = IntVar()
    getbeta = StringVar()
    getgamma = StringVar()
    
    # getbeta = DoubleVar()
    # getgamma = DoubleVar()

    
    tk.Label(mainwindow, text="N").grid(row=2)
    tk.Label(mainwindow, text="i0").grid(row=3)
    tk.Label(mainwindow, text="r0").grid(row=4)
    tk.Label(mainwindow, text="beta").grid(row=5)
    tk.Label(mainwindow, text="gamma").grid(row=6)
    
    e1 = tk.Entry(mainwindow,textvariable = getN).grid(row=2, column=1)
    e2 = tk.Entry(mainwindow,textvariable = geti0).grid(row=3, column=1)
    e3 = tk.Entry(mainwindow,textvariable = getr0).grid(row=4, column=1)
    e4 = tk.Entry(mainwindow,textvariable = getbeta).grid(row=5, column=1)
    e5 = tk.Entry(mainwindow,textvariable = getgamma).grid(row=6, column=1)
    
    solve = tk.Button(mainwindow, text='solve!', command=lambda: [values()]).grid(row=7, column=1, sticky=tk.W, pady=4)
    
    
    
    def values():
        
        readN = getN.get()
        readi0 = geti0.get()
        readr0 = getr0.get()
        # readbeta = float(getbeta.get())
        # readgamma = float(getgamma.get())  
        readbeta = eval(getbeta.get(),{"builtins": {}})
        readgamma = eval(getgamma.get(), {"builtins": {}})
        
        print('ppppppppppppp', readbeta,readgamma)
        
        intN = int(readN)
        inti0 = int(readi0)
        intr0 = int(readr0)
        intbeta = float(readbeta)
        intgamma = float(readgamma)
        
        
        # Total population, N.
        N = readN
        # Initial number of infected and recovered individuals, I0 and R0.
        I0, R0 = readi0, readr0
        # Everyone else, S0, is susceptible to infection initially.
        S0 = N - I0 - R0
        # Contact rate, beta, and mean recovery rate, gamma, (in 1/days).
        beta, gamma = readbeta, readgamma
        # A grid of time points (in days)
        t = np.linspace(0, 160, 160)

        # The SIR model differential equations.
        def deriv(y, t, N, beta, gamma):
            S, I, R = y
            dS = ((-beta * S * I) / N)
            dI = ((beta * S * I) / N) - (gamma * I)
            dR = (gamma * I)
            return dS, dI, dR
        
        # Initial conditions are S0, I0, R0
        # Integrate the SIR equations over the time grid, t.
        solve = odeint(deriv, (S0, I0, R0), t, args=(N, beta, gamma))
        S, I, R = solve.T
        
        # Plot the data on three separate curves for S(t), I(t) and R(t)
        fig = plt.figure(facecolor='w')
        ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
        ax.plot(t, S/1000, 'b', alpha=0.5, lw=2, label='Susceptible')
        ax.plot(t, I/1000, 'r', alpha=0.5, lw=2, label='Infected')
        ax.plot(t, R/1000, 'g', alpha=0.5, lw=2, label='Recovered with immunity')
        ax.set_xlabel('Time /days')
        ax.set_ylabel('Number (1000s)')
        ax.set_ylim(0,1.2)
        ax.yaxis.set_tick_params(length=0)
        ax.xaxis.set_tick_params(length=0)
        ax.grid(b=True, which='major', c='w', lw=2, ls='-')
        legend = ax.legend()
        legend.get_frame().set_alpha(0.5)
        for spine in ('top', 'right', 'bottom', 'left'):
            ax.spines[spine].set_visible(False)
        plt.show()



    mainwindow.mainloop()
    
mainwindow()
它使用getbeta = StringVar()getgamma = StringVar(),然后readbeta = eval(getbeta.get(),{"builtins": {}})readgamma = eval(getgamma.get(), {"builtins": {}})

我在某个地方读到,eval在Python中的使用是不安全的,所以如果有人想要更好的解决方案,请与我们分享

最后设法在将输入发送到eval函数之前对其进行验证,因此代码应该是安全的(或不安全??请在此帮助); 新代码如下:

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import IntVar,StringVar,DoubleVar

###############################################################################
def callback_int(input):
      
    if input.isdigit():
        print(input)
        return True
                          
    elif input == "":
        print(input)
        return True
  
    else:
        print(input)
        return False

def callback_str(input, typez=None):
    
    if all([s.isdigit() or s =='/' for s in input]) and input.count('/') <= 1:
        print([s.isdigit() or s =='/' for s in input])
        # print(input)
        return True
                          
    elif all([s.isdigit() or s =='.' for s in input]) and input.count('.') <= 1:
        print([s.isdigit() or s =='.' for s in input])
        # print(input)
        return True

    else:
        print('no valid input : ',input)
        return False

def mainwindow():

    mainwindow = tk.Tk()
    mainwindow.geometry('350x350')
    
    tk.Label(mainwindow, text="enter parameters below").grid(row=1)
    
    getN = IntVar()
    geti0 = IntVar()
    getr0 = IntVar()
    getbeta = StringVar(mainwindow, value='0')
    getgamma = StringVar(mainwindow, value='0')
    
    # getbeta = DoubleVar()
    # getgamma = DoubleVar()

    
    tk.Label(mainwindow, text="N").grid(row=2)
    tk.Label(mainwindow, text="i0").grid(row=3)
    tk.Label(mainwindow, text="r0").grid(row=4)
    tk.Label(mainwindow, text="beta").grid(row=5)
    tk.Label(mainwindow, text="gamma").grid(row=6)
    
    e1 = tk.Entry(mainwindow,textvariable = getN)
    e1.grid(row=2, column=1)
    e2 = tk.Entry(mainwindow,textvariable = geti0)
    e2.grid(row=3, column=1)
    e3 = tk.Entry(mainwindow,textvariable = getr0)
    e3.grid(row=4, column=1)
    e4 = tk.Entry(mainwindow,textvariable = getbeta)
    e4.grid(row=5, column=1)
    e5 = tk.Entry(mainwindow,textvariable = getgamma)
    e5.grid(row=6, column=1)
    
    reg_int = mainwindow.register(callback_int)
    reg_str = mainwindow.register(callback_str)
    
    print(type(e4))
    
    e1.config(validate ="key", validatecommand =(reg_int, '%P'))
    e2.config(validate ="key", validatecommand =(reg_int, '%P'))
    e3.config(validate ="key", validatecommand =(reg_int, '%P'))
    e4.config(validate ="key", validatecommand =(reg_str, '%P'))
    e5.config(validate ="key", validatecommand =(reg_str, '%P'))
    
    solve = tk.Button(mainwindow, text='solve!', command=lambda: [values()]).grid(row=7, column=1, sticky=tk.W, pady=4)
    
    
    
    def values():
        
        readN = getN.get()
        readi0 = geti0.get()
        readr0 = getr0.get()
        # readbeta = float(getbeta.get())
        # readgamma = float(getgamma.get())  
        readbeta = eval(getbeta.get(),{"builtins": {}})
        readgamma = eval(getgamma.get(), {"builtins": {}})
        
        print('ppppppppppppp', readbeta,readgamma)
        
        intN = int(readN)
        inti0 = int(readi0)
        intr0 = int(readr0)
        intbeta = float(readbeta)
        intgamma = float(readgamma)
        
        
        # Total population, N.
        N = readN
        # Initial number of infected and recovered individuals, I0 and R0.
        I0, R0 = readi0, readr0
        # Everyone else, S0, is susceptible to infection initially.
        S0 = N - I0 - R0
        # Contact rate, beta, and mean recovery rate, gamma, (in 1/days).
        beta, gamma = readbeta, readgamma
        # A grid of time points (in days)
        t = np.linspace(0, 160, 160)

        # The SIR model differential equations.
        def deriv(y, t, N, beta, gamma):
            S, I, R = y
            dS = ((-beta * S * I) / N)
            dI = ((beta * S * I) / N) - (gamma * I)
            dR = (gamma * I)
            return dS, dI, dR
        
        # Initial conditions are S0, I0, R0
        # Integrate the SIR equations over the time grid, t.
        solve = odeint(deriv, (S0, I0, R0), t, args=(N, beta, gamma))
        S, I, R = solve.T
        
        # Plot the data on three separate curves for S(t), I(t) and R(t)
        fig = plt.figure(facecolor='w')
        ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
        ax.plot(t, S/1000, 'b', alpha=0.5, lw=2, label='Susceptible')
        ax.plot(t, I/1000, 'r', alpha=0.5, lw=2, label='Infected')
        ax.plot(t, R/1000, 'g', alpha=0.5, lw=2, label='Recovered with immunity')
        ax.set_xlabel('Time /days')
        ax.set_ylabel('Number (1000s)')
        ax.set_ylim(0,1.2)
        ax.yaxis.set_tick_params(length=0)
        ax.xaxis.set_tick_params(length=0)
        ax.grid(b=True, which='major', c='w', lw=2, ls='-')
        legend = ax.legend()
        legend.get_frame().set_alpha(0.5)
        for spine in ('top', 'right', 'bottom', 'left'):
            ax.spines[spine].set_visible(False)
        plt.show()

    
    mainwindow.mainloop()
    
mainwindow()

这允许Beta和Gamma将浮点数(即0.28)或分数(即2/7)作为输入插入Entry Widget框

开始享受Tkinter,这里是允许单选按钮控制输入类型的另一个改进版本:

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import IntVar,StringVar,DoubleVar

###############################################################################



def mainwindow():

    def switch():
        print(varb.get(), '    ')  #,varbR)
        # print(varbR)
        getbeta.set('0')
        getgamma.set('0')
        return
    
    def callback(input,typez=None, varb=None):
    
        value = mainwindow.getvar(varb)
        print(value)
        # varb.get()=varb.get()
        # uu = varb.get()
        # print(varb, uu)
        # print(varb.get())
        
        if typez == "int":
            if input.isdigit():
                # print(input)
                return True
                                
            elif input == "":
                # print(input)
                return True
        
            else:
                print(input, 'not allowed !!!!')
                return False
    
        if typez == "str":
            if value =='frc':
                if len(input) >=1  and input[0] == '/':
                    return False
                
                if all([s.isdigit() or s =='/' for s in input]) and input.count('/') <= 1:
                    # print([s.isdigit() or s =='/' for s in input])
                    # print(input)
                    return True
                else:
                    print('no valid input : ',input)
                    return False
            
            elif value =='flt':                   
                if all([s.isdigit() or s =='.' for s in input]) and input.count('.') <= 1:
                    # print([s.isdigit() or s =='.' for s in input])
                    # print(input)
                    return True
    
                else:
                    print('no valid input : ',input)
                    return False
            else:
                return False
    
    mainwindow = tk.Tk()
    mainwindow.geometry('550x350')
    
    tk.Label(mainwindow, text="enter parameters below").grid(row=1)
    
    getN = IntVar()
    geti0 = IntVar()
    getr0 = IntVar()
    getbeta = StringVar(mainwindow, value='0')
    getgamma = StringVar(mainwindow, value='0')
    
    # getbeta = DoubleVar()
    # getgamma = DoubleVar()

    
    tk.Label(mainwindow, text="N").grid(row=2)
    tk.Label(mainwindow, text="i0").grid(row=3)
    tk.Label(mainwindow, text="r0").grid(row=4)
    tk.Label(mainwindow, text="beta").grid(row=5)
    tk.Label(mainwindow, text="gamma").grid(row=6)
    
    e1 = tk.Entry(mainwindow,textvariable = getN)
    e1.grid(row=2, column=1)
    e2 = tk.Entry(mainwindow,textvariable = geti0)
    e2.grid(row=3, column=1)
    e3 = tk.Entry(mainwindow,textvariable = getr0)
    e3.grid(row=4, column=1)
    e4 = tk.Entry(mainwindow,textvariable = getbeta)
    e4.grid(row=5, column=1)
    e5 = tk.Entry(mainwindow,textvariable = getgamma)
    e5.grid(row=6, column=1)
    
    
    varb = StringVar(mainwindow, value='flt')
    # varbR=varb.get()
    
    
    rb1 = tk.Radiobutton(mainwindow, borderwidth=8,height=1, text='float   ' ,
                         variable = varb, value='flt', command=switch, justify="left")
    rb1.grid(row=5,column =2, rowspan=1, sticky="w")
    
    rb2 = tk.Radiobutton(mainwindow, borderwidth=8,height=1, text='fraction' ,
                         variable = varb, value='frc', command=switch ,justify="left")
    rb2.grid(row=6,column =2, rowspan=1, sticky="w")
    
    rb1.deselect()  # finche non attivo radiobutton non prende parametri
    
    
    
    
    reg = mainwindow.register(callback) 
    
    
    
    # e1.config(validate ="key", validatecommand =(reg, '%P', 'int',varbR))
    # e2.config(validate ="key", validatecommand =(reg, '%P', 'int',varbR))
    # e3.config(validate ="key", validatecommand =(reg, '%P', 'int',varbR))
    # e4.config(validate ="key", validatecommand =(reg, '%P', 'str',varbR))
    # e5.config(validate ="key", validatecommand =(reg, '%P', 'str',varbR))
    
    # e1.config(validate ="key", validatecommand =(reg, '%P', 'int',varb.get()))
    # e2.config(validate ="key", validatecommand =(reg, '%P', 'int',varb.get()))
    # e3.config(validate ="key", validatecommand =(reg, '%P', 'int',varb.get()))
    # e4.config(validate ="key", validatecommand =(reg, '%P', 'str',varb.get()))
    # e5.config(validate ="key", validatecommand =(reg, '%P', 'str',varb.get()))
    
    e1.config(validate ="key", validatecommand =(reg, '%P', 'int',varb))
    e2.config(validate ="key", validatecommand =(reg, '%P', 'int',varb))
    e3.config(validate ="key", validatecommand =(reg, '%P', 'int',varb))
    e4.config(validate ="key", validatecommand =(reg, '%P', 'str',varb))
    e5.config(validate ="key", validatecommand =(reg, '%P', 'str',varb))
    
    solve = tk.Button(mainwindow, text='solve!', command=lambda: [values()]).grid(row=7, column=1, sticky=tk.W, pady=4)
    
    
    

    def values():
        
        try:
            a = varb.get()
            print(a)
            
            readN = getN.get()
            readi0 = geti0.get()
            readr0 = getr0.get()
            # readbeta = float(getbeta.get())
            # readgamma = float(getgamma.get())
    
            # readbeta_ = getbeta.get()
            
            # if readbeta_[0] == '/':
            #     readbeta_ = readbeta_[1:]
            # readbeta = eval(readbeta_,{"builtins": {}})
            readbeta = eval(getbeta.get(),{"builtins": {}})
            readgamma = eval(getgamma.get(), {"builtins": {}})
            
            
            
            intN = int(readN)
            inti0 = int(readi0)
            intr0 = int(readr0)
            intbeta = float(readbeta)
            intgamma = float(readgamma)
            
            print('varb : ', varb.get(),
                  '
N : ', intN,
                  '
iO : ',inti0,
                  '
r0 : ',intr0,
                  '
beta : ',getbeta.get(),
                  '
gamma : ',getgamma.get())
            
            # Total population, N.
            N = readN
            # Initial number of infected and recovered individuals, I0 and R0.
            I0, R0 = readi0, readr0
            # Everyone else, S0, is susceptible to infection initially.
            S0 = N - I0 - R0
            # Contact rate, beta, and mean recovery rate, gamma, (in 1/days).
            beta, gamma = readbeta, readgamma
            # A grid of time points (in days)
            t = np.linspace(0, 160, 160)
    
            # The SIR model differential equations.
            def deriv(y, t, N, beta, gamma):
                S, I, R = y
                dS = ((-beta * S * I) / N)
                dI = ((beta * S * I) / N) - (gamma * I)
                dR = (gamma * I)
                return dS, dI, dR
            
            # Initial conditions are S0, I0, R0
            # Integrate the SIR equations over the time grid, t.
            solve = odeint(deriv, (S0, I0, R0), t, args=(N, beta, gamma))
            S, I, R = solve.T
            
            # Plot the data on three separate curves for S(t), I(t) and R(t)
            fig = plt.figure(facecolor='w')
            ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
            ax.plot(t, S/1000, 'b', alpha=0.5, lw=2, label='Susceptible')
            ax.plot(t, I/1000, 'r', alpha=0.5, lw=2, label='Infected')
            ax.plot(t, R/1000, 'g', alpha=0.5, lw=2, label='Recovered with immunity')
            ax.set_xlabel('Time /days')
            ax.set_ylabel('Number (1000s)')
            ax.set_ylim(0,1.2)
            ax.yaxis.set_tick_params(length=0)
            ax.xaxis.set_tick_params(length=0)
            ax.grid(b=True, which='major', c='w', lw=2, ls='-')
            legend = ax.legend()
            legend.get_frame().set_alpha(0.5)
            for spine in ('top', 'right', 'bottom', 'left'):
                ax.spines[spine].set_visible(False)
            plt.show()
            return
            
        except:
            print('maybe wrong values !!!!!!!!')
            return
        
    mainwindow.mainloop()
    
mainwindow()

相关文章