我在Tkinter(tennisGUI)中创建了一个GUI,用于获取“用户输入”并提供另一个python脚本(tennisTotal.py)“输出。
一切都有效,除了我无法上班的一件事。如何在其他脚本中获得“用户输入”(tennisTotal.py。
例如,在GUI中有一个字段“Service stats Serving player”。我希望这个字段的输入成为“tennisTotal.py”脚本
对于剧本的任何评论和建议也欢迎,因为我对pythong很新。
tennisGUI脚本
from Tkinter import *
import sys
sys.path.append("C:\Users\Magali\Desktop\Tennis\tennisTotal.py")
class App(Frame):
def run_script(self):
sys.stdout = self
try:
del(sys.modules["tennisTotal"])
except:
# Yeah, it's a real ugly solution...
pass
import tennisTotal
tennisTotal
sys.stdout = sys.__stdout__
def build_widgets(self):
self.text1 = Text(self, height=8, width=25, font=('time', 9, 'italic'))
self.text1.grid(row=13, column=6, columnspan=2, rowspan=50, padx=10, pady=10)
Label(self, text="Players & Stats", font="Verdana 10 bold").grid(row=1, column=2, columnspan=3)
Label(self, text="Serving Player").grid(row=2, column=2, sticky='w')
Label(self, text="Receiving Player").grid(row=3, column=2, sticky='w')
Label(self, text="Scoring", font="Verdana 10 bold").grid(row=13, column=2, columnspan=3)
Label(self, text="Game Score Serving Player").grid(row=14, column=2, sticky='w')
Label(self, text="Game Score Receiving Player").grid(row=15, column=2, sticky='w')
Label(self, text="Set Score Serving Player").grid(row=16, column=2, sticky='w')
Label(self, text="Set Score Receiving Player").grid(row=17, column=2, sticky='w')
Label(self, text="Stats", font="Verdana 10 bold").grid(row=4, column=2, columnspan=3)
Label(self, text="Service stats Serving Player").grid(row=5, column=2, sticky='w')
Label(self, text="Service stats Receiving Player").grid(row=6, column=2, sticky='w')
Label(self, text="Return stats Serving Player").grid(row=7, column=2, sticky='w')
Label(self, text="Return stats Receiving Player").grid(row=8, column=2, sticky='w')
e1 = Entry(self)
e2 = Entry(self)
e3 = Entry(self)
e4 = Entry(self)
e5 = Entry(self)
e6 = Entry(self)
e7 = Entry(self)
e8 = Entry(self)
e9 = Entry(self)
e10 = Entry(self)
e1.insert(10, "Novak Djokovic")
e2.insert(10, "Andy Murray")
e3.insert(10, "30")
e4.insert(10, "15")
e5.insert(10, "2")
e6.insert(10, "1")
e7.insert(10, "75.2%")
e8.insert(10, "72.2%")
e9.insert(10, "30.5%")
e10.insert(10, "27.5%")
e1.grid(row=2, column=4)
e2.grid(row=3, column=4)
e3.grid(row=14, column=4, padx=10)
e4.grid(row=15, column=4)
e5.grid(row=16, column=4)
e6.grid(row=17, column=4)
e7.grid(row=5, column=4)
e8.grid(row=6, column=4)
e9.grid(row=7, column=4)
e10.grid(row=8, column=4)
Button(self, text='Run', command=self.run_script).grid(row=12, column=2, columnspan=6, ipadx=100, pady=15)
def write(self, txt):
self.text1.insert(INSERT, txt)
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.build_widgets()
root = Tk()
app = App(master=root)
app.mainloop()
tennisTotal script - >前11行是我想要的“用户输入”形式的tennisGUI脚本。
s_point=0.6
v_game_point=0
w_game_point=0
v_tiebreak=0
w_tiebreak=0
returnpoint_server=0.3
v_games_in_set=0
w_games_in_set=0
v_sets_won=0
w_sets_won=0
best_of=5
def fact(x):
if x in[0, 1]:
return 1
r = 1
for a in range(1, (x+1)):
r = r*a
return r
def ch(a, b):
return fact(a)/(fact(b)*fact(a-b))
def gameOutcome(s, a, b):
return ch((a+b), a)*(s**a)*((1-s)**b)*s
# Game Probability
def gameProb(s=s_point, v=v_game_point, w=w_game_point):
# function calculates the probability of server winning
# a single game, given p(winning any given point) [s],
# and the current point score.
# v, w = current game score, where love = 0, 15 = 1, etc.
# - e.g. 30-15 is v=2, w=1
# check if game is already over:
if v >= 4 and (v-w) >= 2:
return 1
elif w >= 4 and (w-v) >= 2:
return 0
else:
pass
# if deuce or ad score e.g. 5-4, reduce to e.g. 3-2
while True:
if (v+w) > 6:
v -= 1
w -= 1
else:
break
# specific probabilities:
if w == 0:
w0 = gameOutcome(s, 3-v, 0)
else:
w0 = 0
if w <= 1:
w15 = gameOutcome(s, 3-v, 1-w)
else:
w15 = 0
if w <= 2:
w30 = gameOutcome(s, 3-v, 2-w)
else:
w30 = 0
if v == 4:
wAd, lAd = s, 0
d = 1-s
elif w == 4:
wAd, lAd = 0, 1-s
d = s
else:
wAd, lAd = 0, 0
a = 3 - v
b = 3 - w
d = ch((a+b), a)*(s**a)*((1-s)**b)
if v <= 2:
l30 = gameOutcome((1-s), 3-w, 2-v)
else:
l30 = 0
if v <= 1:
l15 = gameOutcome((1-s), 3-w, 1-v)
else:
l15 = 0
if v == 0:
l0 = gameOutcome((1-s), 3-w, 0)
else:
l0 = 0
# given d = prob of getting to deuce,
# math to divide up further outcomes
denom = s**2 + (1-s)**2
wd = (d*(s**2))/denom
ld = (d*((1-s)**2))/denom
win = w0 + w15 + w30 + wd + wAd
lose = l0 + l15 + l30 + ld + lAd
return win
# Tiebreak Probability
def tiebreakProb(s=s_point, t=returnpoint_server, v=v_tiebreak, w=w_tiebreak, p=7):
# calculate the probability that the current server wins a best-of-p
# tiebreak.
# s = p(server wins service point)
# t = p(current server wins return point)
# v, w = current score
# check if tiebreak is already over:
if v >= p and (v-w) >= 2:
return 1
elif w >= p and (w-v) >= 2:
return 0
else:
pass
# re-adjust so that point score is not higher than p;
# e.g., if p=7 and score is 8-8, adjust to 6-6, which
# is logically equivalent
while True:
if (v+w) > 2*(p-1):
v -= 1
w -= 1
else:
break
outcomes = {}
# track probability of each possible score
# this is messy and probably not optimal, figuring out
# how many points remain, and how many are on each
# player's serve:
for i in range((p-1)):
remain = p + i - v - w
if remain < 1:
continue
else:
pass
if remain % 2 == 1:
if (v+w) % 2 == 0:
if (remain-1) % 4 == 0:
svc = (remain+1)/2
ret = (remain-1)/2
else:
svc = (remain-1)/2
ret = (remain+1)/2
else:
if (remain-1) % 4 == 0:
svc = (remain+1)/2
ret = (remain-1)/2
else:
svc = (remain+1)/2
ret = (remain-1)/2
else:
if (v+w) % 2 == 0:
svc, ret = remain/2, remain/2
else:
svc, ret = (remain-2)/2, (remain-2)/2
if remain % 4 == 0:
svc += 1
ret += 1
else:
svc += 2
# who serves the last point?
if (v+w) % 2 == 0:
if (remain % 4) in [0, 1]:
final = s
svc -= 1
else:
final = t
ret -= 1
else:
if (remain % 4) in [3, 0]:
final = t
ret -= 1
else:
final = s
svc -= 1
pOutcome = 0
for j in range(svc+1):
for k in range(ret+1):
if (j+k) == (p - 1 - v):
m = svc - j
n = ret - k
pr = (s**j)*(t**k)*((1-s)**m)*((1-t)**n)*ch(svc, j)*ch(ret, k)*final
pOutcome += pr
else:
continue
key = str(p) + str(i)
outcomes[key] = pOutcome
if remain % 2 == 1:
if (v+w) % 2 == 0:
if (remain-1) % 4 == 0:
svc = (remain+1)/2
ret = (remain-1)/2
else:
svc = (remain-1)/2
ret = (remain+1)/2
else:
if (remain-1) % 4 == 0:
svc = (remain+1)/2
ret = (remain-1)/2
else:
svc = (remain+1)/2
ret = (remain-1)/2
else:
if (v+w) % 2 == 0:
svc, ret = remain/2, remain/2
else:
svc, ret = (remain-2)/2, (remain-2)/2
if remain % 4 == 0:
svc += 1
ret += 1
else:
svc += 2
# probability of getting to (p-1)-(p-1) (e.g. 6-6)
final = 1
x = 0
for j in range(svc+1):
for k in range(ret+1):
if (j+k) == (p - 1 - v):
m = svc - j
n = ret - k
pr = (s**j)*(t**k)*((1-s)**m)*((1-t)**n)*ch(svc, j)*ch(ret, k)*final
x += pr
else:
continue
outcomes['+'] = (x*s*t)/((s*t) + (1-s)*(1-t))
# add up all positive outcomes
wtb = 0
for z in outcomes:
wtb += outcomes[z]
return wtb
# Set Probability
def setOutcome(final, sGames, rGames, vw, g, h):
pOutcome = 0
for j in range((sGames+1)):
for k in range((rGames+1)):
if (j + k) == (6 - 1 - vw):
m = sGames - j
n = rGames - k
p = (g**j)*(h**k)*((1-g)**m)*((1-h)**n)*ch(sGames, j)*ch(rGames, k)*final
pOutcome += p
else:
continue
return pOutcome
def setGeneral(s=s_point, u=returnpoint_server, v=v_games_in_set, w=w_games_in_set, tb=1):
# calculate the probability of the current server winning
# a 6-game, tiebreak set, given prob. of server winning any
# given service point (s) or return point (u), and the current
# game score (v, w)
# get prob of current server winning a service game:
g = gameProb(s)
# and current server winning a return game:
h = gameProb(u)
# is set over?
if tb:
if v == 7:
return 1
elif w == 7:
return 0
elif v == 6 and (v-w) > 1:
return 1
elif w == 6 and (w-v) > 1:
return 0
else:
pass
else:
if v >= 6 and (v-w) > 1:
return 1
elif w >= 6 and (w-v) > 1:
return 0
else:
pass
# if not over, re-adjust down to no higher than 6-6
while True:
if (v+w) > 12:
v -= 1
w -= 1
else:
break
# if no tiebreak, chance that server wins set is ratio
# of server's prob of winning
# two games in a row to returner's prob of winning two games in a row
if not tb:
deuceprob = (g*h)/((g*h) + (1-g)*(1-h))
outcomes = {}
# special cases, 11 games or more already
if (v+w) == 12:
if tb:
tp = tiebreakProb(s, u)
outcomes['76'] = tp
outcomes['67'] = 1 - tp
else:
outcomes['75'] = deuceprob
outcomes['57'] = 1-deuceprob
elif (v+w) == 11:
if tb:
tp = tiebreakProb((1-u), (1-s))
if v == 6:
outcomes['75'] = g
x = (1-g)
outcomes['76'] = x*(1 - tp)
outcomes['67'] = x*tp
else:
outcomes['57'] = 1-g
x = g
outcomes['76'] = x*(1 - tp)
outcomes['67'] = x*tp
else:
if v == 6:
outcomes['75'] = g
outcomes['57'] = 0
f = 1 - g
else:
outcomes['57'] = 1-g
outcomes['75'] = 0
f = g
outcomes['75'] += f*deuceprob
outcomes['57'] += f*(1-deuceprob)
else:
for i in range(5):
t = 6 + i - v - w
if t < 1:
continue
if t % 2 == 0:
final = h
sGames = t/2
rGames = sGames - 1
else:
final = g
sGames = (t-1)/2
rGames = (t-1)/2
pOutcome = setOutcome(final, sGames, rGames, v, g, h)
key = '6' + str(i)
outcomes[key] = pOutcome
# loss probabilities
# this section isn't necessary, but I wrote it for informal
# testing purposes
for i in range(5):
t = 6 + i - v - w
if t < 1:
continue
if t % 2 == 0:
final = 1-h
sGames = t/2
rGames = sGames - 1
else:
final = 1-g
sGames = (t-1)/2
rGames = (t-1)/2
pOutcome = setOutcome(final, sGames, rGames, w, (1-g), (1-h))
key = str(i) + '6'
outcomes[key] = pOutcome
t = 10 - v - w
if t % 2 == 0:
sGames = t/2
rGames = t/2
else:
sGames = (t-1)/2 + 1
rGames = (t-1)/2
f = setOutcome(1, sGames, rGames, v, g, h)
if tb == 1:
outcomes['75'] = f*g*h
outcomes['57'] = f*(1-g)*(1-h)
x = f*g*(1-h) + f*(1-g)*h
if (v+w) % 2 == 0:
tp = tiebreakProb(s, u)
else:
tp = tiebreakProb(u, s)
outcomes['76'] = x*tp
outcomes['67'] = x - x*tp
else:
outcomes['75'] = f*deuceprob
outcomes['57'] = f*(1-deuceprob)
win = 0
for o in outcomes:
if o in ['60', '61', '62', '63', '64', '75', '76']:
win += outcomes[o]
else:
pass
return win
#Match Probability
def matchGeneral(e, v=0, w=0, s=3):
# calculates probability of winning the match
# from the beginning of a set
# e is p(winning a set)
# v and w is current set score
# s is total number of sets ("best of")
towin = (s+1)/2
left = towin - v
if left == 0:
return 1
remain = s - v - w
if left > remain:
return 0
win = 0
for i in range(left, (remain+1)):
add = ch((i-1), (left-1))*(e**(left-1))*((1-e)**(i-left))*e
win += add
return win
def matchProb(s=s_point, t=returnpoint_server, gv=v_game_point, gw=w_game_point, sv=v_games_in_set, sw=w_games_in_set, mv=v_sets_won, mw=w_sets_won, sets=best_of):
# calculates probability of winning a match from any given score,
# given:
# s, t: p(server wins a service point), p(server wins return point)
# gv, gw: current score within the game. e.g. 30-15 is 2, 1
# sv, sw: current score within the set. e.g. 5, 4
# mv, mw: current score within the match (number of sets for each player)
# v's are serving player; w's are returning player
# sets: "best of", so default is best of 3
a = gameProb(s)
b = gameProb(t)
c = setGeneral(s, t)
if gv == 0 and gw == 0:
if sv == 0 and sw == 0:
return matchGeneral(c, v=mv, w=mw, s=sets)
else:
sWin = setGeneral(a, b, s, t, v=sv, w=sw)
sLoss = 1 - sWin
elif sv == 6 and sw == 6:
sWin = tiebreakProb(s, t, v=gv, w=gw)
sLoss = 1 - sWin
else:
gWin = gameProb(s, v=gv, w=gw)
gLoss = 1 - gWin
sWin = gWin*(1 - setGeneral((1-b), (1-a), (1-t), (1-s), v=sw, w=(sv+1)))
sWin += gLoss*(1 - setGeneral((1-b), (1-a), (1-t), (1-s), v=(sw+1), w=sv))
sLoss = 1 - sWin
mWin = sWin*matchGeneral(c, v=(mv+1), w=mw, s=sets)
mWin += sLoss*matchGeneral(c, v=mv, w=(mw+1), s=sets)
return mWin, sLoss
print "Server Game = ""{0:.2%}".format(gameProb())
print "Receiver Game = ""{0:.2%}".format(1-gameProb())
print "Server Tiebreak = ""{0:.2%}".format(tiebreakProb())
print "Receiver Tiebreak = ""{0:.2%}".format(1-tiebreakProb())
print "Server Set = ""{0:.2%}".format(setGeneral())
print "Receiver Set = ""{0:.2%}".format(1-setGeneral())
print "Server Match = ""{0:.2%}".format(matchProb())
print "Receiver Match= ""{0:.2%}".format(1-matchProb())