Will Will - 1 year ago 105
Python Question

Fixing syntax error suggestions

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
# 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

vec.reshape(2*self.N) [1: :2])
set_data == update data set
[::2] == picks pout even number elements (x-axis valies) from the velocity
[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__':

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download