File Handling Practice Questions
Python File Handling & Data Persistence Practice Companion
This workbook contains 50 progressive, high-quality programming exercises categorized into 5 distinct levels of difficulty. Each question represents a functional, real-world data processing scenario solved using a strictly procedural, function-based paradigm.
Every single solution is complete and executable, utilizing built-in Python standard libraries (such as pathlib, csv, json, shutil, hashlib, and zipfile). There are zero object-oriented classes, zero database engines (no SQLite), and zero external data science packages (no Pandas) to ensure absolute compliance with the Phase 1 Python Foundations syllabus.
Table of Contents
Level 1: Basic File System & Text Operations
Question 1: Create and Write Text to File
Write a function write_notes(file_name, note_content) that creates a new text file and writes a string of notes to it using a safe context manager.
main.pyRunnabledef write_notes(file_name, note_content): """Creates a file and writes content to it""" with open(file_name, "w", encoding="utf-8") as file: file.write(note_content) ## Verification write_notes("quick_note.txt", "Study Python variables, functions, and file handling operations.") with open("quick_note.txt", "r", encoding="utf-8") as f: print(f.read()) import pathlib pathlib.Path("quick_note.txt").unlink()
Expected Output:
Study Python variables, functions, and file handling operations.
Question 2: Read Entire Text File
Write a function read_notes(file_name) that loads and returns the entire contents of an existing text file. If the file is not found, it must return a blank string.
main.pyRunnabledef read_notes(file_name): """Safely reads the entire contents of a file""" try: with open(file_name, "r", encoding="utf-8") as file: return file.read() except FileNotFoundError: return "" ## Verification pathlib.Path("temp_note.txt").write_text("Permanent storage initialized.", encoding="utf-8") print(f"Content: {read_notes('temp_note.txt')}") print(f"Missing File: '{read_notes('missing.txt')}'") pathlib.Path("temp_note.txt").unlink()
Expected Output:
Content: Permanent storage initialized. Missing File: ''
Question 3: Append Line to Text File
Write a function append_log(file_name, log_entry) that opens an existing file and appends a new message to the end without truncating previous contents.
main.pyRunnabledef append_log(file_name, log_entry): """Appends a new line of text to a log file""" with open(file_name, "a", encoding="utf-8") as file: file.write(log_entry + "\n") ## Verification append_log("events.log", "System Boot: Success") append_log("events.log", "User logged in: Admin") with open("events.log", "r", encoding="utf-8") as f: print(f.read().strip()) pathlib.Path("events.log").unlink()
Expected Output:
System Boot: Success User logged in: Admin
Question 4: Count Lines in Text File
Write a function count_lines(file_name) that counts and returns the number of physical rows inside a text file.
main.pyRunnabledef count_lines(file_name): """Counts lines inside a file""" count = 0 with open(file_name, "r", encoding="utf-8") as file: for line in file: count += 1 return count ## Verification pathlib.Path("lines.txt").write_text("Row 1\nRow 2\nRow 3\nRow 4\n", encoding="utf-8") print(f"Total Lines: {count_lines('lines.txt')}") pathlib.Path("lines.txt").unlink()
Expected Output:
Total Lines: 4
Question 5: Count Characters in Text File
Write a function count_characters(file_name) that counts and returns the total number of characters in a text file, including spaces and newlines.
main.pyRunnabledef count_characters(file_name): """Counts all characters in a file""" with open(file_name, "r", encoding="utf-8") as file: return len(file.read()) ## Verification pathlib.Path("chars.txt").write_text("Hello\nWorld!", encoding="utf-8") print(f"Total Characters: {count_characters('chars.txt')}") pathlib.Path("chars.txt").unlink()
Expected Output:
Total Characters: 12
Question 6: Count Words in Text File
Write a function count_words(file_name) that counts and returns the number of space-separated words inside a text file.
main.pyRunnabledef count_words(file_name): """Counts all words in a file""" with open(file_name, "r", encoding="utf-8") as file: content = file.read() return len(content.split()) ## Verification pathlib.Path("words.txt").write_text("Python file handling is easy.", encoding="utf-8") print(f"Word Count: {count_words('words.txt')}") pathlib.Path("words.txt").unlink()
Expected Output:
Word Count: 5
Question 7: Copy a Text File Line-by-Line
Write a function copy_text_file(source, destination) that streams text from a source file and writes it row-by-row into a destination file to conserve active RAM.
main.pyRunnabledef copy_text_file(source, destination): """Copies text file line by line""" with open(source, "r", encoding="utf-8") as src, open(destination, "w", encoding="utf-8") as dest: for line in src: dest.write(line) ## Verification pathlib.Path("origin.txt").write_text("Stream Copy Target.", encoding="utf-8") copy_text_file("origin.txt", "copied.txt") print(f"Copied: {pathlib.Path('copied.txt').read_text(encoding='utf-8')}") pathlib.Path("origin.txt").unlink() pathlib.Path("copied.txt").unlink()
Expected Output:
Copied: Stream Copy Target.
Question 8: Search for a Specific Word in a File
Write a function find_word_in_file(file_name, search_term) that searches a file and returns a list of integer line numbers (1-indexed) where the target search term exists as a substring.
main.pyRunnabledef find_word_in_file(file_name, search_term): """Finds lines containing the search term""" matching_lines = [] with open(file_name, "r", encoding="utf-8") as file: for idx, line in enumerate(file, 1): if search_term.lower() in line.lower(): matching_lines.append(idx) return matching_lines ## Verification pathlib.Path("search.txt").write_text("Learn Python.\nWrite clean functions.\nPersist data on disk.", encoding="utf-8") print(f"Lines containing 'Python': {find_word_in_file('search.txt', 'Python')}") print(f"Lines containing 'data': {find_word_in_file('search.txt', 'data')}") pathlib.Path("search.txt").unlink()
Expected Output:
Lines containing 'Python': [1] Lines containing 'data': [3]
Question 9: List Files in a Directory Using Pathlib
Write a function list_all_files(directory_path) that scans a directory path using pathlib.Path and returns a list of string file names (excluding folders).
main.pyRunnableimport pathlib def list_all_files(directory_path): """Returns a list of files in a directory""" dir_path = pathlib.Path(directory_path) file_list = [] if dir_path.exists() and dir_path.is_dir(): for item in dir_path.iterdir(): if item.is_file(): file_list.append(item.name) return sorted(file_list) ## Verification test_dir = pathlib.Path("test_list") test_dir.mkdir(exist_ok=True) (test_dir / "a.txt").touch() (test_dir / "b.txt").touch() print(f"Files inside folder: {list_all_files('test_dir' if False else test_dir)}") shutil = __import__("shutil") shutil.rmtree(test_dir)
Expected Output:
Files inside folder: ['a.txt', 'b.txt']
Question 10: Check if a Path Exists and is a File
Write a function verify_file_exists(path_string) that returns True if a path points to an existing file on disk, and False otherwise.
main.pyRunnableimport pathlib def verify_file_exists(path_string): """Verifies if a path exists and is a file""" target = pathlib.Path(path_string) return target.exists() and target.is_file() ## Verification print(f"Check active: {verify_file_exists('quick_note.txt')}") pathlib.Path("exists_test.txt").touch() print(f"Check exist_test.txt: {verify_file_exists('exists_test.txt')}") pathlib.Path("exists_test.txt").unlink()
Expected Output:
Check active: False Check exist_test.txt: True
Level 1 Checkpoint
Level 2: Advanced Text Processing & String Formatting
Question 11: Find and Replace Text Inside a File
Write a function file_replace(file_name, target_word, replacement_word) that reads a file, replaces all occurrences of a target word with a replacement string, and saves the updated text back to the same file.
main.pyRunnabledef file_replace(file_name, target_word, replacement_word): """Replaces words in a file in-place""" with open(file_name, "r", encoding="utf-8") as file: content = file.read() modified_content = content.replace(target_word, replacement_word) with open(file_name, "w", encoding="utf-8") as file: file.write(modified_content) ## Verification pathlib.Path("replace_test.txt").write_text("I love JavaScript and JavaScript development.", encoding="utf-8") file_replace("replace_test.txt", "JavaScript", "Python") print(pathlib.Path("replace_test.txt").read_text(encoding="utf-8")) pathlib.Path("replace_test.txt").unlink()
Expected Output:
I love Python and Python development.
Question 12: Remove All Empty Lines from a Text File
Write a function remove_empty_lines(file_name) that modifies a text file by removing any blank rows or rows consisting only of whitespace.
main.pyRunnabledef remove_empty_lines(file_name): """Removes all empty lines from a text file""" cleaned_lines = [] with open(file_name, "r", encoding="utf-8") as file: for line in file: if line.strip(): cleaned_lines.append(line) with open(file_name, "w", encoding="utf-8") as file: file.writelines(cleaned_lines) ## Verification pathlib.Path("empty_lines.txt").write_text("Row 1\n\n\nRow 2\n \nRow 3\n", encoding="utf-8") remove_empty_lines("empty_lines.txt") print(pathlib.Path("empty_lines.txt").read_text(encoding="utf-8")) pathlib.Path("empty_lines.txt").unlink()
Expected Output:
Row 1 Row 2 Row 3
Question 13: Extract Lines Containing Specific Pattern
Write a function extract_pattern_lines(source, output_dest, pattern) that copies lines from a source file to an output file only if they contain a specified substring pattern.
main.pyRunnabledef extract_pattern_lines(source, output_dest, pattern): """Extracts matching rows into a separate destination file""" extracted_count = 0 with open(source, "r", encoding="utf-8") as src, open(output_dest, "w", encoding="utf-8") as dest: for line in src: if pattern.lower() in line.lower(): dest.write(line) extracted_count += 1 return extracted_count ## Verification pathlib.Path("server.log").write_text("INFO: Server booted\nERROR: Database connection timeout\nINFO: Syncing logs\nERROR: Auth error\n", encoding="utf-8") extract_pattern_lines("server.log", "errors.log", "ERROR") print(pathlib.Path("errors.log").read_text(encoding="utf-8").strip()) pathlib.Path("server.log").unlink() pathlib.Path("errors.log").unlink()
Expected Output:
ERROR: Database connection timeout ERROR: Auth error
Question 14: Count Unique Words in a File (Word Frequency)
Write a function word_frequency(file_name) that counts the frequency of words in a text file and returns a dictionary of {word: count} formatted with clean, lowercase words (removing punctuation like ., ,, !).
main.pyRunnabledef word_frequency(file_name): """Calculates word frequency inside a file""" frequency = {} with open(file_name, "r", encoding="utf-8") as file: for line in file: words = line.split() for word in words: # Strip common punctuation characters clean_word = word.lower().strip(".,!?;:\"()[]{}") if clean_word: frequency[clean_word] = frequency.get(clean_word, 0) + 1 return frequency ## Verification pathlib.Path("freq.txt").write_text("Python, Python, and more Python! Coding is fun.", encoding="utf-8") freq = word_frequency("freq.txt") for k, v in sorted(freq.items()): print(f"{k}: {v}") pathlib.Path("freq.txt").unlink()
Expected Output:
and: 1 coding: 1 fun: 1 is: 1 more: 1 python: 3
Question 15: Reverse Line Order of a Text File
Write a function reverse_file_lines(file_name) that modifies an existing file in-place by reversing the order of its rows (the last line becomes the first line).
main.pyRunnabledef reverse_file_lines(file_name): """Reverses the lines of a text file in place""" with open(file_name, "r", encoding="utf-8") as file: lines = file.readlines() with open(file_name, "w", encoding="utf-8") as file: file.writelines(reversed(lines)) ## Verification pathlib.Path("reverse.txt").write_text("Line A\nLine B\nLine C\n", encoding="utf-8") reverse_file_lines("reverse.txt") print(pathlib.Path("reverse.txt").read_text(encoding="utf-8")) pathlib.Path("reverse.txt").unlink()
Expected Output:
Line C Line B Line A
Question 16: Split a Text File into Smaller Files
Write a function split_file(file_name, lines_per_file) that splits a large text file into smaller files, each containing at most lines_per_file lines. The split files should be named split_1.txt, split_2.txt, etc.
main.pyRunnabledef split_file(file_name, lines_per_file): """Splits a file into multiple sub-files of a maximum row count""" split_count = 0 with open(file_name, "r", encoding="utf-8") as file: chunk = [] for line in file: chunk.append(line) if len(chunk) == lines_per_file: split_count += 1 with open(f"split_{split_count}.txt", "w", encoding="utf-8") as out: out.writelines(chunk) chunk = [] # Flush remaining lines if chunk: split_count += 1 with open(f"split_{split_count}.txt", "w", encoding="utf-8") as out: out.writelines(chunk) return split_count ## Verification pathlib.Path("large.txt").write_text("Row 1\nRow 2\nRow 3\nRow 4\nRow 5\n", encoding="utf-8") total_splits = split_file("large.txt", 2) for i in range(1, total_splits + 1): sub_file = pathlib.Path(f"split_{i}.txt") print(f"split_{i}.txt:\n{sub_file.read_text(encoding='utf-8').strip()}") sub_file.unlink() pathlib.Path("large.txt").unlink()
Expected Output:
split_1.txt: Row 1 Row 2 split_2.txt: Row 3 Row 4 split_3.txt: Row 5
Question 17: Merge Multiple Text Files
Write a function merge_files(file_list, output_file) that merges a list of text file paths into a single master text file.
main.pyRunnabledef merge_files(file_list, output_file): """Merges contents of a list of text files into a single destination file""" with open(output_file, "w", encoding="utf-8") as dest: for file_name in file_list: with open(file_name, "r", encoding="utf-8") as src: dest.write(src.read()) if not dest.tell() or dest.read(-1) != "\n": dest.write("\n") # Ensure a trailing newline is appended safely ## Verification pathlib.Path("part1.txt").write_text("Part 1: Variables\n", encoding="utf-8") pathlib.Path("part2.txt").write_text("Part 2: Loops\n", encoding="utf-8") merge_files(["part1.txt", "part2.txt"], "combined.txt") print(pathlib.Path("combined.txt").read_text(encoding="utf-8").strip()) pathlib.Path("part1.txt").unlink() pathlib.Path("part2.txt").unlink() pathlib.Path("combined.txt").unlink()
Expected Output:
Part 1: Variables Part 2: Loops
Question 18: Read First N Lines of a File (Head)
Write a function get_file_head(file_name, num_lines) that reads and returns a list of the first num_lines strings from a text file, handling files that contain fewer lines gracefully.
main.pyRunnabledef get_file_head(file_name, num_lines): """Returns the first N lines of a file""" head_lines = [] with open(file_name, "r", encoding="utf-8") as file: for _ in range(num_lines): line = file.readline() if not line: break head_lines.append(line.strip()) return head_lines ## Verification pathlib.Path("head.txt").write_text("A\nB\nC\nD\nE\n", encoding="utf-8") print(f"First 3: {get_file_head('head.txt', 3)}") print(f"First 10: {get_file_head('head.txt', 10)}") pathlib.Path("head.txt").unlink()
Expected Output:
First 3: ['A', 'B', 'C'] First 10: ['A', 'B', 'C', 'D', 'E']
Question 19: Read Last N Lines of a File (Tail)
Write a function get_file_tail(file_name, num_lines) that returns the last num_lines strings from a text file.
main.pyRunnabledef get_file_tail(file_name, num_lines): """Returns the last N lines of a file""" with open(file_name, "r", encoding="utf-8") as file: lines = file.readlines() tail = lines[-num_lines:] return [line.strip() for line in tail] ## Verification pathlib.Path("tail.txt").write_text("1\n2\n3\n4\n5\n", encoding="utf-8") print(f"Last 2: {get_file_tail('tail.txt', 2)}") pathlib.Path("tail.txt").unlink()
Expected Output:
Last 2: ['4', '5']
Question 20: Extract Uppercase Words
Write a function extract_uppercase_words(source, destination) that filters uppercase words (consisting only of characters A-Z with length > 1) from a source text file, saving the unique uppercase terms in alphabetical order to a destination file.
main.pyRunnabledef extract_uppercase_words(source, destination): """Filters unique uppercase keywords and saves them to a destination file""" uppercase_set = set() with open(source, "r", encoding="utf-8") as file: for line in file: words = line.split() for word in words: clean_word = word.strip(".,!?;:\"()[]{}") if clean_word.isupper() and len(clean_word) > 1: uppercase_set.add(clean_word) sorted_words = sorted(list(uppercase_set)) with open(destination, "w", encoding="utf-8") as file: for word in sorted_words: file.write(word + "\n") ## Verification pathlib.Path("story.txt").write_text("The HTML and CSS specs were updated by the W3C. This is IMPORTANT.", encoding="utf-8") extract_uppercase_words("story.txt", "keywords.txt") print(pathlib.Path("keywords.txt").read_text(encoding="utf-8").strip().split()) pathlib.Path("story.txt").unlink() pathlib.Path("keywords.txt").unlink()
Expected Output:
['CSS', 'HTML', 'IMPORTANT', 'W3C']
Level 2 Checkpoint
Level 3: Tabular Data Processing (CSV & TSV)
Question 21: CSV Column Sum/Average
Write a function calculate_column_average(csv_file, column_header) that reads a CSV file containing tabular data and returns the average of a specific column containing numeric values.
main.pyRunnableimport csv def calculate_column_average(csv_file, column_header): """Computes column mathematical average inside CSV""" total = 0.0 count = 0 with open(csv_file, "r", encoding="utf-8") as file: reader = csv.DictReader(file) for row in reader: if column_header in row and row[column_header]: try: total += float(row[column_header]) count += 1 except ValueError: continue return total / count if count > 0 else 0.0 ## Verification with open("test_grades.csv", "w", newline="", encoding="utf-8") as f: w = csv.writer(f) w.writerow(["student", "score"]) w.writerows([["Alice", "95"], ["Bob", "85"], ["Charlie", "90"]]) print(f"Average score: {calculate_column_average('test_grades.csv', 'score')}") pathlib.Path("test_grades.csv").unlink()
Expected Output:
Average score: 90.0
Question 22: CSV Row Filter
Write a function filter_csv_rows(source, destination, column_name, filter_value) that filters records from a source CSV and writes them into a destination CSV if a specific column's value matches the filter criteria.
main.pyRunnableimport csv def filter_csv_rows(source, destination, column_name, filter_value): """Filters CSV records by cell values and outputs a new file""" filtered_records = [] fieldnames = [] with open(source, "r", encoding="utf-8") as file: reader = csv.DictReader(file) fieldnames = reader.fieldnames for row in reader: if row.get(column_name) == filter_value: filtered_records.append(row) with open(destination, "w", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=fieldnames) writer.writeheader() writer.writerows(filtered_records) return len(filtered_records) ## Verification with open("employees.csv", "w", newline="", encoding="utf-8") as f: w = csv.writer(f) w.writerow(["name", "dept"]) w.writerows([["Alice", "Engineering"], ["Bob", "Sales"], ["Carol", "Engineering"]]) filter_csv_rows("employees.csv", "engineering.csv", "dept", "Engineering") with open("engineering.csv", "r", encoding="utf-8") as f: print(f.read().strip()) pathlib.Path("employees.csv").unlink() pathlib.Path("engineering.csv").unlink()
Expected Output:
name,dept Alice,Engineering Carol,Engineering
Question 23: CSV Column Extractor
Write a function extract_csv_columns(source, destination, columns_to_keep) that takes a source CSV path and copies only selected columns specified in a list to a destination CSV.
main.pyRunnableimport csv def extract_csv_columns(source, destination, columns_to_keep): """Extracts a subset of CSV columns into a new file""" extracted = [] with open(source, "r", encoding="utf-8") as file: reader = csv.DictReader(file) for row in reader: new_row = {col: row[col] for col in columns_to_keep if col in row} extracted.append(new_row) with open(destination, "w", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=columns_to_keep) writer.writeheader() writer.writerows(extracted) ## Verification with open("data_cols.csv", "w", newline="", encoding="utf-8") as f: w = csv.writer(f) w.writerow(["id", "name", "role", "salary"]) w.writerows([["1", "Alice", "Dev", "90k"], ["2", "Bob", "Sale", "60k"]]) extract_csv_columns("data_cols.csv", "extracted_cols.csv", ["name", "salary"]) with open("extracted_cols.csv", "r", encoding="utf-8") as f: print(f.read().strip()) pathlib.Path("data_cols.csv").unlink() pathlib.Path("extracted_cols.csv").unlink()
Expected Output:
name,salary Alice,90k Bob,60k
Question 24: TSV to CSV Converter
Write a function convert_tsv_to_csv(tsv_file, csv_file) that converts a Tab-Separated Values (TSV) file to a Comma-Separated Values (CSV) file.
main.pyRunnableimport csv def convert_tsv_to_csv(tsv_file, csv_file): """Converts a tab-separated data file into a comma-separated csv""" with open(tsv_file, "r", encoding="utf-8") as t_in, open(csv_file, "w", newline="", encoding="utf-8") as c_out: tsv_reader = csv.reader(t_in, delimiter="\t") csv_writer = csv.writer(c_out, delimiter=",") for row in tsv_reader: csv_writer.writerow(row) ## Verification pathlib.Path("data.tsv").write_text("id\tname\tscore\n1\tAlice\t95\n", encoding="utf-8") convert_tsv_to_csv("data.tsv", "converted.csv") print(pathlib.Path("converted.csv").read_text(encoding="utf-8").strip()) pathlib.Path("data.tsv").unlink() pathlib.Path("converted.csv").unlink()
Expected Output:
id,name,score 1,Alice,95
Question 25: Sort CSV Rows Based on a Column
Write a function sort_csv_by_column(source, destination, sort_column, is_numeric=False) that reads a CSV and sorts its rows based on the values in a specified column, saving the sorted output in a destination CSV.
main.pyRunnableimport csv def sort_csv_by_column(source, destination, sort_column, is_numeric=False): """Sorts CSV records in-place by target column values""" with open(source, "r", encoding="utf-8") as file: reader = csv.DictReader(file) fieldnames = reader.fieldnames rows = list(reader) if is_numeric: rows.sort(key=lambda x: float(x[sort_column])) else: rows.sort(key=lambda x: x[sort_column]) with open(destination, "w", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=fieldnames) writer.writeheader() writer.writerows(rows) ## Verification with open("unsorted.csv", "w", newline="", encoding="utf-8") as f: w = csv.writer(f) w.writerow(["item", "price"]) w.writerows([["apple", "1.50"], ["banana", "0.75"], ["cherry", "2.00"]]) sort_csv_by_column("unsorted.csv", "sorted.csv", "price", is_numeric=True) with open("sorted.csv", "r", encoding="utf-8") as f: print(f.read().strip()) pathlib.Path("unsorted.csv").unlink() pathlib.Path("sorted.csv").unlink()
Expected Output:
item,price banana,0.75 apple,1.50 cherry,2.00
Question 26: Count Value Frequencies in a Column
Write a function column_value_counts(csv_file, column_name) that counts the frequency of each unique value in a specific column, returning a dictionary representing the breakdown.
main.pyRunnableimport csv def column_value_counts(csv_file, column_name): """Calculates categorical frequency within a single CSV column""" counts = {} with open(csv_file, "r", encoding="utf-8") as file: reader = csv.DictReader(file) for row in reader: val = row.get(column_name) if val: counts[val] = counts.get(val, 0) + 1 return counts ## Verification with open("feedback.csv", "w", newline="", encoding="utf-8") as f: w = csv.writer(f) w.writerow(["user", "rating"]) w.writerows([["1", "Good"], ["2", "Bad"], ["3", "Good"], ["4", "Excellent"]]) print(column_value_counts("feedback.csv", "rating")) pathlib.Path("feedback.csv").unlink()
Expected Output:
{'Good': 2, 'Bad': 1, 'Excellent': 1}
Question 27: Detect Missing CSV Values
Write a function detect_missing_values(csv_file) that inspects a CSV file and returns a list of dictionaries detailing the row indexes (0-indexed) and column headers containing blank cells.
main.pyRunnableimport csv def detect_missing_values(csv_file): """Scans tabular records to identify missing values""" anomalies = [] with open(csv_file, "r", encoding="utf-8") as file: reader = csv.DictReader(file) for idx, row in enumerate(reader): for col, val in row.items(): if not val or not val.strip(): anomalies.append({"row_index": idx, "column": col}) return anomalies ## Verification with open("missing.csv", "w", newline="", encoding="utf-8") as f: w = csv.writer(f) w.writerow(["id", "name", "email"]) w.writerows([["1", "Alice", "alice@test.com"], ["2", "", "bob@test.com"], ["3", "Charlie", ""]]) print(detect_missing_values("missing.csv")) pathlib.Path("missing.csv").unlink()
Expected Output:
[{'row_index': 1, 'column': 'name'}, {'row_index': 2, 'column': 'email'}]
Question 28: Merge Two CSV Files on a Shared Key
Write a function merge_csv_files(file1, file2, output_file, shared_key) that performs a database-like inner join on two CSV files based on a shared key column, saving the joined rows to a destination CSV.
main.pyRunnableimport csv def merge_csv_files(file1, file2, output_file, shared_key): """Joins two CSV files based on a common identifier key""" # Load first file records into dictionary mapping key -> row data data_map = {} with open(file1, "r", encoding="utf-8") as f: reader = csv.DictReader(f) for row in reader: data_map[row[shared_key]] = row joined_data = [] fieldnames = [] with open(file2, "r", encoding="utf-8") as f: reader = csv.DictReader(f) file2_fields = reader.fieldnames for row in reader: key = row[shared_key] if key in data_map: merged_row = data_map[key].copy() merged_row.update(row) joined_data.append(merged_row) if joined_data: # Construct header combining unique columns from both databases fieldnames = list(joined_data[0].keys()) with open(output_file, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() writer.writerows(joined_data) return len(joined_data) ## Verification with open("users.csv", "w", newline="", encoding="utf-8") as f: csv.writer(f).writerows([["id", "name"], ["S1", "Alice"], ["S2", "Bob"]]) with open("scores.csv", "w", newline="", encoding="utf-8") as f: csv.writer(f).writerows([["id", "score"], ["S1", "95"], ["S2", "88"]]) merge_csv_files("users.csv", "scores.csv", "joined.csv", "id") with open("joined.csv", "r", encoding="utf-8") as f: print(f.read().strip()) pathlib.Path("users.csv").unlink() pathlib.Path("scores.csv").unlink() pathlib.Path("joined.csv").unlink()
Expected Output:
id,name,score S1,Alice,95 S2,Bob,88
Question 29: Deduplicate Rows in a CSV File
Write a function deduplicate_csv(csv_file) that updates a CSV in-place, removing rows containing identical column values.
main.pyRunnableimport csv def deduplicate_csv(csv_file): """Removes identical row duplicates from CSV in-place""" unique_rows = [] seen_signatures = set() fieldnames = [] with open(csv_file, "r", encoding="utf-8") as file: reader = csv.DictReader(file) fieldnames = reader.fieldnames for row in reader: # Create a signature tuple from all columns signature = tuple(row.items()) if signature not in seen_signatures: seen_signatures.add(signature) unique_rows.append(row) with open(csv_file, "w", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=fieldnames) writer.writeheader() writer.writerows(unique_rows) ## Verification with open("dups.csv", "w", newline="", encoding="utf-8") as f: csv.writer(f).writerows([["colA", "colB"], ["X", "1"], ["X", "1"], ["Y", "2"]]) deduplicate_csv("dups.csv") with open("dups.csv", "r", encoding="utf-8") as f: print(f.read().strip()) pathlib.Path("dups.csv").unlink()
Expected Output:
colA,colB X,1 Y,2
Question 30: Parse CSV into List of Nested Dictionaries
Write a function csv_to_nested_dict(csv_file, key_column) that reads a CSV file and parses it into a dictionary of nested dictionaries, using the values in key_column as primary dictionary keys.
main.pyRunnableimport csv def csv_to_nested_dict(csv_file, key_column): """Parses a CSV file into a nested dictionary structure""" nested_database = {} with open(csv_file, "r", encoding="utf-8") as file: reader = csv.DictReader(file) for row in reader: primary_key = row[key_column] inner_record = row.copy() del inner_record[key_column] # Remove key column from nested dictionary nested_database[primary_key] = inner_record return nested_database ## Verification with open("cities.csv", "w", newline="", encoding="utf-8") as f: csv.writer(f).writerows([["code", "name", "pop"], ["CO", "Denver", "700k"], ["NY", "New York", "8m"]]) db = csv_to_nested_dict("cities.csv", "code") print(db["CO"]) pathlib.Path("cities.csv").unlink()
Expected Output:
{'name': 'Denver', 'pop': '700k'}
Level 3 Checkpoint
Level 4: Hierarchical & Nested Data Formats (JSON & Configs)
Question 31: Load and Pretty-Print JSON File Contents
Write a function pretty_print_json(json_file) that reads a JSON file and outputs its contents to the console as a formatted, properly indented JSON string.
main.pyRunnableimport json def pretty_print_json(json_file): """Outputs indented JSON string to console""" with open(json_file, "r", encoding="utf-8") as file: data = json.load(file) print(json.dumps(data, indent=4, ensure_ascii=False)) ## Verification pathlib.Path("data.json").write_text('{"name": "Alice", "skills": ["Python", "Algorithms"]}', encoding="utf-8") pretty_print_json("data.json") pathlib.Path("data.json").unlink()
Expected Output:
{ "name": "Alice", "skills": [ "Python", "Algorithms" ] }
Question 32: Modify Value in Nested JSON Structure
Write a function update_nested_json(json_file, keys_path_list, new_val) that navigates down a nested JSON hierarchy using a list of keys and updates the target value, saving the modified dictionary back to the JSON file.
main.pyRunnableimport json def update_nested_json(json_file, keys_path_list, new_val): """Updates a nested value inside a JSON file in-place""" with open(json_file, "r", encoding="utf-8") as file: data = json.load(file) # Traverse depth using keys list references cursor = data for key in keys_path_list[:-1]: cursor = cursor[key] cursor[keys_path_list[-1]] = new_val with open(json_file, "w", encoding="utf-8") as file: json.dump(data, file, indent=4) ## Verification pathlib.Path("config.json").write_text('{"server": {"connection": {"port": 8080}}}', encoding="utf-8") update_nested_json("config.json", ["server", "connection", "port"], 9000) print(pathlib.Path("config.json").read_text(encoding="utf-8").strip()) pathlib.Path("config.json").unlink()
Expected Output:
{ "server": { "connection": { "port": 9000 } } }
Question 33: Filter Nested Items in JSON Array
Write a function filter_json_records(json_file, query_key, filter_val) that filters a JSON file containing a list of objects, returning only the objects where the query key matches the filter value.
main.pyRunnableimport json def filter_json_records(json_file, query_key, filter_val): """Filters lists of objects inside a JSON file""" with open(json_file, "r", encoding="utf-8") as file: records = json.load(file) # Filter using list comprehensions return [item for item in records if item.get(query_key) == filter_val] ## Verification pathlib.Path("roster.json").write_text('[{"id": 1, "graduated": true}, {"id": 2, "graduated": false}]', encoding="utf-8") print(filter_json_records("roster.json", "graduated", True)) pathlib.Path("roster.json").unlink()
Expected Output:
[{'id': 1, 'graduated': True}]
Question 34: Flatten Nested JSON Structure
Write a function flatten_json(json_file, output_file) that reads a nested JSON object containing only dictionaries at nested levels, flattens it into a single-level dictionary using dot-separated keys, and saves it to a new JSON file.
main.pyRunnableimport json def flatten_json(json_file, output_file): """Flattens a multi-level JSON dictionary structure into a flat key map""" with open(json_file, "r", encoding="utf-8") as file: nested_data = json.load(file) flat_data = {} def walk(dict_node, prefix=""): for k, v in dict_node.items(): full_key = f"{prefix}.{k}" if prefix else k if isinstance(v, dict): walk(v, prefix=full_key) else: flat_data[full_key] = v walk(nested_data) with open(output_file, "w", encoding="utf-8") as file: json.dump(flat_data, file, indent=4) ## Verification pathlib.Path("nested.json").write_text('{"app": {"db": {"host": "localhost", "port": 5432}}}', encoding="utf-8") flatten_json("nested.json", "flat.json") print(pathlib.Path("flat.json").read_text(encoding="utf-8").strip()) pathlib.Path("nested.json").unlink() pathlib.Path("flat.json").unlink()
Expected Output:
{ "app.db.host": "localhost", "app.db.port": 5432 }
Question 35: Convert List of Dictionaries to JSON
Write a function dict_list_to_json(dictionary_list, output_file) that writes a list of Python dictionaries to a structured JSON file.
main.pyRunnableimport json def dict_list_to_json(dictionary_list, output_file): """Serializes a list of dictionaries to a JSON file""" with open(output_file, "w", encoding="utf-8") as file: json.dump(dictionary_list, file, indent=4) ## Verification dicts = [{"user": "Alice", "active": True}, {"user": "Bob", "active": False}] dict_list_to_json(dicts, "users.json") print(pathlib.Path("users.json").read_text(encoding="utf-8").strip()) pathlib.Path("users.json").unlink()
Expected Output:
[ { "user": "Alice", "active": true }, { "user": "Bob", "active": false } ]
Question 36: Parse Simple INI Configuration File
Write a function parse_ini_config(ini_file) that parses a simple key-value INI configuration file (ignoring comments starting with ; or # and section headers inside []) and returns a flat dictionary representing the active settings.
main.pyRunnabledef parse_ini_config(ini_file): """Parses standard key-value configuration lines into a dictionary""" config_dict = {} with open(ini_file, "r", encoding="utf-8") as file: for line in file: stripped = line.strip() # Ignore comments and empty lines or headers if not stripped or stripped.startswith(";") or stripped.startswith("#") or (stripped.startswith("[") and stripped.endswith("]")): continue if "=" in stripped: k, v = stripped.split("=", 1) config_dict[k.strip()] = v.strip() return config_dict ## Verification pathlib.Path("app.ini").write_text("# Configuration Settings\n[database]\nhost=127.0.0.1\nport=3306\n;debug=true\n", encoding="utf-8") print(parse_ini_config("app.ini")) pathlib.Path("app.ini").unlink()
Expected Output:
{'host': '127.0.0.1', 'port': '3306'}
Question 37: Validate JSON Structure Against Schema
Write a function validate_json_schema(json_file, required_keys_dict) that loads a JSON object and verifies that it contains all specified keys with the expected data types. It must return a tuple of (is_valid, error_message).
main.pyRunnableimport json def validate_json_schema(json_file, required_keys_dict): """Validates JSON parameters and type alignments""" try: with open(json_file, "r", encoding="utf-8") as file: data = json.load(file) for key, expected_type in required_keys_dict.items(): if key not in data: return False, f"Missing required key: '{key}'" if not isinstance(data[key], expected_type): return False, f"Invalid type for '{key}': Expected {expected_type.__name__}, got {type(data[key]).__name__}" return True, "Validation successful" except Exception as e: return False, str(e) ## Verification schema = {"username": str, "age": int, "admin": bool} pathlib.Path("user_profile.json").write_text('{"username": "student", "age": "17", "admin": false}', encoding="utf-8") print(f"Validation: {validate_json_schema('user_profile.json', schema)}") pathlib.Path("user_profile.json").write_text('{"username": "student", "age": 17, "admin": false}', encoding="utf-8") print(f"Validation: {validate_json_schema('user_profile.json', schema)}") pathlib.Path("user_profile.json").unlink()
Expected Output:
Validation: (False, "Invalid type for 'age': Expected int, got str") Validation: (True, 'Validation successful')
Question 38: Convert Nested List of Dictionaries to CSV
Write a function json_to_csv(json_file, csv_output_file) that reads a JSON file containing a list of identical flat dictionaries and exports it to a flat, comma-separated CSV spreadsheet.
main.pyRunnableimport json import csv def json_to_csv(json_file, csv_output_file): """Flattens a list of JSON object records into a tabular CSV""" with open(json_file, "r", encoding="utf-8") as file: records = json.load(file) if not records: return # Extract headers from first object keys fieldnames = list(records[0].keys()) with open(csv_output_file, "w", newline="", encoding="utf-8") as file: writer = csv.DictWriter(file, fieldnames=fieldnames) writer.writeheader() writer.writerows(records) ## Verification pathlib.Path("data.json").write_text('[{"id": "S1", "gpa": 3.8}, {"id": "S2", "gpa": 3.6}]', encoding="utf-8") json_to_csv("data.json", "output.csv") print(pathlib.Path("output.csv").read_text(encoding="utf-8").strip()) pathlib.Path("data.json").unlink() pathlib.Path("output.csv").unlink()
Expected Output:
id,gpa S1,3.8 S2,3.6
Question 39: Convert Flat CSV File into Nested JSON
Write a function csv_to_nested_json(csv_file, json_output_file, group_by_column) that reads a CSV and outputs a JSON file grouped by a column key, mapping grouping values to a list of associated records.
main.pyRunnableimport csv import json def csv_to_nested_json(csv_file, json_output_file, group_by_column): """Transforms a flat tabular CSV file into a nested grouped JSON structure""" grouped_data = {} with open(csv_file, "r", encoding="utf-8") as file: reader = csv.DictReader(file) for row in reader: group_key = row[group_by_column] record = row.copy() del record[group_by_column] if group_key not in grouped_data: grouped_data[group_key] = [] grouped_data[group_key].append(record) with open(json_output_file, "w", encoding="utf-8") as file: json.dump(grouped_data, file, indent=4) ## Verification with open("roster.csv", "w", newline="", encoding="utf-8") as f: csv.writer(f).writerows([["dept", "name"], ["CS", "Alice"], ["CS", "Bob"], ["ME", "Carol"]]) csv_to_nested_json("roster.csv", "nested_roster.json", "dept") print(pathlib.Path("nested_roster.json").read_text(encoding="utf-8").strip()) pathlib.Path("roster.csv").unlink() pathlib.Path("nested_roster.json").unlink()
Expected Output:
{ "CS": [ { "name": "Alice" }, { "name": "Bob" } ], "ME": [ { "name": "Carol" } ] }
Question 40: Config Manager with Defaults
Write a function load_config_with_defaults(json_file, default_settings_dict) that loads a JSON config file. If the file does not exist, it must write the default dictionary to disk and return the default values. If the file exists, it must return a merged dictionary of user selections overriding defaults.
main.pyRunnableimport json import pathlib def load_config_with_defaults(json_file, default_settings_dict): """Loads configuration options, applying default values for missing keys""" target = pathlib.Path(json_file) if not target.exists(): with open(target, "w", encoding="utf-8") as file: json.dump(default_settings_dict, file, indent=4) return default_settings_dict.copy() try: with open(target, "r", encoding="utf-8") as file: user_config = json.load(file) # Merge dictionaries (user overrides defaults) merged = default_settings_dict.copy() merged.update(user_config) return merged except json.JSONDecodeError: return default_settings_dict.copy() ## Verification defaults = {"theme": "light", "fontsize": 12} print(f"Fresh: {load_config_with_defaults('settings.json', defaults)}") pathlib.Path("settings.json").write_text('{"theme": "dark"}', encoding="utf-8") print(f"Override: {load_config_with_defaults('settings.json', defaults)}") pathlib.Path("settings.json").unlink()
Expected Output:
Fresh: {'theme': 'light', 'fontsize': 12} Override: {'theme': 'dark', 'fontsize': 12}
Level 4 Checkpoint
Level 5: Real-World Systems & Integrity
Question 41: Safe Atomic File Writer
Write a function safe_atomic_write(file_path, content) that prevents file corruption during crashes by writing content to a temporary file (temp.tmp), and only renaming it to the target file name once the write is complete and flushed to disk.
main.pyRunnableimport pathlib import os def safe_atomic_write(file_path, content): """Safely writes content using atomic temp file replacement""" target_path = pathlib.Path(file_path) temp_path = target_path.with_suffix(".tmp") try: # 1. Write data to temporary file with open(temp_path, "w", encoding="utf-8") as temp_file: temp_file.write(content) temp_file.flush() os.fsync(temp_file.fileno()) # Force flush system buffers to disk # 2. Swap temp file into final location atomically temp_path.replace(target_path) return True except Exception as e: if temp_path.exists(): temp_path.unlink() # Cleanup temp file if write fails return False ## Verification safe_atomic_write("atomic.txt", "Atomic persistent storage completed.") print(pathlib.Path("atomic.txt").read_text(encoding="utf-8")) pathlib.Path("atomic.txt").unlink()
Expected Output:
Atomic persistent storage completed.
Question 42: Recursive Directory Size Calculator
Write a function get_directory_size_bytes(directory_path) that calculates the sum total size in bytes of all files inside a directory and its subdirectories recursively.
main.pyRunnableimport pathlib def get_directory_size_bytes(directory_path): """Recursively computes cumulative directory bytes size""" total_size = 0 dir_path = pathlib.Path(directory_path) if dir_path.exists() and dir_path.is_dir(): for path in dir_path.rglob("*"): if path.is_file(): total_size += path.stat().st_size return total_size ## Verification dir_a = pathlib.Path("size_dir/sub") dir_a.mkdir(parents=True, exist_ok=True) (dir_a / "f1.txt").write_text("Hello", encoding="utf-8") # 5 bytes (pathlib.Path("size_dir") / "f2.txt").write_text("World!", encoding="utf-8") # 6 bytes print(f"Total Bytes: {get_directory_size_bytes('size_dir')}") shutil = __import__("shutil") shutil.rmtree("size_dir")
Expected Output:
Total Bytes: 11
Question 43: File Integrity Checksum Generator
Write a function verify_file_integrity(file_path, expected_sha256) that reads a file in binary mode chunks, calculates its SHA-256 hash, and returns True if it matches the expected hash checksum.
main.pyRunnableimport hashlib def verify_file_integrity(file_path, expected_sha256): """Calculates SHA-256 checksum using chunked streams to verify integrity""" sha256_hash = hashlib.sha256() try: # Open in binary mode ('rb') to handle any file type safely with open(file_path, "rb") as file: # Read in 4096-byte chunks to avoid memory issues with large files for chunk in iter(lambda: file.read(4096), b""): sha256_hash.update(chunk) return sha256_hash.hexdigest() == expected_sha256 except FileNotFoundError: return False ## Verification pathlib.Path("secure.bin").write_bytes(b"Secret Code") correct_hash = hashlib.sha256(b"Secret Code").hexdigest() print(f"Checksum matched? {verify_file_integrity('secure.bin', correct_hash)}") print(f"Bad match? {verify_file_integrity('secure.bin', 'incorrecthash')}") pathlib.Path("secure.bin").unlink()
Expected Output:
Checksum matched? True Bad match? False
Question 44: Find Duplicate Files
Write a function find_duplicate_files(directory_path) that scans a directory recursively and returns a list of lists containing paths of identical files (files with the exact same content hash).
main.pyRunnableimport pathlib import hashlib def find_duplicate_files(directory_path): """Identifies duplicate files based on content hash""" hashes_map = {} duplicates = [] dir_path = pathlib.Path(directory_path) if not dir_path.exists() or not dir_path.is_dir(): return duplicates for path in dir_path.rglob("*"): if path.is_file(): # Generate MD5 content signature hasher = hashlib.md5() with open(path, "rb") as f: for chunk in iter(lambda: f.read(4096), b""): hasher.update(chunk) file_hash = hasher.hexdigest() if file_hash not in hashes_map: hashes_map[file_hash] = [] hashes_map[file_hash].append(str(path)) # Extract entries containing duplicate file listings for paths in hashes_map.values(): if len(paths) > 1: duplicates.append(paths) return duplicates ## Verification test_folder = pathlib.Path("dup_test") test_folder.mkdir(exist_ok=True) (test_folder / "file1.txt").write_text("Unique text A", encoding="utf-8") (test_folder / "file2.txt").write_text("Copy text", encoding="utf-8") (test_folder / "file3.txt").write_text("Copy text", encoding="utf-8") print(find_duplicate_files(test_folder)) __import__("shutil").rmtree(test_folder)
Expected Output:
[['dup_test/file2.txt', 'dup_test/file3.txt']]
Question 45: XOR Byte File Encryptor/Decryptor
Write a function xor_file_cipher(source_file, destination_file, key_byte) that performs a simple byte-level XOR encryption/decryption, reading a source file in binary mode, XORing each byte with a key byte, and writing the result to a destination file.
main.pyRunnabledef xor_file_cipher(source_file, destination_file, key_byte): """XOR byte cipher operation for file security""" with open(source_file, "rb") as src, open(destination_file, "wb") as dest: while True: chunk = src.read(4096) if not chunk: break # XOR each byte against the key byte cipher_bytes = bytes([b ^ key_byte for b in chunk]) dest.write(cipher_bytes) ## Verification pathlib.Path("plain.txt").write_text("Hello Python World", encoding="utf-8") ## Encrypt xor_file_cipher("plain.txt", "encrypted.dat", 42) ## Decrypt (XORing again with same key decrypts the file) xor_file_cipher("encrypted.dat", "decrypted.txt", 42) print(pathlib.Path("decrypted.txt").read_text(encoding="utf-8")) pathlib.Path("plain.txt").unlink() pathlib.Path("encrypted.dat").unlink() pathlib.Path("decrypted.txt").unlink()
Expected Output:
Hello Python World
Question 46: Zip a Directory Recursively
Write a function zip_directory(source_dir, output_zip_path) that recursively compresses a directory and all of its contents (files and subfolders) into a standard ZIP archive.
main.pyRunnableimport zipfile import pathlib def zip_directory(source_dir, output_zip_path): """Compresses a directory recursively into a ZIP file""" src_path = pathlib.Path(source_dir) with zipfile.ZipFile(output_zip_path, "w", zipfile.ZIP_DEFLATED) as zip_file: for path in src_path.rglob("*"): if path.is_file(): # Write file with relative path mapping to preserve folder structure zip_file.write(path, path.relative_to(src_path.parent)) ## Verification pack_folder = pathlib.Path("pack") pack_folder.mkdir(exist_ok=True) (pack_folder / "note.txt").write_text("Important notes inside zip file", encoding="utf-8") zip_directory(pack_folder, "archive.zip") print(f"Zip created? {pathlib.Path('archive.zip').exists()}") pathlib.Path("archive.zip").unlink() __import__("shutil").rmtree(pack_folder)
Expected Output:
Zip created? True
Question 47: Extract ZIP Files by Extension
Write a function extract_files_by_extension(zip_path, extract_destination, target_extension) that extracts only files matching a target extension from a ZIP archive.
main.pyRunnableimport zipfile import pathlib def extract_files_by_extension(zip_path, extract_destination, target_extension): """Selectively extracts files with a target extension from a ZIP file""" dest = pathlib.Path(extract_destination) dest.mkdir(exist_ok=True) extracted_files = [] with zipfile.ZipFile(zip_path, "r") as zip_ref: for info in zip_ref.infolist(): if info.filename.endswith(target_extension): # Extract file to destination zip_ref.extract(info, path=dest) extracted_files.append(info.filename) return extracted_files ## Verification ## Setup ZIP file temp_zip = pathlib.Path("temp_archive.zip") with zipfile.ZipFile(temp_zip, "w") as z: z.writestr("a.py", "print('Python code')") z.writestr("b.txt", "Plain text") extracted = extract_files_by_extension(temp_zip, "selective_extract", ".py") print(f"Extracted files: {extracted}") temp_zip.unlink() __import__("shutil").rmtree("selective_extract")
Expected Output:
Extracted files: ['a.py']
Question 48: File Backup Manager with Rotation
Write a function create_rotated_backup(file_path, backup_dir, max_backups=3) that copies a target file into a backup directory, appending an incrementing integer index (e.g. file.txt.1, file.txt.2). If the number of backups exceeds max_backups, it must delete the oldest backup.
main.pyRunnableimport pathlib import shutil def create_rotated_backup(file_path, backup_dir, max_backups=3): """Manages file backups with version rotation""" target = pathlib.Path(file_path) backup_folder = pathlib.Path(backup_dir) backup_folder.mkdir(exist_ok=True) # 1. Rotate existing backups (shift indices up) for i in range(max_backups - 1, 0, -1): old_backup = backup_folder / f"{target.name}.{i}" new_backup = backup_folder / f"{target.name}.{i+1}" if old_backup.exists(): if new_backup.exists(): new_backup.unlink() old_backup.rename(new_backup) # 2. Copy the current file to index 1 destination = backup_folder / f"{target.name}.1" shutil.copy2(target, destination) # 3. List active backup files in order active_backups = sorted(list(backup_folder.iterdir())) return [b.name for b in active_backups] ## Verification pathlib.Path("main.txt").write_text("Version 1.0", encoding="utf-8") print(f"Rotate 1: {create_rotated_backup('main.txt', 'backups_folder')}") pathlib.Path("main.txt").write_text("Version 1.1", encoding="utf-8") print(f"Rotate 2: {create_rotated_backup('main.txt', 'backups_folder')}") __import__("shutil").rmtree("backups_folder") pathlib.Path("main.txt").unlink()
Expected Output:
Rotate 1: ['main.txt.1'] Rotate 2: ['main.txt.1', 'main.txt.2']
Question 49: File-based Rate Limiter Log System
Write a function is_request_allowed(ip_log_file, ip_address, limit=3, window_seconds=10) that reads and appends timestamped records (using float epoch values from time.time()) to check if a client IP address has exceeded a request limit within a specific time window.
main.pyRunnableimport time import pathlib def is_request_allowed(ip_log_file, ip_address, limit=3, window_seconds=10): """Enforces request limits using physical timestamp files""" log_path = pathlib.Path(ip_log_file) current_time = time.time() valid_logs = [] request_count = 0 # 1. Load active logs inside current window if log_path.exists(): with open(log_path, "r", encoding="utf-8") as file: for line in file: if line.strip(): ip, ts_str = line.strip().split(",", 1) ts = float(ts_str) # Keep records within active window if current_time - ts <= window_seconds: valid_logs.append((ip, ts)) if ip == ip_address: request_count += 1 # 2. Check if request limit has been exceeded allowed = request_count < limit if allowed: valid_logs.append((ip_address, current_time)) # 3. Rewrite active logs back to disk to prune old entries with open(log_path, "w", encoding="utf-8") as file: for ip, ts in valid_logs: file.write(f"{ip},{ts}\n") return allowed ## Verification print(f"Request 1: {is_request_allowed('rate.log', '192.168.1.1')}") print(f"Request 2: {is_request_allowed('rate.log', '192.168.1.1')}") print(f"Request 3: {is_request_allowed('rate.log', '192.168.1.1')}") print(f"Request 4: {is_request_allowed('rate.log', '192.168.1.1')}") pathlib.Path("rate.log").unlink()
Expected Output:
Request 1: True Request 2: True Request 3: True Request 4: False
Question 50: Offline Student Database & Gradebook System
Write a complete, procedural data system integrating a CSV database (attendance.csv) and a JSON database (profiles.json). Implement two operations:
enroll_student(student_id, name): Adds a new profile toprofiles.jsonif it doesn't already exist.log_attendance(student_id, date, status): Validates that the student exists inprofiles.jsonand appends a record toattendance.csv.get_student_summary(student_id): Merges the profile and attendance records to return a summary dictionary of the student's information.
main.pyRunnableimport json import csv import pathlib DB_JSON = pathlib.Path("profiles.json") DB_CSV = pathlib.Path("attendance.csv") def setup_databases(): """Initializes databases if they do not exist""" if not DB_JSON.exists(): DB_JSON.write_text('{"profiles": {}}', encoding="utf-8") if not DB_CSV.exists(): with open(DB_CSV, "w", newline="", encoding="utf-8") as f: csv.writer(f).writerow(["student_id", "date", "status"]) def enroll_student(student_id, name): """Enrolls a student in the JSON profile database""" setup_databases() with open(DB_JSON, "r", encoding="utf-8") as f: data = json.load(f) profiles = data["profiles"] if student_id in profiles: return False # Student already enrolled profiles[student_id] = {"name": name} with open(DB_JSON, "w", encoding="utf-8") as f: json.dump(data, f, indent=4) return True def log_attendance(student_id, date, status): """Logs attendance in the CSV database after validating the student's profile exists""" setup_databases() with open(DB_JSON, "r", encoding="utf-8") as f: profiles = json.load(f)["profiles"] if student_id not in profiles: return False # Student profile missing with open(DB_CSV, "a", newline="", encoding="utf-8") as f: csv.writer(f).writerow([student_id, date, status]) return True def get_student_summary(student_id): """Retrieves a merged summary of a student's profile and attendance history""" setup_databases() with open(DB_JSON, "r", encoding="utf-8") as f: profiles = json.load(f)["profiles"] if student_id not in profiles: return None student_name = profiles[student_id]["name"] attendance_records = [] with open(DB_CSV, "r", encoding="utf-8") as f: reader = csv.DictReader(f) for row in reader: if row["student_id"] == student_id: attendance_records.append({"date": row["date"], "status": row["status"]}) return { "student_id": student_id, "name": student_name, "attendance": attendance_records } ## Verification enroll_student("S101", "Alice") log_attendance("S101", "2026-05-19", "Present") log_attendance("S101", "2026-05-20", "Absent") print(get_student_summary("S101")) DB_JSON.unlink() DB_CSV.unlink()
Expected Output:
{'student_id': 'S101', 'name': 'Alice', 'attendance': [{'date': '2026-05-19', 'status': 'Present'}, {'date': '2026-05-20', 'status': 'Absent'}]}
Level 5 Checkpoint
Finished this lesson?
Mark it complete to advance your curriculum progress.