So eine Art Switch einbauen

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.
Antworten
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

Liebe Leute
Ich hab mir folgendes Skript gebastelt, dass ein GNUPlot File erstellt in welchem eine Cosinus Funktion überlagert wird. Der Hintergrund ist, dass so ein Wellenpaket modelliert werden kann.

Code: Alles auswählen

#!/usr/bin/env python3

# NOTE:
# - Write superpositions of wavefunction into a
#   plotting script
# - The wavefunction is a linear combination according to
#    psi(x) = sum[ (1/N)*cos(k*pi*x), k=1..N]

import os  

# The primitive wavefunction
def wave(N, k): 
    return '1/{0}.0*cos({1}.0*pi*x)'.format(N,k)

# Superimposing the wavefunction
def loop(L):
    function = ''
    for i in range(1, L+1):
        if i < L:
            function += wave(L, i) + '+' 
        else:
            function += wave(L, i)
    return '(' + function + ')*(' + function + ')', L

# Generating the GNUPlot script
def writeGnuString(functions, lw='2'): 
    gs  = ''
    gs += 'set xrange[-1:1]\n'
    gs += 'plot \\' + '\n'
    i = 0 
    for func in functions: 
        if i < len(functions)-1:
            gs += '{0} title "N={1}" lw {2}, \\'\
                    .format(func[0], func[1], lw) + '\n'
            i+=1
        else:
            gs += '{0} title "N={1}" lw {2};\n'\
                    .format(func[0], func[1], lw) 
    gs += 'pause -1;'
    return gs

# Work
functions = []

# Number of superpositions
for i in [2,5,10,25]:
    functions.append(loop(i))

file = open('wave.gnu', 'w')
file.write(writeGnuString(functions))
file.close()

os.system('gnuplot wave.gnu')
Wenn GNUPlot auf dem System installiert ist, wird das Programm ausgeführt und erst nach Drücken der Eingabetaste wird es beendet. Die 'wave' Funktion liefert die primitive Wellenfunktion und in der 'loop' Funktion wird daraus 'wave^2'. Was ich nun wissen möchte ist, wie kann ich am besten einen Switch einbauen, so dass ich mit einem Parameter bestimmen kann, ob mir 'wave' oder 'wave^2' ins GNUPlot Skript geschrieben wird (der Unterschied ist ja dass 'wave^2' nicht negative wäre und somit physikalische Signifikanz erlangt). Natürlich dachte ich mir, ich kann sowas wie einen Kondition einbauen, if param=='sqr': return wave*wave else: return wave. Kann man das nicht schlauer machen?
Weiter bin ich auch offen für Hinweise zur sinnvollen Optimierung des Codes hinsichtlich den Formatting Konventionen, list comprehensions, lambda functions etc etc.
Freue mich auf Beiträge.
[url=http://www.proandkon.com]proandkon.com[/url]
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Hier erstmal die ueberarbeitete Version: http://paste.pocoo.org/show/336146/

Da gibt es so einige Varianten, nur kann man das schlecht anhand deiner Informationen abwaegen. Wenn sich an der Funktion nicht mehr viel aendern soll, wuerde ich zu der einfachen `if`-Abfrage raten, auch moeglich ist eine eigene Funktion, etc etc.
BlackJack

`loop()` liesse sich wohl auch so schreiben:

Code: Alles auswählen

def loop(L):
    """Superimposing the wavefunction"""
    function = '+'.join(wave(L, i) for i in range(1, L + 1))
    return '({0})*({0})'.format(function), L
Aber kann man das Quadrat in GNUPlot nicht auch anders ausdrücken als tatsächlich den Ausdruck zweimal zu "schreiben"? Gibt's da nicht '^2' oder '**2' oder eine `pow()`-Funktion?
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

@blackjack: ich hab da nicht lange drüber nachgedacht. Ziemlich sicher schon.
Vielen Dank für die Hinweise soweit.
[url=http://www.proandkon.com]proandkon.com[/url]
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Also laut http://www.gnuplot.info/docs_4.4/gnuplot.pdf 13.2.2 binary Operators, sollte ** durchaus möglich sein.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

stimmt. Danke für den Link.
Mir ist da aber gerade eine andere Frage in den Sinn bekommen. Ich hab ja hier die 'format()' Syntax benutzt um Strings zu erstellen.
Ist es möglich, den Code so zu schreiben, dass das Skript auch noch mit Python 2.x kompatibel bleibt, wo es ja noch keine '.format()' Methode gibt?

Vielen Dank für weitere Hinweise.
[url=http://www.proandkon.com]proandkon.com[/url]
BlackJack

@mzh: Naja statt `format()` dann halt den ``%``-Operator.

Code: Alles auswählen

def wave(N, k):
    """The primitive wavefunction"""
    return '1/%s.0*cos(%s.0*pi*x)' % (N, k)


def loop(L):
    """Superimposing the wavefunction"""
    function = '+'.join(wave(L, i) for i in range(1, L + 1))
    return '(%s)*(%s)' % (function, function), L
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

Ja, so ists schon möglich. Aber war es nicht so, dass der Trend in die Richtung geht, den '%' Operator nicht mehr einzusetzen? Andererseits, ist es nicht so, dass sich hier die Möglichkeit auftun würde einen Callback zu verwenden? Dh., wenn ich das richtig verstanden habe, die Funktion wird für Python 2 und Python 3 geschrieben, an einen Bezeichner gebunden, aber erst beim Aufruf wird entschieden, welche Version nun ausgeführt wird. Muss da ein bisschen mehr darüber nachlesen, bin aber ganz sicher dass ich es irgendwo sah.
[url=http://www.proandkon.com]proandkon.com[/url]
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ja natuerlich geht das. Nur ist es so, dass `%` von beiden Versionen unterstuetzt wird und in Python 3 auch nicht irgendwann wegfallen wird. Insofern kann man sich da die Arbeit sparen.
BlackJack

@mzh: Wenn es kein `str.format()` gibt, kann man schlecht von ``%`` weg kommen. Das mit dem Callback habe ich jetzt nicht verstanden!?
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

BlackJack hat geschrieben:@mzh: Wenn es kein `str.format()` gibt, kann man schlecht von ``%`` weg kommen. Das mit dem Callback habe ich jetzt nicht verstanden!?
komme darauf zurück.
[url=http://www.proandkon.com]proandkon.com[/url]
Antworten