2017-04-13 26 views
1

我正在編寫一個Python程序,它將執行the power triangle的計算,並且需要一些幫助來確定我的方法是選擇方程式的效率最高。根據給定輸入執行觸發計算

如果你不熟悉,這只是餘弦定律的應用。在五個可能的輸入中,我只需要兩個輸入,並且可以計算其他輸入。我也在實現matplotlib來顯示輸出,但現在,我只想讓數學運行。

我正在使用tkinter來獲取輸入和字典來存儲輸入。

fields = 'kW', 'kVA', 'kVAR', 'PF', 'Theta' 
calcInputs = {} 

def fetch(entries): 
    for entry in entries: 
     field = entry[0] 
     text = entry[1].get() # User input for each textbox 
     print('%s: %s' % (field, text)) # Print to stdout with name 
     if len(text) == 0: 
      pass # Don't update dictionary with nulls 
     else: 
      calcInputs.update({field:text}) # name : value updated to dictionary 

後來我存儲每個字典條目爲變量,我將轉換爲浮動後。

kW = calcInputs.get('kW') 
kVA = calcInputs.get('kVA') 
kVAR = calcInputs.get('kVAR') 
pF = calcInputs.get('PF') 
theta = calcInputs.get('Theta') 

這是一個讓我知道哪些是空的佔位符:

for i in calcInputs: 
    if i is not None: 
     print({i}) 
    else: 
     pass 

讓我的一個功能諾內斯的每個組合,並調用相應的一個基於我有什麼樣的數據?這似乎是最直接的,但我覺得必須有更好的方法。

回答

3

讓我們做一些你的代碼多一點「Python化」首。您寫道:

calcInputs = {} 

def fetch(entries): 
    for entry in entries: 
     field = entry[0] 
     text = entry[1].get() # User input for each textbox 
     print('%s: %s' % (field, text)) # Print to stdout with name 
     if len(text) == 0: 
      pass # Don't update dictionary with nulls 
     else: 
      calcInputs.update({field:text}) # name : value updated to dictionary 

這樣做的問題在於calcInputs將是持久的 - 也就是說,它會呆在身邊,直到下一個週期(假設有多個週期),因此可以從一個時間暫時保留數據下一個。讓我們初始化函數中的空字典,所以我們總是從一個乾淨的石板開始。 (注:如果輸入框保持其價值,從週期到週期,這跟我沒關係 - 用戶可以看到它,如果她想清洗。)

def fetch(entries): 
    inputs = {} 

這下位似乎還好,雖然我不熟悉Python下的TkInter:

for entry in entries: 
     field = entry[0] 
     text = entry[1].get() 

這顯然是調試代碼 - 保持它,直到你很高興。

 print('%s: %s' % (field, text)) # Print to stdout with name 

接下來的部分是「錯了」。看起來你來自Java--這是一門偉大的語言。但由於"truthiness"和語法糖,我們可以做一些更清潔的事情。在Python中,字符串是「真」,如果他們不爲空,並且字典可以使用dict[key]符號索引:

 if text: 
      inputs[field] = text 

就是這樣。但是,由於我們不使用全局變量,讓我們繼續前進,返回結果:

return inputs 

現在,你可以打電話獲取和使用結果。或者,如果您願意,您可以將結果重新分配給全局:

global calcInputs 
    calcInputs = inputs # instead of return inputs 

一旦您有輸入,請繼續處理它們。你有一個問題,因爲你實際上並不知道你得到了哪些輸入。一個簡單的方法就是一系列的if/then涉及兩個值,報表,我們可以定義一些常量能夠更方便(以免必須鍵入引號的所有時間):

KW = 'kW' 
PF = 'PF' 
THETA = 'Theta' 
: 

calcInputs = fetch(entries) # Or however you choose to init calcInputs 

if KW in calcInputs and PF in calcInputs: 
    triangle_from_KWPF(calcInputs) 
elif KW in calcInputs and THETA in calcInputs: 
    triangle_from_KWTHETA(calcInputs) 
elif ... 
    : 
else: 
    report_error("You didn't provide enough inputs! I need at least 2!") 

Python的in運營商適用於詞典並設置爲關鍵字或成員資格測試,字符串作爲子字符串搜索,並列爲線性掃描。

這種方法是@Alden所描述的二進制樣式序列,其中的一切都是拼寫出來的。

另一種方式是創建一個編碼的給定參數的哈希的對象,並使用字典派遣他們:

given_keys = [] 

for key in sorted(fields): 
    if key in calcInputs: 
     given_keys.append(key) 
     if len(given_keys) == 2: 
      break 
else: # Fell through 
    report_error("You didn't provide enough inputs! I need at least 2!") 

# given_keys has 2 field-names in it. Concatenate them. 
calc_key = '_'.join(given_keys) 

# calc_key looks like "KW_Theta" 

dispatch = { # dictionary: string -> function 
    'KW_Theta' : triangle_from_KW_Theta, 
    'KW_PF' : triangle_from_KW_PF, 
    # etc.... 
} 

calc_function = dispatch[calc_key] 

calc_function(calcInputs) 

注:for...else是一個有效的Python形式。當for循環耗盡其迭代時它運行else子句。所以它非常適合在中間有一個break語句的塊。

+0

修復了calcInput沒有清除的問題,謝謝。 我實際上比Java更熟悉Python(只在大學中使用過Java),但顯然不是那麼好。 「如果文本:」部分基本上是這樣,雖然是真的,我想呢?依靠內在屬性? 哈希/連接方法似乎是最緊湊和可讀的,所以我想我會嘗試實現。謝謝! –

+0

對於獎勵積分,如果你正確選擇你的函數名,那麼'globals()'返回的字典可以是調度字典 - 只需計算實際函數名,在當前模塊中查找並調用它! –

1

您可以使用簡單的二進制映射來查看您的輸入是什麼並應用正確的功能。這裏有一個例子:

kW = input('kW') 
kVA = input('kVA') 
kVAR = input('kVAR') 
pF = input('PF') 
theta = input('Theta') 

inputs = (kW, kVA, kVAR, pF, theta) 

def cmp(t): 
    z = zip(inputs, t) 
    z = [a and b for a, b in z] 
    return sum(z) == sum(t) # 2 

if cmp((1,1,0,0,0)): 
    pass # kW and kVA given 
elif cmp((1,0,1,0,0)): 
    pass # kW and kVAR given 
elif cmp((1,0,0,1,0)): 
    pass 
elif cmp((1,0,0,0,1)): 
    pass 
elif cmp((0,1,1,0,0)): 
    pass 
elif cmp((0,1,0,1,0)): 
    pass 
elif cmp((0,1,0,0,1)): 
    pass 
elif cmp((0,0,1,1,0)): 
    pass 
elif cmp((0,0,1,0,1)): 
    pass 
elif cmp((0,0,0,1,1)): 
    pass 
+0

看起來很緊湊,但我擔心我會在未來更新它。我只有在完成特定任務時才進行編碼,然後通常不會在幾個月內更新工具。 雖然我欣賞另一種方式來完成某件事的教訓! –