嗨,您尝试了将 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 我得到:
希望知道如何使用分数作为输入的人会出现,
我尝试使用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)作为输入小部件框
开始享受 Tkinter,这里是另一个改进版本,其中 RadioButtons 控制允许的输入类型:
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(),
'\nN : ', intN,
'\niO : ',inti0,
'\nr0 : ',intr0,
'\nbeta : ',getbeta.get(),
'\ngamma : ',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()