2

I have no idea how to fix this. I've tried retyping the program.

I get an unexpected indentation error for the last main function.

resident = 81
nonresident = 162


def main():

    # initialize counters and total tuition
    resident_counter = 0
    nonresident_counter = 0
    total_tuition = 0

    print("Name \tCode\tCredits\tTuition")
    print

    try:
        # open the data file
        infile = open('enroll.txt', 'r')

        # read the first value from the file
        student_name = infile.readline()

        # continue reading from file until the end
        while student_name != '':

            # strip the new line character and print the student's name
            student_name = student_name.rstrip('\n')
            print(student_name, end='\t')

            # read the code type, strip the new line, and print it
            code = infile.readline()
            code = code_type.rstrip('\n')
            print(code_type, end='\t')

            # read the number of credits, strip the new line, and print it
            credits = infile.readline()
            credits = int(credits)
            print(format(credits, '3.0f'), end='\t')

            # check the room type and compute the rental amount due 
            # increment the appropriate counter
            if code_type == "R" or room_type == "r":
                payment_due = credits * resident
                resident_counter += 1
            elif code_type == "N" or room_type == "n":
                payment_due = credits * nonresident
                nonresident_counter += 1
            elif code_type != "R" or code_type != "r" or code_type != "N" or code_type != "n":
                payment_due = 0

            # accumulate the total room rent
            tuition += payment_due

            # print the appropriate detail line
            if payment_due == 0:
                print('invalid code')
            else:
                print('$', format(tuition, '8,.2f'))

            # get the next studen't name
            student_name = infile.readline()

        # close the input file
        infile.close()

        # print the counters and payment total amount
        print
        print('total number of resident students: ', resident_counter)
        print('total number of nonresident: ', nonresident_counter)
        print
        print('total students: ', end='')
        print('$', format(tuition, ',.2f'))
# execute the main function

main()
Matthew Adams
  • 9,426
  • 3
  • 27
  • 43
  • 3
    As a side note: Writing `print` by itself won't print a blank line in Python 3, it'll just look up the value of the `print` function and do nothing with it. You probably want `print()`. Also, you probably want `with open('enroll.txt', 'r') as infile` instead of doing manual `close` calls; if you're just learning how `try` works you're just asking for trouble trying to do manual cleanup. – abarnert Nov 05 '12 at 20:08
  • PS, where did you copy the code from? If we know what you're trying to do, we can better guess how to do it… – abarnert Nov 05 '12 at 20:19
  • One last thing: An explicit loop around `readline(f)` is usually worth replacing with a `for line in f:`. It's easier to read, it eliminates the possibility of fencepost errors, etc. In your case, you're dealing with batches of three lines, rather than line by line, which makes this trickier—but you can just do `for (student, code, credits) in grouper(3, infile):` (see http://stackoverflow.com/questions/1624883/alternative-way-to-split-a-list-into-groups-of-n for `grouper`). – abarnert Nov 06 '12 at 19:30
  • I didn't copy this code. I wrote it for a class assignment and got frustrated after working it over and over with it not working. – David German Nov 07 '12 at 19:47
  • Then why did you add the `try:` line in the first place? – abarnert Nov 07 '12 at 20:02

7 Answers7

6

You don't have an except clause to match the try.

Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
5

Despite what everyone else is saying, if you have a try, you don't have to have an except: you must have an except or a finally.

That may seem nitpicky, but it's pretty plausible that the code you were copying was actually using finally (e.g., to make sure some cleanup code always gets run—given that it's doing C-/Java-style manual cleanup).

At any rate, adding an except clause is not the right answer. If you're actually looking to handle or ignore errors, then yes, add an except clause. If you're looking for somewhere to add cleanup code that gets run even on an error, add a finally clause instead. If you don't want either, just remove the try line.

abarnert
  • 354,177
  • 51
  • 601
  • 671
2

you are mixing room type and code type in your if else statement. You are also missing your except statement. This should be your last two lines before calling main.

It should read:

except IOError:
    print('an error occurred trying to open or read enroll.txt')
mata
  • 67,110
  • 10
  • 163
  • 162
melissa
  • 21
  • 1
1

You are using the try statement. It means that you MUST have an except block

try:
    some code
except:
    pass

It is simplification, but will solve your problem.

alexvassel
  • 10,600
  • 2
  • 29
  • 31
  • 1
    As I said on another answer: "`except: pass` basically means that if there is a problem anywhere in the `try: `block of code, you do nothing, instead of handling the error. You generally don't want to use `except: pass`, especially as a "fix" to the indent problem." – Matthew Adams Nov 05 '12 at 19:58
  • Sure, but to explain smth to a new python guy it is possible to use it (IMHO). – alexvassel Nov 05 '12 at 20:00
1

The other answers have (correctly) pointed out that you need to have an except to go with your try: (or not use a try altogether). I'm going to try to explain how you could go about debugging similar issues in the future, since these can be very annoying to debug.

Your error message most likely looked something like this:

  File "test.py", line 74
    main()
    ^
IndentationError: unexpected unindent

At first glance, that doesn't seem too helpful, and it's definitely not very clear.

The fact that you "tried retyping the program" sounds like you saw IndentationError and thought, "this means my indents are messed up; maybe there's an extra space somewhere or a mixture of spaces and tabs or something." Those are definitely valid IndentationErrors, and retyping the program would fix them, if you didn't make the same typing error again. (On a side note, I believe that any text editor worth using will have the option to convert all of your tabs to 4 spaces to avoid a lot of indent headaches.)

However, looking at the error text, we see "unexpected unindent". To me this sounds kind of like gibberish, but what it means is that, when python was looking at your program, it ran into a line that it thought should be indented more than it was. (Unfortunately, this same kind of error can be called "unexpected unindent" or "expected an indented block", and it can even show up as a plain old SyntaxError: invalid syntax.)

So knowing what the error message means, we can look back through the code to see why python thought that main() was indented strangely- though we have to be careful because python isn't always right about where the problem actually is. Here would be something like my thought process:

  • There's a function definition right before main() is called, maybe that function wants main() to be inside it? No that isn't it, because python only really expects at least one line of code after a function definition.
  • What else "wants" code to be indented after it? if, elif, and while all do, but all of them have code after them as well.
  • The only other "indenter" is try:. At this point, you either know that try: needs to be followed by a except: or a finally: and you fix it, or you don't. If you don't know that, than you could still see that try: is followed by an indented block, and, given that it is a likely culprit for you error, decide that it's time to look up what try: does.

Well I hope that helps troubleshooting problems like this in the future, and check out abarnert's answer and my link for more on handling errors with try/except/else/finally statements.

Matthew Adams
  • 9,426
  • 3
  • 27
  • 43
0
  1. As noted by LevLevitsky and david above, there's no except clause. The easiest way to solve this is adding a line like the following to your code before the call to main:

    except: pass
    
  2. The second comment I have to your code is more stylistic, but you could add the following, before your call to main and after the except clause:

    if __name__ == '__main__':
        main()
    
hd1
  • 33,938
  • 5
  • 80
  • 91
  • 1
    `except: pass` basically means that if there is a problem anywhere in the `try:` block of code, you do nothing, instead of handling the error. You generally don't want to use `except: pass`, especially as a "fix" to the indent problem. – Matthew Adams Nov 05 '12 at 19:56
  • @MatthewAdams it was the "easiest way to solve this", not the best, nor the recommended way. – hd1 Nov 05 '12 at 19:57
  • Right, but I wanted to make that clear to any newer users reading this. – Matthew Adams Nov 05 '12 at 19:58
  • @MatthewAdams you should really vote my answer down as well. I'd do it but SO won't let me. – hd1 Nov 05 '12 at 20:07
  • I haven't voted anyone's answer down. If you don't like your answer anymore, you can delete it (though it isn't horrible or anything IMO). – Matthew Adams Nov 05 '12 at 20:11
  • How is this the easiest way to solve it? It's far easier to just remove the `try` line, isn't it? – abarnert Nov 05 '12 at 20:13
  • Presumably, @abarnert, there's a reason for the try clause. – hd1 Nov 05 '12 at 20:15
  • 1
    Maybe, but if you have no idea what it is, you're never going to figure it out by silently throwing away exceptions; better to let it raise and see what needs to be done. (PS, how do you know the reason for the `try` clause isn't a `finally` rather than an `except`?) – abarnert Nov 05 '12 at 20:16
0

Besides the missing except or finally or the extra try... If you have a look at the edited code, you can see the strangely mixed color blocks in the indentation. It means that you are mixing tabs and spaces which can lead to problems like bad indentation. The reason is that the interpreter thinks differently about how the tabs should be interpreted (for example 8 vs. 4 column tab stops).

You must not mix tabs and spaces for the indentation. I personally would recommend to use only the spaces. Any decent editor is capable to expand TAB key to spaces and/or Untabify the existing mixture of tabs and spaces.

Community
  • 1
  • 1
pepr
  • 20,112
  • 15
  • 76
  • 139