Today's lab looks at nested loops and indefinite loops from Chapter 8 and more on finding errors.

Mystery Point Game

Today, we are going to write a simple game where the user tries to find our mystery point in the graphics window. Lets first go through the program section by section:

Try running the program. How easy is it to win?

Giving Hints

Could you find the point without peeking at the IDLE shell? To make the game a bit easier, we will add hints. The first hint will be to tell the user if they need to click more to the left (or right) to find the point. Here is the pseudocode:

	if point clicked is to the left of mystery point
		give message "Too far left"
	else 
		give message "Too far right"
How can you tell if the point clicked is to the left of the mystery point? The x-coordinate tells how far left or right a point is, so, we compare the x-coordinates of the two points:
        if p.getX() < mysteryPoint.getX():
            t.setText("Click again! You were too far left")
        else:
            t.setText("Click again! You were too far right")

Now, add in the code that will give a hint to move up (or down) depending on where they clicked with respect to the mystery point. Your completed program should have a "left/right" hint and an "low/high" hint to make the game possible to do without looking at our diagonostics on the python shell.

Hint: Before the loop, set up another Text object, t2 to display the message about being too low or too high:

    t2 = Text(Point(0,-230), "")
    t2.setSize(16)
    t2.draw(w)

Finding Errors, II

In Lab 6, we looked at some common syntax errors and how to fix them. Most of those errors were missing punctuation (such at colons, quotes, or plus signs). Let's look at a few more errors that occur when using conditionals, loops, and functions:

# errors2.py-- modified from Zelle
# recursions.py
#   A collection of simple recursive functions from Zelle, 2nd Edition
#   (Some also include looping counterparts).

def fact(n)
    # returns factorial of n
    if n == 0:
        return 1
    else
        return n * fact(n-1

def reverse(s):
    # returns reverse of string s
    if s == "":
        return s
    elif:
        return reverse(s[1:]) + s[0]

def anagrams(s):
    # returns a list of all anagrams of string s
    if s == "":
        return [s]
    else:
        ans = []
        for w in anagrams(s[1:]):
            for pos in range(len(w)+1):
                    ans.append(w[:pos]+s[0]+w[pos:])
        return ans

def loopFib(n):
    # returns the nth Fibonacci number
    curr = 1
        prev = 1
    for i in range(n-2):
        curr, prev = curr+prev, curr
    return curr

def main():
    n = eval(input("Enter a number: "))
    s = input("Enter a string: ")
    print(n+"!= ", fact(n), "or, loopFig(n))
    print(s, "reversed is: ", reverse(s))
    print("\n anagrams: ", anagrams(s))

main()

Load the program into IDLE and run the program. A dialog box pops up and says "invalid syntax":


We have seen this one before, it's a missing colon (":") at the end of the function definition. Add it in and run again.

Again, we get an invalid syntax. What's wrong here? (Hint: same as the last one). Fix the error, and let's run the program again:

This one is different. IDLE has highlighted the word def, and yet that seems to spelled correctly. A general rule to follow: if you do not see an error on the current line, look above (usually for missing quotes or closing parenthesis). On the previous line, the function call to fact() is missing the closing parenthesis. Add it, and run the program again:

This one is a bit harder-- all the keywords are spelled correctly and there's no missing colons, parenthesis, or quotes. What's wrong? Python expected the word else (elif is only used when you need multiple tests in multi-way decision). Replace elif with else and try again:

The message says: unexpected indent. The line does seem to be indented for no reason (i.e. it's not part of a block of code in a loop or decision construct). Remove the extra indent and continue:

This is a common error. In plain English, it means that the end of the line ("EOL") was reached before the string finished. In other words, the string is missing its ending quotes. Add it in (right after the word or) and run the program again.

It now compiles! But we need to test it to make sure no run-time errors remain:

When reading the traceback message (all the red text), go to the very last line and see what it says. The message says we cannot use + for 'int' and 'string'. We only used + once in the line to concatenate n to a string. Since we want n to eventually be a string and printed to the screen, let's change it to a string (by using the str() function):

print(str(n)+"!= ", fact(n), "or", loopFig(n))

Running it again, a new run-time errors appears:

The message says that IDLE cannot find loopFig(). Scanning through the file, it looks we misspelled it! The function is called loopFib(). Fix the misspelling in the main() and try again...

Success! The program accepted input, processed it, and outputted it to the screen. Try with a couple of different inputs to test how it works.

If you finish early, you may work on the programming problems.