Towers of Hanoi

Hello guys,

For the love of all that is sacred… I cannot get this exercise done.
https://www.codecademy.com/paths/computer-science/tracks/linear-data-structures/modules/cspath-stacks/projects/towers-of-hanoi
I get stuck on the last bit cannot get it working as intended.

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} moves".format(moves=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("Press {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]
    else:
      print("Invalid choice, please pick from below list:\n")
#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. 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
    else: 
      print("\n\nInvalid Move. Lower disk is smaller. Try Again")
    break
print("\n\nYou completed the game in {0} moves, and the optimal number of moves is {1}".format(num_user_moves, num_optimal_moves))
      

It looks like it skips the if and elif statement in the last while True loop.
I`m very now to coding, so please bare with me.
If you could give me a hint of where to look instead of just giving me working code, that would be awesome :slight_smile:

Kind Regards,

If by skip you mean the condition isn’t met, then that’s where you would look isn’t it?
You probably want to avoid the word “working” as well, and instead consider what’s different from what you expect, and what code is responsible for that part of the behaviour.

I found the issue. After line 43 I forgot to insert the if user_input == choises[i]
Small mistakes, big changes,
What would a normal expression be for code that is not working as expected?

I don’t know about normal, but the difference between what’s wanted and what’s observed is like a big shiny arrow pointing at where the bug is.
So the word “(not) working” is like discarding the solution. Terrible word.

Some condition is not being met. What should have made it be met? Did that happen? What’s the difference there? What should have made that different? … repeat until bug has been found.

(condition not met -> stack empty, shouldn’t have been -> stack came from taking user input -> didn’t get the stack indicated by user -> logic for associating user input with stack wrong (a loop that isn’t a loop at all))

For a lot of bugs, working your way backwards through events from the observed difference in behaviour will lead you right to the offending code.

Just a note about the video, he uses

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():

You can also use the .is_empty() function instead of the “== 0”

if from_stack.is_empty():
      print("\n\nInvalid Move. Try Again")

elif to_stack.is_empty() or from_stack.peek() < to_stack.peek():

It should be the same thing.

1 Like

I was wondering about that already, but since both of them worked i decided to go with the first option as provided in the video.
Would there be any arguments against that?
And thanks for you earlier reply, learned quite a bit from it!
I`m on this code path on my own, so some input from others helps :slight_smile:

Thank you so much for posting this issue, as I am also new to coding and was also having trouble just towards the end with my get_input() method not functioning properly. Should have searched the community boards sooner. Thanks again for the post.

is_empty is less information than the length and depending on the data structure there may be less work required to obtain it (since in this case you implemented the data structure, you already know whether that’s the case)