Will - 1 year ago 87

Python Question

New to programming. Trying to run my first script in Spyder but the following syntax error has been returned.

`anim = animation.FuncAnimation(fig, tick, fargos=(pts, beak, boids),`

^

interval = 50)

SyntaxError: invalid syntax

At first I thought it is because I failed to import the right module, but then:

`import sys, argparse`

import math #import math functions such as pi

import numpy as np # creates arrays

import matplotlib.pyplot as plt # creates 2D graphs

import matplotlib.animation as animation

from scipy.spatial.distance import squareform, pdist, cdist

from numpy.linalg import norm

Clearly the matplotlib.animation as animation covers that angle. I then thought that perhaps that Spyder did't have the module installed, but I understand that spyder automatically has that particular modules pre-installed.

Any suggestions for things to try?

Full code:

`# -*- coding: utf-8 -*-`

"""

Created on Fri Apr 8 15:23:25 2016

@author: williamneal

"""

import sys, argparse

import math #import math functions such as pi

import numpy as np # creates arrays

import matplotlib.pyplot as plt # creates 2D graphs

import matplotlib.animation as animation

from scipy.spatial.distance import squareform, pdist, cdist

from numpy.linalg import norm

"""

1. The Boids simulation needs to compute the position and velocities of

the boids at each step by pulling infomation from numpy arrays.

2.At the beginning of the simulation, the boids will be placed in

approximately in the centre of the screen with their

velocities set in different directions

"""

width, height = 640, 480 #defines simulation area aka viewport

class Boids:

"""class that represents Boids simulation, handles the initialization,

updates the animation, and applies the rules"""

def _init_(self, N):

""" initialize Boid simulation"""

# init positions and velocities

self.pos = [width/2.0, height/2.0] + np.random.rand(2*N).reshape(N,2)

"""

1) pos = list + random float --> ([randomfloat, randomfloat])1D array...

pos = [element, element] + random float --> (2, )

2) ...1D array + reshape --> 2D array

(2, ) + (N,2) --> (None, 2) + (N,2) --> (N, 2) + (N, 2) --> (N,2)

Note that pos defines the positions of the boids, not the boids themselves.

The position of the boids is defined in reference to the viewport.

"""

# normalized random velocities

angles = 2*math.pi*np.random.rand(N)

"""

angles = 2pi * random(N)

"""

self.vel = np.array(list(zip(np.sin(angles), np.cos(angles))))

"""

1) vel == captures the output of 'angles' and inserts them into a 2D

array so as to map boids positions.

Sin is used for y coordinates and Cos is used for x coordinates

2) the zip function paires off elements of the two lists

"""

self.N = N

# min dist of approach

self.minDist = 25.0

# max magnitude of velocities calculated by "rules"

self.maxRuleVel = 0.03

# max magnitude of final velocity

self.maxVel = 2.0

def tick (self, frameNum, pts, beak):

""" update sim by one time step"""

#get pairwise distances

self.distMatrix = squareform(pdist(self.pos))

"""

distMatrix = initial starting positions -> condensed matrix -> redundent matrix

Calculates the pairwise distance between an array of points in a matrix.

Distance matrix acts as a transformational matrix

"""

# apply rules

self.vel += self.applyRules()

self.limit(self.vel, self.maxVel)

self.pos += self.vel

self.applyBC()

# update data

pts.set_data(self.pos.reshape(2*self.N)[: : 2],

self.pos.reshape(2*self.N) [1: :2])

vec = self.pos + 10*self.vel/self.maxVel

"""

1)Calculates the position of the head through applying a discplacment of 10 units

in the direction of the velocity (vel)

2)This displacement in turn determines the distance of beak from body

"""

beak.set_data(vec.reshape(2*self.N)[::2],

vec.reshape(2*self.N) [1: :2])

"""

set_data == update data set

[::2] == picks pout even number elements (x-axis valies) from the velocity

list

[1::2] == picks out odd numbers from the velocity list (y-axis values)

"""

def limitVec(self, vec, maxVal):

"""limit the magnitude of the 2D vector"""

mag = norm(vec)

if mag > maxVal:

vec[0], vec[1] = vec[0] * maxVal/mag, vec[1] * maxVel/mag

def limit(self, X, maxVal):

"""limit magnitude of 2D vectors in array X to maxValue"""

for vec in X:

self.limitVec(vec, maxval)

def applyBC(self):

"""apply boundary conditions, torodial tiled, creates the word"""

deltaR = 2.0 # creates an appearance of a delay between boid moving off screen and appearing again

for coord in self.pos:

if coord[0] > width + deltaR:

coord[0] = - deltaR

if coord [0] < - deltaR:

coord [0] = width + deltaR

if coord[1] > height + deltaR:

coord[1] = -deltaR

if coord[1] < - deltaR:

coord[1] = height + deltaR

def applyRules (self):

# apply rule #1 Seperation

D = distMatrix < 25.0

#Pushes boids away that 25.0px

vel = self.pos*D.sum(axis=1).reshape(self.N,1) - D.dot(self.pos)

# calculated velocity is throttled

self.limit(vel, self.maxRulevel)

# distance threshold for alignment (different from seperation)

D = distMatrix < 50.0

# apply rule #2: Alignment

vel2 = D.dot(self.vel)

self.limit(vel2, self.maxRuleVel)

vel += vel2; """ = vel= vel+vel2 """

#apply rule #3 - Cohesion

""" add a velocity vector for each boid that points to the centroid of

neighboring boids within a certain distance

centroid = athretic mean of boids in a given radius

"""

vel3 = D.dot(self.pos) - self.pos

self.limit(vel3, self.maxRuleVel)

vel += vel3

return vel

"""

Button events in matplotlib go here...

# add a "button press event" handler

cid = fig.canvas.mpl_connect('button_press_event', buttonPress)

"""

def tick(self, frameNum, pts, boids):

#print frameNum

""" update function for animation"""

boids.tick(frameNum,pts, beak)

return pts, beak

# main() funtion

def main():

#use sys.argv if needed

print('starting boids...')

parser = argparse.ArgumentParser(description="Implementing Craig Reynolds's Boids...")

#add arguments

parser.add_argument('--num-boids', dest='N', required=False)

args = parser.parse_args()

#number of boids

N = 100

if args.N:

N = int(args.N)

# create boids

boids = Boids(N)

# setup plot

fig = plt.figure() # opens a new figure window and make it active

ax = plt.axes (xlim=(0, width), ylim=(0, height))

"""

plt.axes() == adds an axes to a figure (sets limits of x axis (min, max),

sets limits of y axis (min, max))

"""

pts, = ax.plot([], [], markersize=10, c='k', marker='o', ls='None')

"""

plt.axes.plot(x, y) == plots x, y with other arguments used for formatting

c='k' == plot colour is black

marker = 'o' == format of point is a circle

ls='None' == line styling between points

Marker for the boids body

"""

beak, = ax.plot([], [], markersize=4, c='r', marker='o', ls='None'

"""

Marker for birds head and beak

"""

anim = animation.FuncAnimation(fig, tick, fargos=(pts, beak, boids),interval = 50)

# call main

if __name__ == '__main__':

main()

Answer Source

You have a few trailing commas on your variable assignments and you are missing an end bracket on that second line.

```
pts, = ax.plot...
beak, = ax.plot([], [], markersize=4, c='r', marker='o', ls='None'
```

You should use an IDE like PyCharm. It will highlight your syntax errors.