top-down-design: Funktionen allgemein definieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Eine allgemeine Frage als Programmierneuling. Ich benuetze fuer das Programm, an dem ich schreibe das top- down design. Nun moechte ich aber eine vorgefertigte Funktion abhaengig von vorher nicht definierten Parametern definieren und erst spaeter ausfuehren(mit bestimmten Parametern).
Ich dachte, das muesste so gehen:

Code: Alles auswählen

def main():
    Qcont, A1, Around, nameiso, abu, qdivbya, abu2, information = readcontaminationfile()
    cavmaxCSS, cavmaxreal, factor = readcavmaxfile()
    betaS, geff, Lambda, phi, Qin, A, E, Ein, minimumf, maximumf, Vebitmax, check2, check1, check3, check4, checks,\
           number, minnumber, maxnumber, diffqa0, cavlist, combo = getInputs(A1, Around, nameiso, Qcont, factor)
    alarm(cavlist, cavmaxCSS, number)
    decision(betaS, geff, Lambda, phi, Qin, A, E, Ein, minimumf, maximumf, Vebitmax, check2, check1, check3, check4, checks,\
             number, minnumber, maxnumber, cavlist, factor, cavmaxCSS, cavmaxreal)
    clickrow(table1, Qcont, A1, nameiso, abu, qdivbya, abu2, information, A, diffqa0, check3, check4, factor, \
             betaS, geff, Lambda, phi, minimumf, maximumf, cavmaxreal, combo)
def readcavmaxfile():
do something
def readcontaminationfile():
do something
def getInputs(A1, Around, nameiso, Qcont, factor):
do something
def alarm(cavlist, cavmaxCSS, number):
    for i in range(1, number + 1):
        if number >= i and cavlist[i-1] > cavmaxCSS[i-1]:
            display.getWidget("cav" + str(i)).setPropertyValue("foreground_color",RED)

#define function that writes values in cells

def set_cells(table1, row, *args):
    for i, value in enumerate(args):
        table1.setCellText(row, i, str(value))
        
# define function that refreshes output
def refresh():        
    table.setContent([[" ", " ", " ", " "]])
    table1.setContent([[" ", " ", " ", " ", " ", " "]])
 def computeEnergy(number):    
    v = sqrt(2*600*1.602177*10**(-16)/1.6726*10**27)
    c = 299792458.0
    beta = v/c
    T = sin(pi*geff/(beta*Lambda))/(pi*geff/(beta*Lambda))*sin(pi*betaS/(2*beta))
    E0 = (600*A + i*27.98*cavlist[0]/factor[0]*T*cos(phi))/A
# go from 1,6, because you do not want cavlist[0], factor[0] included
    for k in range(1,number + 1):
# 10**(-16), because keV
        v = sqrt(2*E0*1.602177*10**(-16)/1.6726*10**27)         
        beta = v/c
        T = sin(pi*geff/(beta*Lambda))/(pi*geff/(beta*Lambda))*sin(pi*betaS/(2*beta))
        E0 = E0 + (i*27.98*cavlist[k]/factor[k])/A*T*cos(phi)
        if all(t<u for t, u in zip(cavlist, cavmaxCSS)) and Vebit < Vebitmax:
            Qout.append(i)
            set_cells(table, len(Qout) - 1, i, Vebit, number, E0)
        else:
            refresh()
...
...
...
ruft die restlichen Funktionen in main auf und macht etwas
if __name__ == '__main__': main()
nun haengt es sich aber an der computeEnergy-Funktion auf.. das Programm gibt einen NameError: global name 'geff' is not defined zurueck, da ich die Parameter nicht verwenden kann ohne sie vorher zu definieren..
Vielen Dank im Vorraus!
Gruss,
Peter
BlackJack

@peter99: Das Du ständig betonst, dass Du das Programm Top-Down entworfen hast, ist glaube ich nicht wirklich wichtig.

Ich weiss auch nicht was man da jetzt grossartig sagen soll, ausser dem offensichtlichem: Wenn Du Namen in der Funktion verwendest, müssen die vorher definiert werden. Also solange es sich nicht um Konstanten handelt, sollten sie als Argumente übergeben werden.

Deine Funktionen nehmen teilweise echt viele Argumente entgegen, beziehungsweise geben viele Werte zurück. Ich würde die ja versuchen irgendwie sinnvoll zu Objekten zusammen zu fassen, damit es übersichtlicher und verständlicher wird. `collections.namedtuple` könnte da nützlich sein, oder man schreibt eigene Klassen wenn mit den Werten auch Operationen verbunden sind.

In der `computeEnergy()` ist ziemlich deutlich kopieren und einfügen passiert. Das sollte man vermeiden. Da kann man sicher eine Funktion heraus ziehen.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

danke, entschuldige, ja, sowas in die Richtung versuche ich gerade, aber bis dato ist mein Erfolg beim simplifizieren etwas beschraenkt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@peter99: Gegenfrage: Wieso ist es denn so kompliziert geworden? Fängst Du wirklich an und schreibst so etwas:

Code: Alles auswählen

def some_func(a, b, c, d, e, f, g, h):
    # do something
    return h, i, j, k, l, m, n
?

Ich denke und hoffe doch mal nicht!

Vermutlich fängst Du mit weniger Parametern an (sowohl als Argument als auch als Return-Value) und im Laufe der Implementierung fällt Dir auf, dass man noch dies und das bräuchte und so wird daraus ein solcher Molloch.

Wie BlackJack es schon sagte, ändere Dein Vorgehen, indem Du Dir sinnvolle Datenstrukturen überlegst, mit denen Du diesen Wust an Parametern gruppieren und "ordnen" kannst. Sicherlich ist das nicht einfach - ganz im Gegenteil ist das mit das schwierigste beim Programmieren; denn ist die Datenstruktur gut, so kann man damit eigentlich auch immer ein einfaches und elegantes API drum herum bauen :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

ja, das genau ist mein Problem. Ich habe vor diesem Programm nicht programmiert und es wurde immer komplexer.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

By the way.. dieses übergeben von vielen Parametern von einer Funktion an eine andere Funktion macht das Programm nicht um vieles langsamer oder?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

peter99 hat geschrieben:By the way.. dieses übergeben von vielen Parametern von einer Funktion an eine andere Funktion macht das Programm nicht um vieles langsamer oder?
Nein. Aber es macht das Programm auf Dauer unwartbar ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@peter99: Was mir noch an der `computeEnergy()` aufgefallen ist: Das ``if`` innerhalb der Schleife hängt von nichts ab was in der Schleife verändert wird. Dieser Test wird also bei jedem Schleifendurchlauf durchgeführt, obwohl er jedes mal zum gleichen Ergebnis kommt. Also könnte man den Test *einmal* *vor* der Schleife auswerten.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@peter99: Ich glaube, du hast dich mit deinem Code einfach total verrannt. Das sieht alles nicht wirklich danach aus, als ob du dir vorab ausreichend Gedanken über ein passendes Konzept gemacht hast. Vielmehr sieht das nach wild zusammengeschustert aus. Vielleicht solltest du einfach nochmal ganz von vorne anfangen. Du kannst deinen bisherigen Code dabei ja durchaus als Vorlage für eine komplett neu aufgelegte Version deines Programms benutzen. Das ist auch eine Sache, die selbst erfahrenen Entwicklern ab und zu mal passiert und einem Anfänger erst recht. Sieh es doch einfach als Erfahrung an und ärgere dich nicht weiter mit Code herum, bei dem du vermutlich selbst kaum noch durchblickst. ;)
BlackJack

@peter99: Diese Sonderbehandlung für das erste Wertepaar aus `cavlist` und `factor` ist überhaupt nicht notwendig! Diese ganze Rechnerei vor der Schleife kann man sich sparen:

Code: Alles auswählen

def compute_energy(number):
    # TODO Find a better name for `condition`.
    condition = (
        all(t < u for t, u in izip(cavlist, cavmaxCSS)) and Vebit < Vebitmax
    )
    E0 = 600
    for cav, factor in islice(izip(cavlist, factors), number + 1):
        # 10**(-16), because keV
        beta = sqrt(2 * E0 * 1.602177 * 10**(-16) / 1.6726 * 10**27) / 299792458
        tmp = pi * geff / (beta * Lambda)
        T = sin(tmp) / tmp * sin(pi * betaS / (2 * beta))
        E0 = (27.98 * cav * i * cos(phi) * T) / (factor * E0)
        if condition:
            Qout.append(i)
            set_cells(table, len(Qout) - 1, i, Vebit, number, E0)
        else:
            refresh()
Ich habe hier `factor` in `factors` umbenannt, damit man `factor` als Name für ein einzelnes Element verwenden kann.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Ich habe noch ein Problem mit dem späteren Aufrufen
Zuletzt geändert von peter99 am Sonntag 18. August 2013, 15:34, insgesamt 1-mal geändert.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Code: Alles auswählen

from math import*
from string import*
table = display.getWidget("Table").getTable()
table1 = display.getWidget("Table1").getTable()
c0 = 299792458.0
betaS = 0.041
geff = 0.067539767
#big letter because lambda seems to be predefined
Lambda = 3.724129913
k = 2
Vebit0 = 1

def compute_energy(number, k, cavlist, Vebit0, Vebitmax, cavmaxCSS, factor, betaS):
    # TODO Find a better name for `condition`.
    condition = (
        all(t < u for t, u in zip(cavlist, cavmaxCSS)) and Vebit < Vebitmax
    )
    E0 = 600
    for s in range(1,number + 1):
        # 10**(-16), because keV
        beta = sqrt(2 * E0 * 1.602177 * 10**(-16) / 1.6726 * 10**27) / 299792458
        tmp = pi * geff / (beta * Lambda)
        T = sin(tmp) / tmp * sin(pi * betaS / (2 * beta))
        E0 = (27.98 * cavlist[s-1] * i * cos(phi) * T) / (factor[s-1] * E0)
        if condition:
            Qout.append(i)
            set_cells(table, len(Qout) - 1, k, Vebit0, number, E0)
        else:
            refresh()
                

def decision(phi, Qin, A, E, Ein, minimumf, maximumf, Vebitmax, checks, \
             number, minnumber, maxnumber, cavlist, factor, cavmaxCSS, cavmaxreal):
    Q = range(1 , Qin + 1, 1)
    Qout = []
    for i in Q:
        Vebit = 12*A/i   
# Ist possibility: fixed number, compute Energy
        if checks == [1, 0, 0, 1]:
            compute_energy(number, i, cavlist, Vebit, Vebitmax, cavmaxCSS, factor, betaS)     
   	else:
            refresh()
Vielen Dank im Vorraus!

NameError: global name 'i' is not defined
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

und auch natürlich global name 'Vebit' is not defined.. sorry wegen des postens
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Die Fehlermeldungen sind doch Eindeutig. Die Namen ``i`` und ``Vebit`` existieren noch nicht an der Stelle, an der du sie verwenden möchtest. Schau dir den Traceback an, dort steht die Zeilennummer. Und zeige bei deinem nächsten Fehler bitte auch den gesamten Traceback, dort stecken noch viel mehr Informationen drin als in der reien Fehlermeldung.
Das Leben ist wie ein Tennisball.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

danke, es funktioniert
BlackJack

@peter99: Warum willst Du vermeiden Module aus der Standardbibliothek zu importieren? Das macht keinen Sinn. Dafür sind diese Module da.

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)
Hier könnte man noch überlegen ob man den `all()`-Teilausdruck in `decision()` nicht in den Aufrufer verschieben kann, dann würde man ein Argument sparen, denn `cavmax_css` wird nur für diesen Test verwendet.

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.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Vielen Dank für den vielen, äußerst produktiven Input. refresh wird deshalb gebraucht, dass wenn der user das Programm zB mehrmals hintereinander läuft, nicht noch etwas altes vom vorigen Durchlauf in dem table stehen bleibt, obwohl das Programm eigentlich keinen output produziert, deswegen muss immer wenn die condition nicht erfüllt ist refresht werden.. und an der richtigen stelle- muss also erst schauen an welcher Stelle das in deinem code ist.
Sorry, dass ich erst jetzt antworte, hab die 2. Seite nicht gesehen.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

Außerdem(verwende jetzt noch den alten code, aber werde deine Verbesserungsvorschläge definitiv berücksichtigen;) muss ich leider k und dieses dumme Zeug setten(zum. ist es der einzige Umweg, den ich gerade sehe), weil ich sonst den error in meiner main-Funktion erhalte, dass ich k nicht als globalen Parameter eingeführt habe.. was ich ja verstehe, aber soll ja nur ein Standhalter sein bis ich die Funktion abhängig von einem globalen Parameter aufrufe.

Code: Alles auswählen

k = 2
s = 2
Vebit0 = 1
# find a better solution
Qout = []
numberout = []
Energyout = []
fieldout = []

def main():
    Qcont_unstable, A1_unstable, Around_unstable, nameiso_unstable, qdivbya_unstable, abu2_unstable, information_unstable, \
    Qcont_stable, A1_stable, Around_stable, nameiso_stable, qdivbya_stable, abu2_stable, information_stable = readcontaminationfile()
    cavmaxCSS, cavmaxreal, factor = readcavmaxfile()
    phi, Qin, A, E, diffE, minimumf, maximumf, Vebitmax, check2, check1, check3, check4, checks,\
           number, numbers, diffqa0, cavlist, combo = getInputs(A1, Around, nameiso, Qcont, factor)
    alarm(cavlist, cavmaxCSS, number)
    info_for_click = decision(phi, Qin, A, E, diffE, minimumf, maximumf, Vebitmax, checks, \
             number, numbers, cavlist, factor, cavmaxCSS, cavmaxreal)
    clickrow(info_for_click, Qcont, A1, nameiso, qdivbya, abu2, information, A, diffqa0, check3, check4, factor, \
             phi, minimumf, maximumf, cavmaxreal, combo)

def compute_energy(number, A, phi,  k, cavlist, Vebit0, Vebitmax, cavmaxCSS, factor, betaS):
    #all(t < u for t, u in zip(cavlist, cavmaxCSS)) and
    condition_energy = (
    Vebit0 < Vebitmax
    )
    E0 = 600
    for s in range(1,number + 1):
        # 10**(-16), because keV
        beta = sqrt(2 * E0 * 1.602177 * 10**(-16) / 1.6726 * 10**27) /c0
        tmp = pi * geff / (beta * Lambda)
        T = sin(tmp) / tmp * sin(pi * betaS / (2 * beta))
        E0 = E0 + (k*35*cavlist[s-1]/factor[s-1])/A*T*cos(phi)
    if condition_energy:
        Qout.append(k)
        set_cells(table, len(Qout) - 1, k, Vebit0, number, E0)
    else:
        refresh()
 
def compute_field(s, A, phi,  k, Vebit0, Vebitmax, cavmaxreal, factor, betaS, minimumf, maximumf, diffE, E):
    E_average = (600 + E)/2
    v_averge = sqrt(2*E_average*1.602177*10**(-16)/1.6726*10**27)
    beta_average = v_averge/c0
    tmp = pi * geff / (beta_average * Lambda)
    T_average = sin(tmp)/tmp*sin(pi*betaS/(2*beta_average))
    fieldreal = diffE*A/(27.98*k*float(s)*T_average*cos(phi))
    # cannot be defined earlier because otherwise listfields not already defined
    condition_field = (
    fieldreal > minimumf and fieldreal < maximumf and all(fieldreal < u for u in  cavmaxreal) and Vebit0 < Vebitmax
    )
    if condition_field:
        Qout.append(k)
        fieldout.append(fieldreal)
        numberout.append(s)
        Energyout.append(E)
        set_cells(table, len(Qout) - 1, k, Vebit0, s, E)
    # no provide information for click
  #  info_for_click = zip(Qout, fieldout, numberout, Energyout)
   # else:
      #  refresh()
    #return info_for_click

def decision(phi, Qin, A, E, diffE, minimumf, maximumf, Vebitmax, checks, \
             number, numbers, cavlist, factor, cavmaxCSS, cavmaxreal):
    Q = range(1 , Qin + 1, 1)
    for i in Q:
        Vebit = 12*A/i   
# Ist possibility: fixed number, compute Energy
        if checks == [1, 0, 0, 1]:
            compute_energy(number, A, phi,  i, cavlist, Vebit, Vebitmax, cavmaxCSS, factor, betaS)
            # does not provide any information - not needed
        elif checks == [1, 0, 1, 0]:
            compute_field(number, A, phi, i, Vebit, Vebitmax, cavmaxreal, factor, betaS, minimumf, maximumf, diffE, E)
            info_for_click = zip(Qout, fieldout, numberout, Energyout)
        elif checks == [0, 1, 1, 0]:
        # for some reason: after checks no for..
            normann = 3
            for j in numbers:
                compute_field(j, A, phi, i, Vebit, Vebitmax, cavmaxreal, factor, betaS, minimumf, maximumf, diffE, E)
                info_for_click = zip(Qout, fieldout, numberout, Energyout)
   	else:
            refresh()
    return info_for_click
BlackJack

@peter99: Wenn sich in der `main()`-Funktion über nicht definierte Namen beschwert wird, sollte man die *dort* definieren und nicht für das ganze Modul. Es ist sehr verwirrend wenn in Funktionen Namen verwendet werden die auch auf Modulebene schon definiert sind, weil man dann immer erst schauen muss ob ein Name lokal oder Modulglobal ist.
peter99
User
Beiträge: 84
Registriert: Samstag 3. August 2013, 21:32

meinst du so??

Code: Alles auswählen

from org.csstudio.opibuilder.scriptUtil import PVUtil
from org.csstudio.opibuilder.scriptUtil import FileUtil
from org.csstudio.swt.widgets.natives.SpreadSheetTable  import ITableSelectionChangedListener
from java.util import Arrays
from org.csstudio.opibuilder.scriptUtil import ColorFontUtil
RED = ColorFontUtil.getColorFromRGB(255,0,0)
# import math for later calculations in imported data
import os

from math import*
from string import*
table = display.getWidget("Table").getTable()
table1 = display.getWidget("Table1").getTable()
c0 = 299792458.0
betaS = 0.041
geff = 0.067539767
#big letter because lambda seems to be predefined
Lambda = 3.724129913
# should help not to use not defined functions until this moment
# find a better solution
Qout = []
numberout = []
Energyout = []
fieldout = []

def main():
    Qcont, A1, Around, nameiso, abu, qdivbya, abu2, information = readcontaminationfile()
    cavmaxCSS, cavmaxreal, factor = readcavmaxfile()
    phi, Qin, A, E, diffE, minimumf, maximumf, Vebitmax, check2, check1, check3, check4, checks,\
           number, numbers, diffqa0, cavlist, combo = getInputs(A1, Around, nameiso, Qcont, factor)
    alarm(cavlist, cavmaxCSS, number)
    def compute_energy(number, A, phi,  k, cavlist, Vebit0, Vebitmax, cavmaxCSS, factor, betaS):
    #
        condition_energy = (
        Vebit0 < Vebitmax and all(t < u for t, u in zip(cavlist, cavmaxCSS)) 
        )
        E0 = 600
        for s in range(1,number + 1):
            # 10**(-16), because keV
            beta = sqrt(2 * E0 * 1.602177 * 10**(-16) / 1.6726 * 10**27) /c0
            tmp = pi * geff / (beta * Lambda)
            T = sin(tmp) / tmp * sin(pi * betaS / (2 * beta))
            E0 = E0 + (k*35*cavlist[s-1]/factor[s-1])/A*T*cos(phi)
        if condition_energy:
            Qout.append(k)
            set_cells(table, len(Qout) - 1, k, Vebit0, number, E0)
        else:
            refresh()
 
    def compute_field(s, A, phi,  k, Vebit0, Vebitmax, cavmaxreal, factor, betaS, minimumf, maximumf, diffE, E):
        E_average = (600 + E)/2
        v_averge = sqrt(2*E_average*1.602177*10**(-16)/1.6726*10**27)
        beta_average = v_averge/c0
        tmp = pi * geff / (beta_average * Lambda)
        T_average = sin(tmp)/tmp*sin(pi*betaS/(2*beta_average))
        fieldreal = diffE*A/(27.98*k*float(s)*T_average*cos(phi))
        # cannot be defined earlier because otherwise listfields not already defined
        condition_field = (
        fieldreal > minimumf and fieldreal < maximumf and all(fieldreal < u for u in  cavmaxreal) and Vebit0 < Vebitmax
        )
        if condition_field:
            Qout.append(k)
            fieldout.append(fieldreal)
            numberout.append(s)
            Energyout.append(E)
            set_cells(table, len(Qout) - 1, k, Vebit0, s, E)
    # no provide information for click
  #  info_for_click = zip(Qout, fieldout, numberout, Energyout)
   # else:
      #  refresh()
    #return info_for_click
    info_for_click = decision(phi, Qin, A, E, diffE, minimumf, maximumf, Vebitmax, checks, \
             number, numbers, cavlist, factor, cavmaxCSS, cavmaxreal)
    clickrow(info_for_click, Qcont, A1, nameiso, qdivbya, abu2, information, A, diffqa0, check3, check4, factor, \
             phi, minimumf, maximumf, cavmaxreal, combo)
mein erstes Problem dabei waere wie ich die Funktion compute_field wieder aufrufe...
... wenn ich es einfach spaeter aufrufe, bekomme ich einen error, da compute_field/energy nicht mehr global definiert ist.

Code: Alles auswählen

def decision(phi, Qin, A, E, diffE, minimumf, maximumf, Vebitmax, checks, \
             number, numbers, cavlist, factor, cavmaxCSS, cavmaxreal):
    Q = range(1 , Qin + 1, 1)
    for i in Q:
        Vebit = 12*A/i   
# Ist possibility: fixed number, compute Energy
        if checks == [1, 0, 0, 1]:
            compute_energy(number, A, phi,  i, cavlist, Vebit, Vebitmax, cavmaxCSS, factor, betaS)
            # does not provide any information - not needed
        elif checks == [1, 0, 1, 0]:
            compute_field(number, A, phi, i, Vebit, Vebitmax, cavmaxreal, factor, betaS, minimumf, maximumf, diffE, E)
            info_for_click = zip(Qout, fieldout, numberout, Energyout)
        elif checks == [0, 1, 1, 0]:
        # for some reason: after checks no for..
            normann = 3
            for j in numbers:
                compute_field(j, A, phi, i, Vebit, Vebitmax, cavmaxreal, factor, betaS, minimumf, maximumf, diffE, E)
                info_for_click = zip(Qout, fieldout, numberout, Energyout)
   	else:
            refresh()
    return info_for_click
vielen dank im vorraus
Antworten