Search code examples
pythonfunctionswap

How can one swap elements which come from a function?


So I have defined a class called "Particles":

class Particle:
    def __init__(self, posInit, momInit, spin):
        self.posInit = posInit
        self.momInit = momInit
        self.spin = spin
    def momfT(self, t):
        return self.momInit*(math.cos(t))-self.posInit*(math.sin(t))
    def posfT(self, t):
        return self.posInit*(math.cos(t))+self.momInit*(math.sin(t))

P = [Particle(posInit = i, momInit = j, spin = choice(["up", "down"])) for i,j in zip(Zinitial,Pinitial)]

What I now want to do is switch the positions of the particles if a certain condition is met. So something like the following:

if cond==True:
  P[1].posfT[t], P[2].posfT[t1] = P[2].posfT[t1], P[1].posfT[t]

But the above does not work since I am trying to assign to a function a value.

So I am not sure how to do this?


Solution

  • It seems that you intend to store the position and momentum of your particle over time in posfT and momfT respectfully (edit: I previously thought you wanted only the current position). If so, they should not be methods, but attributes. You should also have separate methods to modify those values as t evolves. I suggest to modify your class like this:

    class Particle:
        
        def __init__(self, posInit, momInit, spin):
            self.posInit = posInit
            self.momInit = momInit
            self.spin = spin
            self.momfT = dict()
            self.posfT = dict()
            self.calc_at_time(0)
        
        def calc_at_time(self, t):
            self.momfT[t] = self.momInit*(math.cos(t))-self.posInit*(math.sin(t))
            self.posfT[t] = self.posInit*(math.cos(t))+self.momInit*(math.sin(t))
    

    Note: I am assuming that posfT and momfT are initialized with t=0. I absolutely lack the knowledge to know if this is correct, please check and correct as necessary. I am focusing on code here.

    You will then be able to set new positions at time t by calling calc_at_time(t)

    t = 1
    t1 = 2
    P[1].calc_at_time(t)
    P[1].calc_at_time(t1)
    P[2].calc_at_time(t)
    P[2].calc_at_time(t1)
    

    And access the position of P[x] at time t with P[x].posfT[t].

    Accordingly, what you're trying to do should now work:

    if cond == True:
      P[1].posfT[t], P[2].posfT[t1] = P[2].posfT[t1], P[1].posfT[t]
    

    Meaning: posfT of P[1] at [t] becomes posfT of P[2] at t1, and reciprocally.