How come this just hangs, after debugging I found it never returns True for precondition even though it should on the very first go around....ugh!!!

#!/usr/local/bin/python
#Scott Landau
#CS 380
#Assignment 1 Programming Portion in Python
#Created - 4/6/09
#Last Edited - 4/8/09

import pdb

#n is going to be equal to 4 for this queens problem.
n = 4

#Assigning the empty list to initialState.
initialState = []

#Making an allDirections list.
allDirections = [[-1,0],[1,0],[0,-1],[0,1],[-1,-1],[-1,1],[1,-1],[1,1]]

#declare the list 'state' which represents the number of non threatening
#queens that have been placed on the board.
state = []

def goal(state):
	if ((len(state)) == n):
		return True
	else:
		return False

#defining allRules list which the contents of which will be created in next function.
allRules = []
#defining all the rules for an nxn board. assigning these rules to allRules
def makeRules(n):
	for i in range(0, (n), 1):
		for j in range(0, (n), 1):
			allRules.append([i,j])
	return

#this function will apply the rule that is in the rule list to the given state, which just appends it to the state list.
def applyRule(rule,state):
	state.append(rule)
	return

#returns true if the row or column of 'pos' is out of bounds.
def outOfBounds(pos):
	if ((pos[0] < 0) or (pos[0] > (n-1)) or (pos[1] < 0) or (pos[1] > (n-1))):
		return True
	else:
		return False 	

#function that will determine which positions queens cannot be placed into because they might eventually run into another queen already on the board.
def blocked(pos,state,direction):
	newpos = [(pos[0]+direction[0]),(pos[1]+direction[1])]
	if newpos in state:
		return True
	elif outOfBounds(newpos):		
		return False
	else:
		return True		
		blocked(newpos,state,direction)
		

#precondition to the actions checker
def precondition(rule,state):
	if not blocked(rule,state,(allDirections[0])):
		if not blocked(rule,state,(allDirections[1])):
			if not blocked(rule,state,(allDirections[2])):
				if not blocked(rule,state,(allDirections[3])):
					if not blocked(rule,state,(allDirections[4])):
						if not blocked(rule,state,(allDirections[5])):
							if not blocked(rule,state,(allDirections[6])):
								if not blocked(rule,state,(allDirections[7])):
									return True
	else:
		return False

#running a simple test using all the functions
pdb.set_trace()
makeRules(n)
while not goal(state):
	for l in range(0, (len(allRules)), 1):
		if precondition((allRules[l]),state):
			applyRule((allRules[l]),state)
			print state

print state

With huge indentations like you have in your code my editor will go up in smoke! I will let someone else try it first! :)

With huge indentations like you have in your code my editor will go up in smoke! I will let someone else try it first! :)

Haha.


I just tried to run through the execution of the code in my head without trying to follow the logic.

It seems to me this if not blocked(rule,state,(allDirections[0])): code will evaluate to false the first time it is executed which seems to be what you are describing.

Take out a piece of paper and try to work through your program. This will probably help you figure out where the problem is.

You should also call each of your functions with all possible test cases to see if they are behaving as you expect so that you know you can rely on them in other parts of your program.

You can replace this:

#precondition to the actions checker
def precondition(rule,state):
	if not blocked(rule,state,(allDirections[0])):
		if not blocked(rule,state,(allDirections[1])):
			if not blocked(rule,state,(allDirections[2])):
				if not blocked(rule,state,(allDirections[3])):
					if not blocked(rule,state,(allDirections[4])):
						if not blocked(rule,state,(allDirections[5])):
							if not blocked(rule,state,(allDirections[6])):
								if not blocked(rule,state,(allDirections[7])):
									return True
	else:
		return False
##---------------------------------------------------------
##   with  (not tested)
##   in other words, if any one is blocked, return false
##   This is the way the code appears to work.
##---------------------------------------------------------
def precondition(rule,state):
   for j in range(0, 8):
      if blocked(rule,state,(allDirections[j])):
         return False
   return True

Whe you have the same line of code multiple times, consider a for() loop or a function instead.

A print statement here shows that len(state) remains at zero.

def goal(state):
        print len(state), n
	if ((len(state)) == n):
		return True
	else:
		return False

Also, put in a counter while testing to eliminate endless loops.

ctr = 0
ctr_max = 100
while (not goal(state)) and (ctr < ctr_max):
        ctr += 1
        if ctr == ctr_max:
           print "Bye, Bye.  ctr_max limit reached."
	for l in range(0, (len(allRules)), 1):
		if precondition((allRules[l]),state):
			applyRule((allRules[l]),state)
			print state
 
print state

also, you could replace this:

#precondition to the actions checker
def precondition(rule,state):
	if not blocked(rule,state,(allDirections[0])):
		if not blocked(rule,state,(allDirections[1])):
			if not blocked(rule,state,(allDirections[2])):
				if not blocked(rule,state,(allDirections[3])):
					if not blocked(rule,state,(allDirections[4])):
						if not blocked(rule,state,(allDirections[5])):
							if not blocked(rule,state,(allDirections[6])):
								if not blocked(rule,state,(allDirections[7])):
									return True

with this:

#precondition to the actions checker
def precondition(rule,state):
	if not blocked(rule,state,(allDirections[0]))and not blocked(rule,state,(allDirections[1])) and  not blocked(rule,state,(allDirections[2]))
    and  not blocked(rule,state,(allDirections[3])) and  not blocked(rule,state,(allDirections[4]))
    and  not blocked(rule,state,(allDirections[5])) and  not blocked(rule,state,(allDirections[6]))
    and  not blocked(rule,state,(allDirections[7])):
        return True

i know it isnt as readable but it does the same job with less indents.

Part of the problem may be all of the global variables, and the functions possibly using locals instead of globals. This program should be using a class anyway. Here it is, converted to a class. The final line prints
Final print [[0, 0], [0, 1], [0, 2], [0, 3]]
Don't know if that is what you were expecting or not. And if you don't already know this, you can pipe any printed output to a file if there is too much to fit on the screen, with the ">" operator. From the command line, this will pipe any output to a file named "test1.txt".
./program_name > test1.txt

#!/usr/bin/python

#Scott Landau
#CS 380
#Assignment 1 Programming Portion in Python
#Created - 4/6/09
#Last Edited - 4/8/09
 
import pdb
 
class Queens:
   def __init__(self):
      self.testing = True     ## print diagnostics
      
      #n is going to be equal to 4 for this queens problem.
      self.n = 4
 
      #Assigning the empty list to initialState.
      self.initialState = []
 
      #Making an allDirections list.
      self.allDirections = [[-1,0],[1,0],[0,-1],[0,1],[-1,-1],[-1,1],[1,-1],[1,1]]
 
      #declare the list 'state' which represents the number of non threatening
      #queens that have been placed on the board.
      self.state = []
      
      #defining allRules list which the contents of which will be created 
      #in makeRules
      ##self.allRules = []     ## declared in makeRules()
 

   def goal(self):
        if self.testing:
	   print "goal()", len(self.state), self.n
	
	if ((len(self.state)) == self.n):
		return True
	else:
		return False
 
   #defining all the rules for an nxn board. assigning these rules to allRules
   def makeRules(self):
	 self.allRules = []
	 for i in range(0, (self.n), 1):
		for j in range(0, (self.n), 1):
			self.allRules.append([i,j])
         return
 
   #this function will apply the rule that is in the rule list to the 
   #given state, which just appends it to the state list.
   def applyRule(self, rule):
	 self.state.append(rule)
	 return
 
   #returns true if the row or column of 'pos' is out of bounds.
   def outOfBounds(self, pos):
	 if ((pos[0] < 0) or (pos[0] > (self.n-1)) \
	    or (pos[1] < 0) or (pos[1] > (self.n-1))):
		return True
	 else:
		return False 	
 
   #function that will determine which positions queens cannot be placed into
   #because they might eventually run into another queen already on the board.
   def blocked(self, pos, direction):
	 newpos = [(pos[0]+direction[0]),(pos[1]+direction[1])]
	 if newpos in self.state:
		return True
	 elif self.outOfBounds(newpos):		
		return False
	 else:
		return True		
		##***** The Following Line Will Never Be Reached *****
		##***** It Is After The Return Statement *****
		self.blocked(newpos, direction)
 
 
   #precondition to the actions checker
   def precondition(self, rule):
         for j in range(0, 8):
	    if self.blocked(rule,(self.allDirections[j])):
               return False
            else:
		return True
 
##====================================================================
#running a simple test using all the functions
##pdb.set_trace()
      
##instantiate class
Q = Queens()

Q.makeRules()
ctr = 0
ctr_max = 100
while (not Q.goal()) and (ctr < ctr_max):
        ctr += 1
	for l in range(0, (len(Q.allRules)), 1):
		if Q.precondition((Q.allRules[l])):
			Q.applyRule((Q.allRules[l]))
			print Q.state
        if ctr >= ctr_max: 
	   print "Bye, Bye.  ctr_max exceeded"
print "Final print", Q.state

Look: I'm new here, and maybe way, way offbase. You elders will correct me if I'm wrong, but I contend:

# we should not be a service to solve interesting lab projects. This one clearly is just that, a request for help in CS 380.

# one approach to a problem is to ask a person to think less mechanically about the problem. His approach would not be pythonic if it 'worked', and he's lucky that it failed.

--gnujohn@gmail.com

I'm certainly not an 'elder' but you're right.

However, I do think the OP came with a legitimate question.

# we should not be a service to solve interesting lab projects. This one clearly is just that, a request for help in CS 380.

This is true, but thankfully the OP came with example code and exactly what his difficulty is. Most people come into this forum and simply copy-paste the instructions to their problem and say

NEED HELP ASAP! Urgent! PLEASEEEEEEEEEEEEEEE!!!!!

So a pat on the back for the OP for reading the forum announcements about homework help.

We should answer questions in such a way that
1. The OP learns something
2. Don't provide the entire program. Just solve the specific problem.

In this case, the OP hopefully learned the value of using the class structure. The problem was likely related to the use of local and global variables, although I'm not going to spend time figuring that out. Also, I doubt that someone taking CS380 would write a program like that. They would still be taking CS102, which means this may be someone learning on their own. Anyway, it does seem that the OP bit off more than they could chew and is not continuing with it, and probably has gone back to the online tutorials. Which is the lesson here.

It's okay, then, if we differ: python code with n levels of indentation, and he asks why the 'while' logic isn't working? He should ask, better, why the interpreter isn't rising from his machine to strangle him! He's looking for an answer to SICPE, p. 124, Ex. 2.42, and wants it to be in Python, not in Lisp. --John (gnujohn@gmail.com) imho.

Honestly, this was an assignment. I would not have lied if someone asked that in the first place. I like this forum though because I always try my assignments to the best of my ability beforehand. And when they fail, I debug. And if that still doesn't work, I try it again. I did all these things before coming here. I also asked my TA as well, so it's not like he didn't know I was seeking help.

I would never have came here asking for an answer to a question that I didn't try. Whats the point of going to school if that's the case, I would just fail later on in life.

I thank you for all the help you guys gave me though. I took everything into consideration and created a better program out of it. I don't cheat.

This article has been dead for over six months. Start a new discussion instead.