Towers of Hanoi Won't Accept Any Move I Make

I have finished my entire code, but when I test run my code it will not accept any tower I attempt to move a ring to at all. I checked the if…elif…else loop in the companion video, but I can’t place any differences. Can someone please help me? Here is my code:

from stack import Stack

print("\nLet's play Towers of Hanoi!!")

#Create the Stacks
stacks = []
left_stack = Stack("Left")
middle_stack = Stack("Middle")
right_stack = Stack("Right")
stacks.append(left_stack)
stacks.append(middle_stack)
stacks.append(right_stack)
#Set up the Game
num_disks = int(input("\nHow many disks do you want to play with?\n"))
while num_disks < 3:
  num_disks = int(input("Enter a number greater than or equal to 3\n"))
for i in range(num_disks, 0, -1):
  left_stack.push(num_disks)
num_optimal_moves = 2 * num_disks - 1
print("\nThe fastest you can solve this game is in {} moves.".format(num_optimal_moves))
#Get User Input
def get_input():
  choices = [stack.get_name()[0] for stack in stacks]
  while True:
    for i in range(len(stacks)):
      name = stacks[i].get_name()
      letter = choices[i]
      print("Enter {} for {}.".format(letter, name))
      user_input = input("")
      if user_input in choices:
        for i in range(len(stacks)):
          return stacks[i]
        
#Play the Game
num_user_moves = 0
while right_stack.get_size() != num_disks:
  print("\n\n\n...Current Stacks...")
  for stack in stacks:
    stack.print_items()
  while True:
    print("\nWhich stack do you want to move from?\n")
    from_stack = get_input()
    print("\nWhich stack do you want to move to?\n")
    to_stack = get_input()
    if from_stack.get_size() == 0:
      print("\n\nInvalid Move. Try Again.")
    elif to_stack.get_size() == 0 or from_stack.peek() < to_stack.peek():
      disk = from_stack.pop()
      to_stack.push(disk)
      num_user_moves += 1
      break
    else:
      print("\n\nInvalid Move. Try Again")
print("\n\nYou completed the game in {} moves, and the optimal number of moves is {}.".format(num_user_moves, num_optimal_moves))

When you run it what sort of outputs do you get? I only get the following option despite starting on the Left stack which I would assume is a move you can’t make-

“Which stack do you want to move to?
Enter L for Left.”

That should tell you something about the way your code is executing.

When I execute my code, first it asks how many disks I’m using, as it should. Then it asks me which stack I want to move from. I answer and it asks me which stack I’m moving to. It then tells me I am making an invalid move, whichever combination of choices I use. I don’t understand it, the parts I would presume are relevant match up to the companion video precisely. What do you make of it?

@varianthealchemist
This part of the code in your get_input function should be outside your for loop, but within your while loop . That’s the only problem i can immediately spot out.

1 Like

I’ve not seen the video but the fact “Enter L for Left” is the only thing printed when user input gets called should tell you where to start looking. It sounds like you’re drifiting dangerously close to copying code without understanding it which will inevitably come back to bite you. Take care to understand each and every statement in that code. Take them out of the script and run them on their own if that’s what it takes. Or better yet working it out yourself will make certain you understand it. When it works then you can check a given solution and refactor it to be cleaner and faster.

There’s a bit of inconsistent indentation on this first section which offers you the potential choices and @ruronite points out the next bit. Have a close look at that chunk of code too, in particular those last two lines.

There’s a section earlier in the code too which might not behave as expected (at least considering the standard towers of hanoi with differently sized disks…

for i in range(num_disks, 0, -1):
  left_stack.push(num_disks)
1 Like

I fixed the indentation and

for i in range(num_disks, 0, 1):
  left_stack.push(num_disks)

. Some aspects of my output are definitely improved, but my basic problem still remains.

After a spot of debugging, I discovered that my get_input() function appears not to be returning any stacks. When I ran it with an extra call to print_items(), it printed the items just fine, and then it cryptically tacked on None. Since the next line of code was the return statement, I must presume that it meant it returned nothing. I see no apparent errors in return stacks[i]. What could be the problem?

Let me know if posting my updated code would help.

@varianthealchemist post your updated code.

In this for loop The step should be minus 1 (-1) not (1).
You want the for loop counting down like 3, 2, 1

If you have some initial state (having entered input) and some final state (not getting a stack) that isn’t what you meant (getting a stack), then you’ll also have a bunch of states between those that you can observe, so get printing.

Observing and comparing to what-you-mean-should-be-happening will tell you what the problem is. It’s not a black box, you can look at anything in your program, the only thing in your way is that you have to actively decide to look because in order to look you have to write code that emits information from the program.

You should probably be observing the effects of all code you write as you write it, programming is an interactive thing, you write a small piece and run some input through it and see what comes out and then add it to a larger part and then put input through that as well, then do the same with whatever is next.

And here it is, @ruronite! Expect the output to look better, but still fall prey to the same basic inability to succesfully make a move (also, sorry about not writing the minus sign in my earlier post, since I was transcribing the line as it was, rather than as it is, I had to type it by hand and I missed that):

from stack import Stack

print("\nLet's play Towers of Hanoi!!")

#Create the Stacks
stacks = []
left_stack = Stack("Left")
middle_stack = Stack("Middle")
right_stack = Stack("Right")
stacks.append(left_stack)
stacks.append(middle_stack)
stacks.append(right_stack)
#Set up the Game
num_disks = int(input("\nHow many disks do you want to play with?\n"))
while num_disks < 3:
  num_disks = int(input("Enter a number greater than or equal to 3\n"))
for disk in range(num_disks, 0, -1):
  left_stack.push(disk)
num_optimal_moves = 2 * num_disks - 1
print("\nThe fastest you can solve this game is in {} moves.".format(num_optimal_moves))
#Get User Input
def get_input():
  choices = [stack.get_name()[0] for stack in stacks]
  while True:
    for i in range(len(stacks)):
      name = stacks[i].get_name()
      letter = choices[i]
      print("Enter {} for {}.".format(letter, name))
    user_input = input("")
    if user_input in choices:
      for i in range(len(stacks)):
        return stacks[i]
        
#Play the Game
num_user_moves = 0
while right_stack.get_size() != num_disks:
  print("\n\n\n...Current Stacks...")
  for stack in stacks:
    stack.print_items()
  while True:
    print("\nWhich stack do you want to move from?\n")
    from_stack = get_input()
    print("\nWhich stack do you want to move to?\n")
    to_stack = get_input()
    if from_stack.get_size() == 0:
      print("\n\nInvalid Move. Try Again.")
    elif to_stack.get_size() == 0 or from_stack.peek() < to_stack.peek():
      disk = from_stack.pop()
      to_stack.push(disk)
      num_user_moves += 1
      break
    else:
      print("\n\nInvalid Move. Try Again")
print("\n\nYou completed the game in {} moves, and the optimal number of moves is {}.".format(num_user_moves, num_optimal_moves))

I did a lot of printing at various phases of my code while I was printing it. Everything went swimmingly except for the print statement immediately before the return statement and (presumably because of this) the print statement for the if…elif…else conditional. Any ideas where else a print statement might shed some light?

You could look at all the operations between input and (not) receiving a stack. There’s not many of them. It might not be the most efficient thing ever to look at everything but when everything is 20 operations then it’ll take you a few minutes to write those print calls. You can’t point at anything in your code and say “oh I wonder what that is, but it cannot be printed”, because it’s all observable.

I printed everything in the get_input() function and all I get back is what I already know: name is the name of the stack, letter is the first letter of the stack, that there are items in the left stack, and that they’re apparently not being returned. Also, if I try printing the from_stack later in the code, all I get back is the letter the player uses to input it, rather than the stack itself or its contents.

Not sure why you’d look at anything later than some point that you know is wrong. You’d look earlier.

Look at the input you give to each operation and then look at the output. Overall there’s some sequence of operations that you are saying should happen, and you should have an expectation for what each and every one of them results in, which you can verify whether that’s the case as it runs.

If you look at everything you’re aware of and don’t see the problem, then, you’re saying you don’t know what should happen.

If you don’t know what should happen then that is the bug. Decide what should happen. Then make the code do that.

Or if you do know entirely all the things that should happen then you can write them all out and look at the output and be you’ll see what is being done differently from what you meant.

In particular, it’s not enough to “sort of” know what’s in the code, because you are the one controlling every single detail. If you don’t know what those details are then nobody and nothing does. Nothing snaps into place and does the right thing where you yourself aren’t sure.


You read input from the user. What does that look like?
Then what? What operation do you do on that input? What should the result be? Do you get that result if you print it out? Is everything as it should be so far? Move on to the operation after that. And so on. At some point you’ll find that, no, this is not the result I should have after this operation, and then you’ll have found the problem.

You’re not missing any knowledge to find this.

Print out each and every thing that is happening, and compare to what should happen.

Every single thing that changes is something you can print out and look at. Every single operator, every function call, every statement.

You might need to change your expectations around how much you control and own your code, but that’s about it.

1 Like

What should happen is get_input() should return a stack, said function should pass stacks into to_stack and from_stack, and the conditional should evaluate whether or not your action suits the game’s rules. As for my understanding of how the function is meant to work, it should collect a letter from the user and associate it with the appropriate stack. If the user put in a valid letter, it should return the corresponding stack.

Everything before get_input() seems to work like clockwork. Then I thoroughly went through the operations in get_input() to try to get to the bottom of the lack of return. When I couldn’t find anything I checked the from_stack just to see for sure if nothing was being returned. Printing my code, I also see that to_stack is not defined, which is not surprising if get_input() returns nothing.

Make your code write out something like this, based on what it is doing:

Existing stacks:
"Left"
"Middle"
"Right"

first letters, which is the options:
"L"
"M"
"R"

user enters:
"M"

is that among the valid options?
True

which option is that?
the one at index 1

what does that value look like?
<Stack blah blah>
and what is its name attribute?
"Middle"

that's the value that this function should return, so, return it, done.

The only way you’ll be able to write out correct output for that is if you’re also doing the right thing.
In other words, if you are able to observe that this function is misbehaving (you say it isn’t returning stacks), then that will show up in this output, because that output is writing out the things that the correct result depends on.

You might want to start by making sure that your function really does return the wrong thing, otherwise you’d be looking for something that isn’t there. If you think the return value is wrong, well, print it, that’ll tell you whether that’s the case, and then you can continue looking at the other things that led up to that point.

those two things contradict each other.

first you say there’s no return value, then you say there’s no problem to find among the things you checked, among which the return value is one of them

There’s no problem to find everything except the return value. I tried the create the output you asked of me, but name only seems to equal one stack’s name at any given point in the code, you don’t notice it in the final output, but when debugging, each loop overwrites the previous value of name. Could this be the problem? If so, how would I fix it?

So you’re saying you obtained the correct value, and then didn’t return it?

You’re saying you’re doing this:

def add(a, b):
    correct_answer = a + b
    return 5

you’re saying everything is right, up to the return. this would be trivial to fix.


Why do you ask whether that could be the problem? You’re the one writing the code, what should happen? If you’re asking that question then you’re not expecting to know what should happen in your code.

You can’t ask that question. You need to have decided that before you even began writing that code.