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

``````itteration()
some sort of class
for rotations
itteration()``````
5
Contributors
6
Replies
7
Views
7 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):
pass``````

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:
currentDataArray.extend([line.rstrip("\n")])
currentDataFile.close()

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:
return

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
newDataFile.write(atom+"\n")
newDataFile.close()

# 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

#index
rotateIndex = rotationParameters.currentIndex

#angle
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[:]``````