Towers of Hanoi - TypeError

Hi everyone,
In project Towers of Hanoi (project url) I follow the instructions step by step
but when I try to run the code it give an error
New

The error as I understand because I am trying to compaire an int value from to_stack object with an None value
from to_stack
to_stack object not filled yet so it hans’t any value

Hi @cssninja03060,

Why are you using the and operator on line 57 instead of or? If one of the stacks is empty, you should not need to use the peek method on it.

We would like to see the code that precedes what is in your screen capture.

1 Like

Thanks a lot,
the problem solved

What did you do to fix the code on line 57? I’ve got the same problem. Can you paste the corrected code?

Try something like this for whatever corresponds to line 57 in the original post …

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

Note the use of or in the correct code instead of and. When the first operand of an or operation evaluates to True, the second operand is not evaluated.

My code gets hung up on Line 50 with an invalid syntax error. I’m trying to compare the values of the to and from disks using the Stack method peek(). Can someone tell me what I’m doing wrong? It’s specifically this line of code:
elif (to_stack.get_size() == 0) or (to_stack.peek() > from_stack.peek()):

***Full 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("\nEnter 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]).upper() for stack in stacks]
  while True:
    for i in range(0, 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(0, 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()
    if from_stack.size() == 0:
      print("\n\nEmpty Stack. Try Again")
    print("\nWhich stack do you want to move to?\n")
    to_stack = get_input()
    elif (to_stack.get_size() == 0) or (to_stack.peek() > from_stack.peek()):
      disk = from_stack.pop()
      to_stack.push(disk)
      num_user_moves += 1
    else:
      print("\n\nInvalid Move. 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))

Is this an indentation error?

Hi @tbswitze,

Could you copy and paste the full message that notified you of a SyntaxError?

$ python3 script.py
File “script.py”, line 50
elif (to_stack.get_size() == 0) or
(to_stack.peek() > from_stack.peek())
:
^
SyntaxError: invalid syntax

Here’s the error message. Thanks everyone for taking a look at this .

I don’t think so. The program ran fine until I tried to implement the elif condition.

@tbswitze,

Do you have this split into two or three lines? …

elif (to_stack.get_size() == 0) or
(to_stack.peek() > from_stack.peek())
:

If so, try to get it all on one line by removing line breaks.

It’s all on one line of code. No line breaks.

I got it. Thanks for looking at the code. Bottom line: I didn’t appreciate the difference between
stack.get_size() == 0
and
stack.is_empty() for the elif conditions. Not the same tests, clearly. Good lesson.

Here’s the updated code:

#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.is_empty() == True:
      print("\n\nEmpty Stack. Try Again")
    elif (to_stack.is_empty() == True) or (to_stack.peek() > from_stack.peek()):
      disk = from_stack.pop()
      to_stack.push(disk)
      num_user_moves += 1
    else:
      print("\n\nInvalid Move. Try Again")
    for stack in stacks:
    	stack.print_items()  
  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))
1 Like

I’m having a problem at the same spot but instead of getting back an error message I always get my own error: “Invalid Move. Try Again!”

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 {} 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 i in stacks:
    i.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.is_empty()):
      print("\n\nInvalid Move. Try Again")
    elif (to_stack.is_empty()) 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))

Hi @dgoelitz,

The problem is in your get_input() function.

The purpose of the final for loop within that function is to identify and return a reference to the Stack that the user selected. Accordingly, within that loop, this statement should execute only when user_input is equivalent to choices[i]:

          return stacks[i]

Precede that return statement with an if block header that checks for that equivalence.

appylpye,
Thank you so much! I think I had deleted that line because I thought it wasn’t in the video walkthrough. I really appreciate your help! Now the game is working perfectly which is great because I really wanted to play it when I was done.

1 Like

You are correct that it is not in the video walkthrough (as of December 28, 2018):

However, that is a mistake. Without the if block header, the for loop always will return the Stack that is at index 0 of stacks. This happens during the first iteration of the loop.

Hi,
I am having the same problem with the Syntax Error message:
grafik

This is the full code I have written:

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 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")
      
    else 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))

Thanks!!

you forgot a colon after your else keyword