i finished the project but for some reason when i want to move one data (in this case disk) to another stack i get the error message doesn’t matter if i’m trying to get data from an empty stack i get the message at Line 57, L-M-R doesn’t matter which one, after that Line 59 again L-M-R then error message (Line 73) this goes on forever until i input another letter how do i solve this?
for i in range(len(stacks)):
name = stacks[i].get_name()
letter = choices[i]
Iterating over indexes is … rarely the right thing to do
Turn it into a dictionary of {char: name} instead, and then you can do:
for letter, name in choices.items()
print("Enter {0} for {1}".format(letter, name))
And:
if user_input in choices:
return choices[user_input]
If you ever have two lists of something that you need to sync up like this, the right thing to do is probably to put them as pairs in a single list, or in this case a dict since you do lookup from one to the other
Not much gain here in terms of efficiency, but in preparation for situations where we have larger collections of objects, why not promote the mindset of favoring dictionary lookups over linear searches when it is possible?
I didn’t really like the solution promoted by the instructions.
if user_input in choices:
for i in range(len(stacks)):
if user_input == choices[i]:
return stacks[i]
With only three pegs, it’s not a big deal, but conceptually it’s kind of ugly to have the player pick an item from a list and then to have the program start looking for it from the beginning of the list.
I cleaned up codecademy’s solution a little bit. Got rid of stack.py because it’s just a list
def show_input_options(choices):
for name in choices:
print("Enter {} for {}".format(name[0], name))
def get_input(prompt):
choices = ['Left', 'Middle', 'Right']
letterToStack = dict(zip('lmr', stacks))
while True:
show_input_options(choices)
user_input = input(prompt)
if user_input.lower() in letterToStack:
return letterToStack[user_input]
print("\nLet's play Towers of Hanoi!!")
stacks = [[], [], []]
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"))
stacks[0] = list(range(num_disks, 0, -1))
num_optimal_moves = (2**num_disks) - 1
print("\nThe fastest you can solve this game is in {0} moves"
.format(num_optimal_moves))
num_user_moves = 0
while len(stacks[-1]) != num_disks:
while True:
print("\n\n\n...Current Stacks...")
for stack in stacks:
print(stack)
from_stack = get_input("\nWhich stack do you want to move from?\n> ")
to_stack = get_input("\nWhich stack do you want to move to?\n> ")
if not from_stack:
print("\n\nInvalid Move. Try Again")
elif len(to_stack) == 0 or from_stack[-1] < to_stack[-1]:
disk = from_stack.pop()
to_stack.append(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)
)
I was thinking recently about whether Python is too high level as a first language, or if perhaps it’s arbitrary where one starts. There’s always a lower level.
This is a case of the language being higher level than the ideas implemented. I can’t figure out if that makes sense or not.
The issue of one’s first programming language is an interesting one. What’s best may vary with the person’s age and learning style. My first programming language was PL/I when I was 31 years old. It was OK, and did get me interested in programming. If I could do it all over again I would probably choose to start at a very early age with turtle graphics or some other sort of drawing program. The first time that one of my early teachers drew a coordinate grid on the chalkboard and started plotting shapes on it, I immediately took great interest in it. I would have really appreciated a system that enabled me to implement algorithms on such a grid.
I think it’s OK for one’s first programming language to be at a higher level than the ideas implemented, so long it offers pretty straightforward means of working with the early concepts that are taught.
We may be getting off topic. Should we split this into a new discussion?
I am somewhat unsettled regarding what the instructions should ask the user to do here. Perhaps, since we only have three Stack objects, making efficiency a trivial issue, we should just leave things as they are, with the user keeping a list of them instead of a dictionary. With Codecademy’s current offerings, users might feel more comfortable with implementing a list than a dictionary
In its content offerings, Codecademy teaches about lists before teaching about dictionaries. This is probably true of nearly all courses in Python. A list is simpler in that it is just a sequence of items, while a dictionary consists of key-value pairs. But, in real life, what is a more fundamental concept, a dictionary (a mapping) or a list?
We could argue that a list is the more fundamental of the two. On paper, we go to the store with a list of items to buy, rather than with a dictionary of items. However, in reality, we are going there with a mapping. Each of the items on the list must have a meaning before we would have any reason to write it on the list. So, for each item, the key is what is written on the paper list, and the value associated with each key is in our head, or we might say that the value is the actual item on the shelf. Early on in life, we start work with symbols, each of which is a key to something else. As soon as we start to use language, we are using a mapping.
Although the Python content here teaches lists prior to dictionaries, it teaches about variables before teaching about lists. Each variable has a name and a value. That is a key-value pair. So, while in name, lists are taught before dictionaries, we actually start working with mappings almost immediately. Perhaps the concept of a mapping should be discussed explicitly earlier in the lessons. Then users, as well as the authors of the content, might find it more comfortable to make greater use dictionaries in the later content, the current project included.
In fact, in a similar respect, some of the coursework uses dictionaries to create dictionaries, which they refer to by the general term, hash maps. As with the Stack class, when they have the user create a HashMap class, its instance variables are supported by a dictionary. This seeming circularity is acceptable, because they are not having the user explicitly use a Python dict to create the HashMap class. The coursework is just a mechanism for teaching how hash maps work, so what is under the hood doesn’t matter so much, except that the authors of the material should, perhaps, have brought that up and used it as an opportunity to discuss how essential hash maps, as dictionaries, are for the inner workings of Python itself.
Here are some links to the material on hash maps …