I am a relatively inexperienced coder so please excuse my ignorance.

I am attempting to write a code to iterate rotations of functional groups in a molecule.
The number of groups that need to rotate and the step size is based on user input.
I know i can generate the iterations using a series of nested for loops

for i in [120,240,360]:
	for j in [60,120,180]:
		print str(i) + '.' + str(j)

My question is how do do this dynamically
The information about the rotations is stored in an array
rotationarray[rotation][3] contains the whole rotation range and
rotationarray[rotation][4] contains the step size

rotationarray = [[2,8,1,360,120,True],[3,9,1,180,60,True]]

My guess is this could be solved something like this but I keep running into a wall in my logic and I was hoping someone could give me a little help

	some sort of class
		for rotations
6 Years
Discussion Span
Last Post by pyTony

You can use the range() function to dynamically decide how many steps to take, with starting ending and step size options.


You can use variables for this, if that is what you are after (untested code).

rotation_in = int(raw_input("Enter rotation "))
for el in rotationarray:
    if rotation_in == el[3]:
        print el
        for x in range(0, el[3]+1, el[4]):     ## start, stop, step
            print x

Edited by woooee: n/a


OMG don't use ListType while looping like that!

This is so much faster:

for i in (3,4,7):

Tuples are so much faster, and consumes less memory


The number of groups that need to rotate and the step size is based on user input.

The OP is asking how to use a variable for range and step, based on user input, specifically

rotationarray[rotation][3] contains the whole rotation range and
rotationarray[rotation][4] contains the step size

OMG?? (this isn't high school).

Edited by woooee: n/a


I figured out a solution; I thought it might be helpful to someone else at some point.
Its tailored to what I needed

If anyone has good ideas on how to boost performance, I'm open to more help.

#! /usr/bin/env python
# example rotation arrays
# format [[atm#1 atm#2 #ofatmMoving totalrotation rotationstepsize compoundrotation],[rotation2],...]
#rotationArray = [[2,8,1,360,120,True],[3,9,1,180,60,True], [3,9,1,30,10,True]]
rotationArray = [[2,8,1,360,120,False],[5,11,4,360,120,True],[11,12,1,360,120,True]]

#format [[atm#ofmoving1,atm#ofmoving2,...],[rotation2],...]
movingAtoms = [[19],[12,23,22,24],[24]]

inputPathStr = "input/datafile.txt"
outputLocationStr = "output/"

def copyInputFile( inputPathStr, outputLocationStr ):
	# copy the input file to the output folder
	# todo: make this dynamic based on parameters too
	return  outputLocationStr + "datafile.txt"

def iterator( rotationParameters ):

	totalIndexLength = len(rotationParameters.rotationArray)

	# open the current file  and load contents into memory for use later
	currentDataArray = []
	currentDataFile = open(rotationParameters.currentFileNameStr,'r')
	for line in currentDataFile:
	print "currentDataArray length " + str( len(currentDataArray) )
	# perform my rotations 
	# set up some variables for driving the for loop based off our first input data element
	print "rotationParameters.currentIndex " + str(rotationParameters.currentIndex)
	if rotationParameters.currentIndex >= totalIndexLength:
	firstPropertiesElement = rotationParameters.rotationArray[rotationParameters.currentIndex]
	startingDegree = 0
	endingDegree = firstPropertiesElement[3]
	stepDegree = firstPropertiesElement[4]
	# debugging prints

	print "startingDegree " + str(startingDegree)
	print "stepDegree " + str(stepDegree)
	print "endingDegree " + str(endingDegree)

	# loop through for my for loop
	degreeCounter = startingDegree
	while degreeCounter < endingDegree:

		# what information do we need to rotate; pass it into the rotateAtoms call
		localRotationParameters = rotationParameters.clone()
		localRotationParameters.currentDegree = degreeCounter
		rotationResultDataArray = rotateAtoms( currentDataArray,  rotationParameters ) 
		# get a new file name
		oldFileNameStr = rotationParameters.currentFileNameStr.rstrip('.txt')
		newFileNameStr = oldFileNameStr + "." + str(degreeCounter) + ".txt"

		# loop through the rotationresult and write it out to the new file
		# save the rotations  to a new data file based off the rotations:  "datafile.0.txt"	
		newDataFile = open( newFileNameStr, 'w' )
		for atom in currentDataArray:
			# write to the file

		# check to see if we should recurse; stopping condition
		print "totalIndexLength " + str(totalIndexLength)
		print "rotationParameters.currentIndex" + str(rotationParameters.currentIndex)
		if rotationParameters.currentIndex < totalIndexLength:
			newRotationParameters = rotationParameters.clone()
			newRotationParameters.currentIndex = rotationParameters.currentIndex +1
			newRotationParameters.currentDegree = degreeCounter
			newRotationParameters.currentFileNameStr = newFileNameStr
			iterator( newRotationParameters )
		#increment degrees based on propertries of input
		degreeCounter = degreeCounter + stepDegree
# end oif iteration function

def rotateAtoms( dataArray, rotationParameters ):
	returnDataArray = dataArray
	# do the rotation of the atoms, whatever that is, need to identify what information we need to do the rotation and call the c execution
	# takes the input dataArray and copies it/modifies it and fills the return Data Array so it can be written to disk
	rotateIndex = rotationParameters.currentIndex
	rotateCurrentDegree = rotationParameters.currentDegree
	#rotationArray values
	rotateArrayValues = rotationParameters.rotationArray[rotateIndex]
	#moving atoms
	rotateMovingAtoms = rotationParameters.movingAtoms[rotateIndex]
	#atoms to rotate around
	# look up in atoms data based on ids in moving attoms and rotation array
	return returnDataArray
# end of the rotateAtoms function

def rotateAtom():
	returnRotation = []
	# call the rotate atom c code
	return returnRotation
# end of the rotateAtom method

class RotationParameters:
	def __init__ (self, currentIndex = 0, rotationArray = None, movingAtoms = None, currentFileNameStr = None, currentDegree = None ):
		self.currentIndex = currentIndex
		self.rotationArray = rotationArray
		self.movingAtoms = movingAtoms
		self.currentFileNameStr = currentFileNameStr
		self.currentDegree = currentDegree
	def clone( self):
		returnParameters = RotationParameters()
		returnParameters.currentIndex = self.currentIndex
		returnParameters.rotationArray = self.rotationArray
		returnParameters.movingAtoms = self.movingAtoms
		returnParameters.currentFileNameStr = self.currentFileNameStr
		returnParameters.currentDegree = self.currentDegree
		return returnParameters
# end of rotationParameters class

#  copy the input file over so we don't destroy it.
newBaseFile = copyInputFile( inputPathStr, outputLocationStr)

# setup the parameters for the rotations
myRotationParameters = RotationParameters()
myRotationParameters.currentIndex = 0
myRotationParameters.rotationArray = rotationArray
myRotationParameters.movingAtoms = movingAtoms
myRotationParameters.currentFileNameStr = newBaseFile

# run the rotations
iterator( myRotationParameters )

if you want to really copy iterable, you should use slice:

returnDataArray = dataArray
==>     returnDataArray = dataArray[:]
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.