Towers of Hanoi

Hi,

I arrived at the Towers of Hanoi project in the Python course. I’m a beginner so it’s really difficult to finish this exercise without any provided solution / video walkthrough which was the case for previous projects.

Is someone willing to share the full solution with me? Thank you.

https://www.codecademy.com/paths/computer-science/tracks/linear-data-structures/modules/cspath-stacks/projects/towers-of-hanoi

Follow-up question.

In step 14 you need to provide the following list comprehension.

choices = [stack.get_name()[0] for stack in stacks]

What is the purpose of “[0]” please?

stack is a list. The [0] is the index number in stack you are referencing.

my completed code is here: https://gist.github.com/cd0ef5b56a757260ce2245c884069ccb

1 Like

Thank you man for the solution

Am I the only one who can’t get this to work? I keep getting a NameError when entering in L, M, or R (or anything else for that matter).

I literally took the solution, copied and pasted it in to my window and I still get the same error. I can’t figure out why this is happening and as a beginner I’m not good at debugging yet. :frowning:

Hi @kbiz,

To run the script, enter the following:

$ python3 script.py

For the current project, avoid doing this:

$ python script.py

If you do that in the Codecademy environment provided for this project, you’ll be executing the script with Python 2 instead of Python 3, and the user input will be interpreted as an expression rather than as a string. As a consequence, the interpreter will look for variables named L, M, or R, when the user enters a choice. Upon not finding variables by those names, the interpreter will raise a NameError.

EDIT (December 20, 2019):

The above was written based on the assumption that you used the input built-in function to get responses from the user. See the following documentation:

If you are using Python 2, use the raw_input function to get user responses. With Python 3, use input to get user responses. For the most part, avoid using input with Python 2, except for debugging purposes.

Some of what was written prior to this edit needs clarification. It is not quite accurate to state that with Python 2, the user response to the input function does not get interpreted as a string. It gets evaluated as an expression, and that expression might evaluate to a string. For example, the expressions "L", "M", and "R", with the quotes included, do evaluate to strings. Accordingly, if you entered them in that manner while running your Towers of Hanoi code in Python 2, those responses would correctly refer to the various stacks. However, the best option is to run the program with Python 3.

1 Like

I am having a similar problem with Towers of Hanoi.

This is my code. Game input always returns “Other problem. Try again.” Any idea where it is going wrong?

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)
#left_stack.print_items()

number_optimal_moves = 2**num_disks -1

print("\nThe fastest you can solve this game is in {optmoves} moves".format(optmoves=number_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 {letter} for {name}".format(letter=letter, name=name))
    user_input = input("")
    if user_input in choices:
      for i in range(len(stacks)):
        return stacks[i]

        
#Play the Game 
#THE ISSUE IS SOMEWHERE IN HERE

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\nFrom stack is empty. 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\nOther problem. Try Again.")
      
print("\n\nYou completed the game in {0} moves, and the optimal number of moves is {1}".format(num_user_moves, num_optimal_moves))

Hello, @arc6358831141, and welcome to the Codecademy Forums!

Take a close look at your get_input function. In particular, consider what happens in the for loop that is contained within the if block. Does it return the Stack that the user chooses? To find out, you can insert a temporary print statement right before the return statement.

Thanks for that. So I need to add in a line like follows, right?

    if user_input in choices:
      for i in range(len(stacks)):
        **if user_input == choices[i]:**
          return stacks[i]

I think then the helper video here is missing the same line of code: https://youtu.be/xLKqFSuLjwE?t=805

Comparing with @akeller33’s code was most helpful. Thanks for sharing!

2 Likes

Hi, @arc6358831141,

Yes, the if header that you added is necessary in order to match user_input to the appropriate instance of Stack.

what is the problem in my code it is not
giving right output

from stack import Stack

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

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 {0} 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 {0} for {1}".format(letter,name))

user_input = input("")

if user_input in choices:

  for i in range(len(stacks)):

    if user_input == choices[i]:

      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 {0} moves, and the optimal number of moves is {1}".format(num_user_moves,num_optional_moves))

Lol wow I’ve spent hours trying to figure out what was wrong with my code only to find out it was just how I was running it. Thank you for posting this I could’ve been here for easily double the time.

How could I be so dumb to miss this piece of text XD:
python3 -c ‘import script; script.get_input()’

Hi all, I just finished doing the Tower of Hanoi problem from the Computer Science course and I am not getting the output that I am expected to get. I am not sure where I went from but help is appreciated. Thanks!

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 += [left_stack, middle_stack, 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(i)

num_optimal_moves = (2 ** num_disks) - 1
print("\nThe fastest you can solve this game is in {0} 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 {0} for {1}”.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 {0} moves, and the optimal number of moves is {1}".format(num_user_moves, num_optimal_moves))

Here because I’ve been struggling with it for a few hours.
My method is to do it on my own as far as I can, then watch the helper video and make sure I was doing it all right up until that point, then pause it and figure out the next chunk, watch the video again to make sure it’s right.
What messed me up is that I WAS RIGHT and THE VIDEO IS WRONG!!!
I followed the instructions perfectly on the task list and I had my if user_input == choices[i] line, but when I saw he didn’t have it, I was like, “oh, okay” and took it out, though I didn’t understand why, because the instructions clearly said to include it, but I thought “well, this guy is the professional, so maybe it’s redundant.” It literally threw me off for HOURS watching and rewatching his video to see what I did wrong. I found someone who had posted their solution on GitHub and that’s when I saw that they had that line that I had removed (when I was right the first time)

So yeah, the video is wrong. Just putting it out there for anyone else who comes to this with issues.

1 Like