returnで値が正しく返ってきません。
Python
1def division(x,y): 2 boolean=False 3 x=x 4 y=y 5 try: 6 z=x/y 7 boolean=True 8 except ZeroDivisionError: 9 y+=1 10 division(x,y) 11 if boolean==True: 12 #print(z)は正しく値を返す 13 print(z) 14 #return zは値を返さない 15 return z 16division(2,0)
多くの方にご回答いただき誠にありがとうございました。おかげさまで書きたかったプログラムが書けました。下のコードのように書くと、引数を更新して正しく計算されるまで関数を呼び直すという動作ができます。
Python
1Z=[] 2def division(x,y): 3 boolean=False 4 x=x 5 y=y 6 try: 7 z=x/y 8 boolean=True 9 Z.append(z) 10 except ZeroDivisionError: 11 y+=1 12 division(x,y) 13 14division(2,0) 15print(Z[0])
また、これを応用して、反応器段数、原料濃度、溶液と冷媒の温度差を変数にとり連続混合槽型反応器のシミュレーションを行うコードを作成しました。(大学で学んでいる化学工学の問題です。かなりマニアックな領域なので化学工学に馴染みのない方が見るのは難しいかもしれません。)
Python
1""" 2与えられた定数(prepared constants) 3Gp: 生産量(product flow rate) [kg/s] 4ζ: 反応転化率(conversion) 5γ: 原料中のブタジエン重量割合(weight fraction of monomer in the feed) 6τ: 滞留時間(residence time) [s] 7ρ: 溶液密度(density of mixture) [kg/m^3] 8α: 反応器の高さ/直径比(ratio of height to diameter of the reactor) 9ΔH: ブタジエンの反応熱(heat of polymerization of butadiene) [J/mol] 10ΔT: 反応溶液と冷媒の温度差(temperature difference between reactant and coolant) [℃] 11λ: 溶液の熱伝導率(thermal conductivity of solution) [W/(m・K)] 12μ: 溶液の粘度(viscosity of solution) [Pa・s] 13Cp: 溶液の比熱(specific heat of solution) [J/(kg・K)] 14M: ブタジエンの分子量(molecular weight of butadiene) [g/mol] 15""" 16 17""" 18計算により求められる値(values obtained by calculation) 19v: 溶液の体積流量(volumetric flow rate of solution) [m^3/s] 20V: 反応器体積(volume of the reactor) [m^3] 21D: 反応器直径(diameter of the reactor) [m] 22Qp: 反応熱(heat of reaction) [J] 23P: 攪拌の消費電力(power consumption of stirring) [kW] 24h: 冷却装置の熱伝達率(heat transfer coefficiency of the coolant) [W/m^2・K] 25Nu: ヌッセルト数(Nusselt number) 26Pr: プラントル数(Prantdl number) 27Re: レイノルズ数(Reynols number) 28n: 1分あたり攪拌回数(number of stirring per minute) [/s] 29Np: 動力数(power number) 30""" 31 32""" 33値の記録に使用するリスト(list to record the value) 34P_log: i段目の反応器の消費電力を計算する際の挙動をi番目の要素に記録する 35 (record the behavior when calculating the power consumption of the i-th reactor in the i-th element) 36P_list: 反応器毎の攪拌消費電力を記録する(record the power consumption of each reactor) 37P_total: 最終的な計算結果を保存する(save the final result of calculation) 38""" 39 40""" 41例外処理(exception handling) 42排熱を処理しきれない場合は冷媒の温度を1度ずつ下げる 43(if the exhaust heat cannot be processed, lower the temperature of the refrigerant by 1 degree.) 44""" 45 46import math 47Gp = 0.729 48ζ = 0.60 49γ_1 = 0.05 50τ_1 = 18000 51ρ = 850 52α = 1.3 53ΔH = 72800 54λ = 0.128 55Cp = 1680 56M = 54.0 57V_1=514.6 #V_1=v*τ_1 58v_1=0.02859 #v_1=Gp/(ρ*γ_1*ζ) 59 60#反応速度定数を求める(find the reaction rate constant) 61ζ_total=ζ 62k=v_1*ζ_total/(V_1*(1-ζ_total)) 63 64P_log=[[]] 65P_list=[] 66P_total=[] 67 68def reactor(N, γ, ΔT): 69 P_log=[[]] 70 P_list=[] 71 N=N 72 γ=γ 73 ΔT=ΔT 74 #反応器のサイズを求める(find the size of each reactor) 75 τ=(1/k)*(1/math.pow(1-ζ_total,1/N)-1) 76 v=Gp/(ρ*γ*ζ_total) 77 V=v*τ 78 D=math.pow(4*V/(1.3*math.pi),1/3) 79 #各反応器の熱収支を計算する(calculate heat balance of each reactor) 80 ζ_each=1-math.pow(1-ζ_total,1/N) 81 try: 82 for i in range(N): 83 P_log.append([]) 84 P_log[i+1].append(0) 85 Qp=(ΔH/(M*0.001))*k*ρ*V*(1-ζ_each)**(i+1)*γ 86 h=Qp/(1.3*math.pi*(D**2)*ΔT) 87 Nu=h*D/λ 88 μ=0.0010*math.pow(50,1.7)*math.pow(1-(1-ζ_each)**(i+1),2.5)*math.exp(21*γ) 89 Pr=μ*Cp/λ 90 Re=math.pow((1/0.5)*Nu*math.pow(Pr,-1/3),3/2) 91 n=μ*Re/(ρ*(D/2)**2) 92 Np=14.6*math.pow(Re,-0.28) 93 P=0.0010*Np*ρ*(n**3)*((D/2)**5) 94 P_log[i+1].append(P) 95 while abs((P-P_log[i+1][len(P_log[i+1])-2])/P)>1.00*math.pow(10, -3): 96 h=(Qp+P*1000)/(1.3*math.pi*(D**2)*ΔT) 97 Nu=h*D/λ 98 Pr=μ*Cp/λ 99 Re=math.pow((1/0.5)*Nu*math.pow(Pr,-1/3),3/2) 100 n=μ*Re/(ρ*(D/2)**2) 101 Np=14.6*math.pow(Re,-0.28) 102 P=0.0010*Np*ρ*(n**3)*((D/2)**5) 103 P_log[i+1].append(P) 104 P_list.append(P_log[i+1][-1]) 105 P_total.append(sum(P_list)) 106 P_total.append(ΔT) 107 except OverflowError: 108 if ΔT<=50+273: 109 ΔT+=1 110 reactor(N, γ, ΔT) 111 else: 112 print("Warning: The feed is too thick. Reduce γ.") 113reactor(1, 0.07, 65) 114print(P_total)
Pythonならインデントをちゃんと揃えたソースじゃないと意味ないんで、質問文を編集してマークダウンでコードを記載しましょう。
ご指摘ありがとうございます。teratailの利用が初めてなものでインデントされていないことに気づいておりませんでした。大変失礼いたしました。
入力画面の上にあるボタン<code>を選択して、自動的に入力される
```ここに言語を入力
コード
```
の「コード」という場所にコードを書いてください。
このままではコードが読めないので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
解決済みなので、こちらにコメントさせていただきます。
もともとのサンプルコードの、exceptの中の、
division(x,y)
を
return division(x,y)
とすればよかったのではないかと思います。(再帰関数のイメージで)
外部の配列に値を追加して値を返すというやり方は、あんまりいい方法ではないと思います。
bsdfanさん、ありがとうございます。確かに、一応動きはしたものの汚いコードだなとは感じていました。except節にreturn function(x, y+1)を入れて動作を確認してみました。再帰関数など、あまり使い慣れていないので良く勉強させていただきます。
回答4件
あなたの回答
tips
プレビュー