0

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
0

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

0

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

0

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

0

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

0

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 )
0

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.