HOSTEL COMPLAINT SYSTEM (1st Semester Python Project)

Hostel Complaints System
Project Walkthrough

Console Based
Hostel Complaints System

A complete breakdown of how this Python project works: file based persistence, complaint classification, admin moderation, and the logic inside every core function.

Python Console App File I/O COMSATS Islamabad

First semester project: structured file storage without any external database.

What the program does

Python based complaint management system for hostels. Uses plain text files inside a Data/ folder to store everything: individual complaint files, a serial counter, an active index, and a resolved archive. The system survives restarts and requires no setup.

Complaint Submission
Students enter name, room, choose main category + subcategory, and write complaint details.
Categorized Taxonomy
Six main categories: Food, Water, Electricity, Internet, Room Maintenance, Other. Subcategories with custom entry.
Serial Number
Auto incrementing counter stored in serial_counter.txt ensures unique IDs across runs.
Admin Panel
Password protected. View unresolved complaints, see full details, mark resolved, view resolved history.
Dual Storage
Individual complaint files (complaint_N.txt) + index file for quick listing. Resolved moved to archive.
Portable Paths
Uses os.path.join and os.makedirs to work on Windows, Linux, macOS without changes.

File system infrastructure

All data lives inside a Data/ folder next to the script. Inside, a complaints/ directory holds every complaint as a separate text file. The program creates everything automatically if missing.

Python
import os

script_dir = os.path.dirname(os.path.abspath(__file__))
data_dir = os.path.join(script_dir, "Data")
complaints_dir = os.path.join(data_dir, "complaints")
os.makedirs(complaints_dir, exist_ok=True)

serial_file = os.path.join(data_dir, "serial_counter.txt")
index_file = os.path.join(data_dir, "complaint_index.txt")
resolved_file = os.path.join(data_dir, "resolved_complaints.txt")
Data folder structure
Data/
├── serial_counter.txt
├── complaint_index.txt
├── resolved_complaints.txt
└── complaints/
    ├── complaint_1.txt
    ├── complaint_2.txt
    └── ...

Serial number generator

Atomic increment operation. Reads the current value, adds one, writes back, and returns the new serial. The r+ mode and seek(0) ensure the file is overwritten from the beginning.

Python
def get_next_serial():
    with open(serial_file, "r+") as f:
        serial = int(f.read()) + 1
        f.seek(0)
        f.write(str(serial))
    return serial
Why this works: The file contains only a single integer. Reading consumes the content, moving the pointer to the end. seek(0) moves it back to the start before writing, so we overwrite the old value instead of appending.

Complaint categories

Six main categories mapped to specific subcategories using a dictionary. Users first pick a main category, then a subcategory from a dynamic list. The "Other" option allows custom subcategory input.

1. Food Issues
2. Water Supply
3. Electricity Problems
4. Internet Issues
5. Room Maintenance
6. Other Complaints
Python
subcategories = {
    "Food Issues": ["Food Quality", "Meal Timings", "Canteen Staff Behavior", "Other"],
    "Water Supply": ["Drinking Water Problems", "Wash Water Issues", "Other"],
    "Electricity Problems": ["Power Outages", "Voltage Issues", "Other"],
    "Internet Issues": ["No Internet Access", "Slow Internet Speed", "Other"],
    "Room Maintenance": ["Room Cleaning Required", "Bathroom Not Cleaned", "Broken Items", "Other"],
    "Other Complaints": ["User Defined"]
}
Dynamic subcategory selection: After picking a main category, the program displays the matching subcategory list. If "Other" or "User Defined" is selected, it prompts for custom text.

Submitting a complaint

The submission process collects name, room, category, subcategory, and details. It then generates a serial number, writes a detailed complaint file inside the complaints/ directory, and appends a summary line to complaint_index.txt.

Python — writing complaint file
filename = os.path.join(complaints_dir, f"complaint_{serial}.txt")
with open(filename, "w") as f:
    f.write(f"Complaint No: {serial}\n")
    f.write(f"Name: {name}\n")
    f.write(f"Room: {room}\n")
    f.write(f"Main Category: {category}\n")
    f.write(f"Sub Category: {subcategory}\n")
    f.write(f"Complaint: {details}\n")

file_append(index_file, f"{serial} | {name} | Room {room} | {category}")
Complaint Record
Complaint No: 7
Name Ahmed Raza
Room Number G-22
Main Category Water Supply
Sub Category Drinking Water Problems
Details No water in the third floor coolers since two days. The coolers on floor 3 have been empty despite multiple requests to the maintenance staff.

Admin authentication

Simple hardcoded password check. While not secure for production, it demonstrates a basic access control layer for a console project. The password is stored directly in the function.

Python
def admin_login():
    password = input("Enter admin password: ")
    return password == "admin123"
admin login
Enter admin password: admin123
Access granted.

Admin Panel:
1. View Current Complaints
2. View Resolved Complaints
3. Logout
Select an option: _

Viewing and resolving complaints

The admin reads complaint_index.txt to display all unresolved complaints. Entering a serial number shows the full complaint file and offers to mark it as resolved.

Python — resolve complaint
def resolve_complaint(serial):
    with open(index_file, "r") as f:
        lines = f.readlines()
    new_lines = []
    resolved_line = ""
    for line in lines:
        if line.startswith(f"{serial} "):
            resolved_line = line
        else:
            new_lines.append(line)
    with open(index_file, "w") as f:
        f.writelines(new_lines)
    file_append(resolved_file, resolved_line.strip())
Filter pattern: The function reads the entire index, filters out the line matching the serial (using startswith to avoid partial matches), writes back the remaining lines, and appends the removed line to the resolved archive. The original complaint file stays untouched.

File formats

Three core text files maintain the system state. Everything is plain text, human readable, and easy to debug.

Data/serial_counter.txt
7
Data/complaint_index.txt
5 | Ali | Room 104 | Internet Issues
6 | Sara | Room 207 | Electricity Problems
Data/resolved_complaints.txt
2 | Bilal | Room 112 | Food Issues
4 | Zain | Room 089 | Room Maintenance

Full execution map

Start └─ main() ├─ create directories and files if missing ├─ while True: main menu │ ├─ 1 → submit_complaint() │ │ ├─ collect name / room │ │ ├─ display categories → pick main │ │ ├─ display subcategories → pick / custom │ │ ├─ collect details │ │ ├─ get_next_serial() (read+write serial_counter.txt) │ │ ├─ write complaint_<serial>.txt │ │ └─ append summary to complaint_index.txt │ ├─ 2 → admin_panel() │ │ ├─ admin_login() (password check) │ │ └─ while True: admin menu │ │ ├─ 1 → view_complaints() │ │ │ ├─ read complaint_index.txt │ │ │ ├─ show list │ │ │ ├─ prompt for serial │ │ │ ├─ show complaint file │ │ │ └─ optionally resolve_complaint() │ │ │ ├─ filter line from index │ │ │ └─ append to resolved_complaints.txt │ │ └─ 2 → view_resolved() (print resolved_complaints.txt) │ └─ 3 → exit

What this teaches

File I/O fundamentals
Reading, writing, appending, and managing multiple text files as a makeshift database.
Data structures
Lists for categories, dictionaries for subcategories, and formatted strings for persistence.
Modular design
Each feature isolated in its own function. The main menu delegates to specific handlers.
Atomic operations
Using r+ and seek to safely increment a counter without race conditions.
Path abstraction
os.path.join and os.makedirs make the code run anywhere.
Separation of active / resolved
Moving records between files instead of using deletion flags simplifies queries.

From physical register to digital system

The idea came from our hostel's messy physical complaint register: just a notebook with no organization. I started with an execution map on a page, improving it again and again as I added parts to overcome limitations. When I began coding, if I could not implement something complex, I changed it into a simpler solution that still worked. I built it step by step, using basic tools like lists and text files, until it became a complete system. It taught me that starting with a clear personal idea and adapting as you go turns a concept into a real working program.

If you want to extend this project: add timestamps, implement complaint searching, allow students to track status, or convert the file storage to SQLite. The structure is ready for incremental improvement.