Skip to content
Laviyx Learn

Try

Python Files, Exceptions and Modules Practice

Practise reading and writing files, handling errors with try/except, and using the json, datetime, re and collections modules.

Intermediate9 problemsUpdated

Review first: File Handling, Exceptions, JSON, Date & Time, Regular Expressions, Modules

  1. 1.Write a file, then read it

    Intermediate

    Write three lines (Asha,88, Ravi,95, Meera,79) to a file called scores.txt. Then read it back and print each name with its score, and the highest score.

    Show hint

    Open with "w" to write and "r" to read, inside with blocks. Each line needs a \n when writing, and .strip() when reading.

    Show solution
    Python
    with open("scores.txt", "w", encoding="utf-8") as f:
        f.write("Asha,88\n")
        f.write("Ravi,95\n")
        f.write("Meera,79\n")
    
    best = 0
    with open("scores.txt", "r", encoding="utf-8") as f:
        for line in f:
            name, score = line.strip().split(",")
            score = int(score)
            print(name, score)
            best = max(best, score)
    
    print("Highest:", best)
    Output
    Asha 88
    Ravi 95
    Meera 79
    Highest: 95

    The with statement closes the file automatically, even if an error happens inside the block.

  2. 2.Append to a log

    Intermediate

    Append the lines started, processing and finished to app.log in three separate open() calls, then print the file's contents and how many lines it has.

    Show hint

    Mode "a" adds to the end of a file; mode "w" would erase it each time.

    Show solution
    Python
    for message in ["started", "processing", "finished"]:
        with open("app.log", "a", encoding="utf-8") as f:
            f.write(message + "\n")
    
    with open("app.log", encoding="utf-8") as f:
        content = f.read()
    
    print(content, end="")
    print(len(content.splitlines()), "lines")
    Output
    started
    processing
    finished
    3 lines
  3. 3.Convert values safely

    Intermediate

    Convert every item in raw = ["10", "abc", "7.5", "", "42"] to an integer. Skip the ones that cannot be converted, printing a message for each, then print the valid numbers and their total.

    Show hint

    int() raises a ValueError for text that is not a whole number. Catch it with try / except ValueError.

    Show solution
    Python
    raw = ["10", "abc", "7.5", "", "42"]
    
    numbers = []
    for item in raw:
        try:
            numbers.append(int(item))
        except ValueError:
            print(f"Skipping {item!r}")
    
    print(numbers, sum(numbers))
    Output
    Skipping 'abc'
    Skipping '7.5'
    Skipping ''
    [10, 42] 52

    {item!r} shows the value with quotes, which makes the empty string '' visible in the message.

  4. 4.try, except, else, finally

    Intermediate

    Write divide(a, b) that prints the result of a / b in an else block, prints Cannot divide by zero for a ZeroDivisionError, and always prints done in a finally block. Call divide(10, 4) and divide(1, 0).

    Show hint

    else runs only when no exception was raised; finally runs every time.

    Show solution
    Python
    def divide(a, b):
        try:
            result = a / b
        except ZeroDivisionError:
            print("Cannot divide by zero")
        else:
            print("Result:", result)
        finally:
            print("done")
    
    
    divide(10, 4)
    divide(1, 0)
    Output
    Result: 2.5
    done
    Cannot divide by zero
    done
  5. 5.A custom exception

    Intermediate

    Create an InsufficientFundsError exception. Write withdraw(balance, amount) that raises it when the amount is more than the balance, and returns the new balance otherwise. Call it with (500, 200) and (500, 800), catching the error.

    Show hint

    A custom exception is a class that inherits from Exception. Raise it with raise InsufficientFundsError("message").

    Show solution
    Python
    class InsufficientFundsError(Exception):
        pass
    
    
    def withdraw(balance, amount):
        if amount > balance:
            raise InsufficientFundsError(f"Cannot withdraw {amount}; balance is {balance}")
        return balance - amount
    
    
    for amount in [200, 800]:
        try:
            print("New balance:", withdraw(500, amount))
        except InsufficientFundsError as error:
            print("Error:", error)
    Output
    New balance: 300
    Error: Cannot withdraw 800; balance is 500
  6. 6.Save and load JSON

    Intermediate

    Convert settings = {"theme": "dark", "font_size": 14, "plugins": ["git", "lint"]} to a JSON string with sorted keys and an indent of 2, and print it. Then parse the string back and print the second plugin.

    Show hint

    json.dumps(obj, indent=2, sort_keys=True) makes the string; json.loads(text) parses it.

    Show solution
    Python
    import json
    
    settings = {"theme": "dark", "font_size": 14, "plugins": ["git", "lint"]}
    
    text = json.dumps(settings, indent=2, sort_keys=True)
    print(text)
    
    loaded = json.loads(text)
    print(loaded["plugins"][1])
    Output
    {
      "font_size": 14,
      "plugins": [
        "git",
        "lint"
      ],
      "theme": "dark"
    }
    lint

    To work with files, use json.dump(obj, f) and json.load(f) (without the s), which write to and read from an open file.

  7. 7.Days between dates

    Intermediate

    For a course that starts on 2026-11-02 and ends on 2027-01-15, print the number of days between the dates, the date 30 days after the start, and the start date formatted like Monday, 02 November 2026.

    Show hint

    Subtracting two date objects gives a timedelta; use .days. Add a timedelta(days=30), and format with strftime("%A, %d %B %Y").

    Show solution
    Python
    from datetime import date, timedelta
    
    start = date(2026, 11, 2)
    end = date(2027, 1, 15)
    
    print((end - start).days)
    print(start + timedelta(days=30))
    print(start.strftime("%A, %d %B %Y"))
    Output
    74
    2026-12-02
    Monday, 02 November 2026

    date.fromisoformat("2026-11-02") converts a YYYY-MM-DD string into a date object, which is handy when dates come from a file or form.

  8. 8.Extract with a regular expression

    Intermediate

    From text = "Call 98200-11111 or 98300-22222. Office: 022-2345678.", extract every mobile number in the form 5 digits, a dash, 5 digits. Then check whether "411001" and "41100" are valid 6-digit PIN codes.

    Show hint

    re.findall(r"\d{5}-\d{5}", text) finds all matches. re.fullmatch(r"\d{6}", s) checks that the whole string matches.

    Show solution
    Python
    import re
    
    text = "Call 98200-11111 or 98300-22222. Office: 022-2345678."
    
    print(re.findall(r"\d{5}-\d{5}", text))
    
    for pin in ["411001", "41100"]:
        print(pin, bool(re.fullmatch(r"\d{6}", pin)))
    Output
    ['98200-11111', '98300-22222']
    411001 True
    41100 False

    Always write patterns as raw strings (r"...") so that backslashes reach the regex engine unchanged. re.search would accept "4110012" for \d{6} because it only needs a match somewhere; fullmatch requires the entire string to match.

  9. 9.Use the standard library

    Intermediate

    Using collections.Counter, print the two most common letters in "mississippi" with their counts. Then use the math module to print the square root of 2 rounded to 4 decimals and math.ceil(7 / 2).

    Show hint

    Counter(text).most_common(2) returns a list of (letter, count) pairs.

    Show solution
    Python
    import math
    from collections import Counter
    
    print(Counter("mississippi").most_common(2))
    print(round(math.sqrt(2), 4))
    print(math.ceil(7 / 2))
    Output
    [('i', 4), ('s', 4)]
    1.4142
    4

    "i" and "s" both appear 4 times. When counts tie, most_common keeps the order in which the items were first seen.