7.4 Python File Handling

Introduction to File Handling

File handling is an essential part of any programming language. Python makes it easy to work with files, allowing you to read, write, and manipulate file data efficiently.

Why File Handling?

  • Store data permanently
  • Process large datasets
  • Save program output
  • Read configuration files

Basic File Operations

Opening and Closing Files

# Open a file
file = open('example.txt', 'r')  # 'r' for reading
# Do something with the file
file.close()  # Always close the file when done

# Better way using 'with' statement (recommended)
with open('example.txt', 'r') as file:
    # File operations go here
    pass  # 'with' automatically closes the file

File Modes

Mode Description
'r' Read (default). Opens file for reading, error if file doesn't exist.
'w' Write. Opens file for writing, creates the file if it doesn't exist, truncates the file if it exists.
'a' Append. Opens file for appending, creates the file if it doesn't exist.
'x' Create. Creates the specified file, returns an error if the file exists.
'b' Binary mode (e.g., 'rb', 'wb', 'ab', 'xb').
'+' Open for updating (reading and writing).

Reading from Files

Reading Methods

# Read the entire file
with open('example.txt', 'r') as file:
    content = file.read()
    print(content)

# Read line by line
with open('example.txt', 'r') as file:
    for line in file:
        print(line.strip())  # strip() removes extra newlines

# Read all lines into a list
with open('example.txt', 'r') as file:
    lines = file.readlines()  # Returns a list of lines
    for line in lines:
        print(line.strip())

# Read a specific number of characters
with open('example.txt', 'r') as file:
    first_100 = file.read(100)  # Reads first 100 characters
    print(first_100)

Writing to Files

Writing Methods

# Write to a file (overwrites existing content)
with open('output.txt', 'w') as file:
    file.write("Hello, World!\n")
    file.write("This is a new line.")

# Append to a file
with open('output.txt', 'a') as file:
    file.write("\nThis line is appended.")

# Writing multiple lines
lines = ["First line\n", "Second line\n", "Third line\n"]
with open('output.txt', 'w') as file:
    file.writelines(lines)

File Object Methods

Common File Methods

with open('example.txt', 'r+') as file:
    # Get current position
    position = file.tell()
    print(f"Current position: {position}")
    
    # Read first 10 characters
    content = file.read(10)
    print(f"Read: {content}")
    
    # Get new position
    position = file.tell()
    print(f"New position: {position}")
    
    # Move to a specific position
    file.seek(0)  # Go to the beginning of the file
    
    # Check if file is readable/writable
    print(f"Readable: {file.readable()}")
    print(f"Writable: {file.writable()}")
    
    # Write at current position
    file.write("New content")
    
    # Flush the internal buffer
    file.flush()
    
    # Get file descriptor
    print(f"File descriptor: {file.fileno()}")
    
    # Check if file is closed
    print(f"Is closed: {file.closed}")

# After 'with' block
print(f"Is closed: {file.closed}")  # True

Handling File Exceptions

Try-Except with Files

try:
    with open('nonexistent.txt', 'r') as file:
        content = file.read()
        print(content)
except FileNotFoundError:
    print("Error: The file does not exist.")
except PermissionError:
    print("Error: You don't have permission to read this file.")
except Exception as e:
    print(f"An unexpected error occurred: {e}")
finally:
    print("File operation completed.")

Working with CSV Files

CSV Module

import csv

# Writing to a CSV file
with open('students.csv', 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(["Name", "Age", "Grade"])
    writer.writerow(["Alice", 20, "A"])
    writer.writerow(["Bob", 22, "B"])
    writer.writerow(["Charlie", 21, "A-"])

# Reading from a CSV file
with open('students.csv', 'r') as file:
    reader = csv.reader(file)
    for row in reader:
        print(f"Name: {row[0]}, Age: {row[1]}, Grade: {row[2]}")

# Using DictReader and DictWriter
with open('students.csv', 'r') as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(f"{row['Name']} is {row['Age']} years old with grade {row['Grade']}")

Working with JSON Files

JSON Module

import json

# Python dictionary
data = {
    "name": "John",
    "age": 30,
    "city": "New York",
    "languages": ["Python", "JavaScript", "Java"],
    "is_student": False
}

# Writing JSON to a file
with open('data.json', 'w') as file:
    json.dump(data, file, indent=4)

# Reading JSON from a file
with open('data.json', 'r') as file:
    loaded_data = json.load(file)
    print(loaded_data["name"])  # Output: John
    print(loaded_data["languages"][0])  # Output: Python

Practice Exercises

Exercise 1: File Word Counter

Write a Python program that reads a text file and counts the number of words in it. The program should:

  1. Prompt the user for a filename
  2. Read the file
  3. Count the number of words
  4. Print the result
def count_words(filename):
    try:
        with open(filename, 'r') as file:
            content = file.read()
            words = content.split()
            return len(words)
    except FileNotFoundError:
        return "File not found."
    except Exception as e:
        return f"An error occurred: {e}"

# Get filename from user
filename = input("Enter the filename: ")
word_count = count_words(filename)
print(f"The file contains {word_count} words.")

Exercise 2: Student Grade Book

Create a program that allows you to manage student grades using a CSV file. The program should:

  1. Allow adding new students with their grades
  2. Display all students and their grades
  3. Calculate and display the average grade
  4. Save the data to a CSV file
import csv
import os

FILENAME = 'grades.csv'

def add_student():
    name = input("Enter student name: ")
    while True:
        try:
            grade = float(input("Enter student grade (0-100): "))
            if 0 <= grade <= 100:
                break
            else:
                print("Grade must be between 0 and 100.")
        except ValueError:
            print("Please enter a valid number.")
    
    # Check if file exists, if not write headers
    file_exists = os.path.isfile(FILENAME)
    
    with open(FILENAME, 'a', newline='') as file:
        writer = csv.writer(file)
        if not file_exists:
            writer.writerow(["Name", "Grade"])
        writer.writerow([name, grade])
    
    print(f"{name} with grade {grade} has been added.")

def display_grades():
    try:
        with open(FILENAME, 'r') as file:
            reader = csv.reader(file)
            header = next(reader, None)
            if header:
                print(f"{header[0]:<20} {header[1]}")
                print("-" * 25)
                
                grades = []
                for row in reader:
                    if len(row) >= 2:  # Ensure row has at least 2 elements
                        print(f"{row[0]:<20} {row[1]}")
                        try:
                            grades.append(float(row[1]))
                        except ValueError:
                            pass
                
                if grades:
                    average = sum(grades) / len(grades)
                    print("\nAverage grade:", f"{average:.2f}")
    except FileNotFoundError:
        print("No grades recorded yet.")

def main():
    while True:
        print("\nGrade Book Menu:")
        print("1. Add Student")
        print("2. View Grades")
        print("3. Exit")
        
        choice = input("Enter your choice (1-3): ")
        
        if choice == '1':
            add_student()
        elif choice == '2':
            display_grades()
        elif choice == '3':
            print("Goodbye!")
            break
        else:
            print("Invalid choice. Please try again.")

if __name__ == "__main__":
    main()