Python file reading and printing, with exceptions and terminations
Question: Hello I am a very new programmer who is self teaching Python. I have
encountered a very interesting problem and need some help in creating a
program for it. It goes like this

A hotel salesperson enters sales in a text file. Each line contains the
following, separated by semicolons: The name of the client, the service sold
(such as Dinner, Conference, Lodging, and so on), the amount of the sale, and
the date of that event. Write a program that reads such a file and displays
the total amount for each service category. Display an error if the file does
not exist or the format is incorrect.

  * Prompt for the name of the file to process and issue an error message and terminate if that file can’t be opened

  * Verify that each line has the correct number of items and terminate if it does not

  * Verify that the dollar amount is a valid floating-­‐point number and terminate if it is not 

  * Keep a list with the categories that are encountered (they may be different than below) and another list with the cumulative dollar amount for each category. These are two lists but the elements in one relate to the elements in the other (by position)

  * Close the file when all the data has been processed 

  * Display the categories and the total for each one

Our Sample text file looks something like this

    
    
    Bob;Dinner;10.00;January 1, 2015
    Tom;Dinner;14.00;January 2, 2015
    Anne;Lodging;125.00;January 3, 2015
    Jerry;Lodging;125.00;January 4, 2015
    

Here is what I am trying to do. I am trying to get an understanding of this
and have some help from experts on Stack Overflow to solve this problem while
learning. Thank you everyone!

    
    
    import sys
    def main():
    
        try:
            line = infile.readline()
            for line in infile:
                inputFileName = input("Input file name: ")
                infile = open(inputFileName, "r")
                fields = line.split(";")
    
                value = float(fields[1])
    
        except:
            print("Error: The file cannot be opened.")
            sys.exit(1)
    
    infile.close()
    main()
    


Answer: Here's a basic sketch. This is untested so likely contains typos, logic errors
and such. Also, it doesn't check all of the error conditions you mentioned.
However, it should be enough to get your started. The main trick is to just
[throw an
exception](https://docs.python.org/3.2/reference/simple_stmts.html#raise)
where you encounter an error, and [catch
it](https://docs.python.org/3.2/reference/compound_stmts.html#except) where
you can deal with it. That immediately stops processing the file as you
wanted. The other trick is to keep a
[dictionary](https://docs.python.org/3.2/tutorial/datastructures.html) mapping
category to total so you can keep a running total by category.

    
    
    def main():
        # Req 1.1: ask for a filename
        file_name = input("Input file name: ")
        try:
            # To keep things simple we do all the file processing
            # in a separate function. That lets us handle
            # any error in the file processing with a single
            # except block
            amount_by_category = process_file(file_name)
            # Req 6: display the categories - python will
            # display the contents of a data structure when we print() it
            print('Totals: ', amount_by_category)
        except Exception, e:
            # Reqs 1-3: display errors
            print('Error processing file:', e)
    
    def process_file(file_name):
            # Req 1.2: open the file
            infile = open(file_name, 'r')
            # Req 4.1: somewhere to remember the categories
            amount_by_catgeory = {}
            # Reqs 2-4: we are dealing with a many line file
            # Req 5: when we reach the end, python closes the file for us automatically
            for line in infile:
                # Req 2.1: each line should have 4 values separated by ;
                fields = line.split(';')
                # Req 2.2: does this line have 4 values?
                if len(fields) != 4:
                    raise Exception('Expected 4 fields but found %s' % len(fields))
                # Req 3: is the third value a number?
                value = float(fields[2])
                # Req 4.2: what category does this line belong to?
                category = fields[1]
                # Req 4.3.1: have we seen this category before?
                if not category in amount_by_category:
                    # Req 4.3.2: accumulations start from 0?
                    amount_by_category[category] = 0.0f
                # Req 4.4: increase the cumulative amount for the category
                amount_by_category[category] += value
    
            return amount_by_category
    

