In den beiden gezeigten Funktionen wird das globale `k` nicht verwendet, und wie die Fehlermeldung sehr deutlich sagt wird in `compute_energy()` ein `i` verwendet, welches nicht definiert ist. Ich würde mal behaupten das müsste auch jeweils `k` heissen und das `k` auf Modulebene kann weg. `Vebit0` von Modulebene wird auch gar nicht verwendet. Verwirrt aber in der Schreibweise, weil es ein Argument mit diesem Namen gibt.
Wenn das mit dem `i` gelöst ist, wird `phi` der nächste `NameError`. Die aufrufende Funktion hat ein Argument mit dem Namen — vielleicht sollte der Wert übergeben werden? Das gleiche gilt für `Qout`. Wobei das übergeben einer leeren Liste, die dann gefüllt wird, nicht schön ist. Wenn eine Funktion etwas zurückgeben soll, dann sollte man das mit ``return`` machen und nicht in dem man eine übergebene Liste mit Werten füllt. Wobei mir diese Liste sehr unsinnig erscheint. Wozu soll die gut sein? Je nach `condition` wird sie mit immer dem gleichen Wert `k` gefüllt und zwar `number` mal, oder sie bleibt leer. Und die `decision()`-Funktion macht dann auch überhaupt gar nichts mit dieser Liste. Das einige wofür die Liste ”benutzt” wird, ist ihre Länge als Schleifenzähler zu missbrauchen. *Das* kann man einfacher und direkter haben.
Bei `Lambda` ist ein Kommentar, den man sich sparen könnte wenn man den Namen komplett in Grossbuchstaben benennt, wie das bei Konstanten per Konvention üblich ist. Siehe Style Guide for Python Code.
Du lässt `s` von 1 bis `number` laufen und ziehst aber jedesmal wenn `s` benutzt wird 1 ab. Warum lässt Du es dann nicht gleich von 0 bis `number - 1` laufen, also einfach ``xrange(number)``. Wobei die Indirektion über einen Index wie gesagt unnötig ist und Module aus der Standardbibliothek dazu da sind sie zu benutzen. `math` und `string` importierst Du ja auch. Die könnte man schliesslich mit der gleichen Argumentation ablehnen.
Wenn man alles bis hierher berücksichtigt, dann bleibt bei der `compute_energy()` eine Schleife übrig die im Falle das `condition` unwahr ist, viel berechnet, aber immer nur `refresh()` aufruft. Ohne das die Berechnungen selber irgendeinen Effekt hätten. Ich kann mich des Eindrucks nicht erwehren, dass man dann `compute_energy()` gar nicht erst *aufrufen* bräuchte, die Bedingung für `condition` also nicht nur nicht *in* der Schleife, sondern eigentlich noch nicht einmal in der Funktion stehen sollte.
Der rückwärtsgerichtete Schrägstrich zur Fortsetzung einer logischen Zeile ist nicht nötig solange noch geöffnete Klammern nicht geschlossen sind. Dann weiss der Compiler das der Ausdruck noch nicht vollständig sein kann.
Bei der `decision()`-Funktion werden ganze sieben Argumente überhaupt nicht verwendet.
Auch in dieser Funktion sind die Prüfungen teilweise an der falschen Stelle falls `refresh()` nichts an den Bedingungen ändert und nur aufgerufen werden muss um zum Beispiel die GUI am laufen zu halten. Der Wert von `checks` ändert sich innerhalb der Schleife nicht. Der Wert des `all()`-Ausdrucks von `condition` den man aus `compute_energy()` vor den Aufruf von `compute_energy()` ziehen kann, wird in der Schleife nicht verändert, kann also auch davor gezogen werden.
Ich lande dann bei ungefähr so etwas hier:
Code: Alles auswählen
from itertools import count, islice, izip
from math import cos, pi as PI, sin, sqrt
BETA_S = 0.041
G_EFF = 0.067539767
LAMBDA = 3.724129913
VEBIT = None # TODO
# ...
# TODO If `beta_s` is not really variable, remove the argument and replace it
# by a constant.
def compute_energy(number, k, cavlist, phi, v_ebit0, factors, beta_s):
table = display.getWidget('Table').getTable()
e_0 = 600
for i, cav, factor in islice(izip(count(), cavlist, factors), number):
# 10**(-16), because keV
beta = sqrt(2 * e_0 * 1.602177e-16 / 1.6726e27) / 299792458
tmp = PI * G_EFF / (beta * LAMBDA)
T = sin(tmp) / tmp * sin(PI * beta_s / (2 * beta))
e_0 = (27.98 * cav * k * cos(phi) * T) / (factor * e_0)
set_cells(table, i, k, v_ebit0, number, e_0)
def decision(
phi, q_in, A, v_ebitmax, checks, number, cavlist, factors, cavmax_css
):
if (
# Ist possibility: fixed number, compute Energy
checks == [1, 0, 0, 1]
and all(t < u for t, u in izip(cavlist, cavmax_css))
):
for i in xrange(1 , q_in + 1):
v_ebit = 12 * A / i
if v_ebit < v_ebitmax:
compute_energy(number, i, cavlist, phi, v_ebit, factors, BETA_S)
Und man könnte (und sollte IMHO) Berechnung und Darstellung besser trennen. Etwas was `compute_energy()` heisst sollte nur das tun: Die Energiewerte berechnen. Und sie zurückgeben und nicht selbst anzeigen. Denn diese Funktion hat ja auch ein Argument was nur übergeben wird weil es in `set_cells()` verwendet wird und nicht weil man es tatsächlich zur Berechnung der Energiewerte brauchen würde.