tobe

Finished
11def grep(pattern: str, flags: str, files: list[str]) -> str:
2 pass
2 # Edge Case: Handle empty pattern
3 if not pattern:
4 return ""
5
6 # Edge Case: Handle empty files list
7 if not files:
8 return ""
9
10 # Parse flags
11 line_numbers = '-n' in flags
12 filenames_only = '-l' in flags
13 case_insensitive = '-i' in flags
14 invert_match = '-v' in flags
15 exact_match = '-x' in flags
16
17 # Prepare pattern for comparison
18 search_pattern = pattern.lower() if case_insensitive else pattern
19
20 # Results storage
21 results = []
22 matched_files = set()
23
24 # Process each file
25 for filename in files:
26 try:
27 with open(filename, 'r') as file:
28 lines = file.readlines()
29
30 # Edge Case: Handle file read error (though we don't raise exception, we skip the file)
31 if lines is None:
32 continue
33
34 for line_num, line in enumerate(lines, start=1):
35 # Prepare line for comparison
36 compare_line = line.lower() if case_insensitive else line
37
38 # Determine if line matches
39 if exact_match:
40 matches = search_pattern == compare_line.rstrip('\n')
41 else:
42 matches = search_pattern in compare_line
43
44 # Apply invert flag
45 if invert_match:
46 matches = not matches
47
48 # If line matches criteria
49 if matches:
50 if filenames_only:
51 matched_files.add(filename)
52 # No need to check other lines in this file for -l flag
53 break
54 else:
55 output_line = line.rstrip('\n')
56
57 # Build output based on flags
58 if line_numbers:
59 output_line = f"{line_num}:{output_line}"
60
61 if len(files) > 1:
62 # Fix the line numbering when multiple files
63 if line_numbers:
64 output_line = f"{filename}:{output_line}"
65 else:
66 output_line = f"{filename}:{output_line}"
67
68 results.append(output_line)
69 except FileNotFoundError:
70 # Edge Case: Handle file not found - raise exception as expected by tests
71 raise
72 except Exception:
73 # Edge Case: Handle any other file reading errors - skip the file
74 continue
75
76 # If -l flag is set, return only filenames
77 if filenames_only:
78 if matched_files:
79 return '\n'.join(sorted(matched_files)) + '\n'
80 else:
81 return ''
82
83 # Return all matching lines with trailing newline
84 if results:
85 return '\n'.join(results) + '\n'
86 else:
87 return ''
88
89# Handled Edge Cases: empty pattern, empty files list, file not found, file read errors, case insensitive matching, exact line matching, invert matching, line numbering, filenames only output
Test NameStatus
test_multiple_files_no_matches_various_flags
Pass
test_multiple_files_one_match_match_entire_lines_flag
Pass
test_multiple_files_one_match_multiple_flags
Pass
test_multiple_files_one_match_no_flags
Pass
test_multiple_files_one_match_print_file_names_flag
Pass
test_multiple_files_several_matches_case_insensitive_flag
Pass
test_multiple_files_several_matches_file_flag_takes_precedence_over_line_number_flag
Pass
test_multiple_files_several_matches_inverted_and_match_entire_lines_flags
Pass
test_multiple_files_several_matches_inverted_flag
Pass
test_multiple_files_several_matches_no_flags
Pass
test_multiple_files_several_matches_print_line_numbers_flag
Pass
test_one_file_no_matches_various_flags
Pass
test_one_file_one_match_case_insensitive_flag
Pass
test_one_file_one_match_file_flag_takes_precedence_over_line_flag
Pass
test_one_file_one_match_match_entire_lines_flag
Pass
test_one_file_one_match_multiple_flags
Pass
test_one_file_one_match_no_flags
Pass
test_one_file_one_match_print_file_names_flag
Pass
test_one_file_one_match_print_line_numbers_flag
Pass
test_one_file_several_matches_case_insensitive_flag
Pass
test_one_file_several_matches_inverted_and_match_entire_lines_flags
Pass
test_one_file_several_matches_inverted_flag
Pass
test_one_file_several_matches_match_entire_lines_flag
Pass
test_one_file_several_matches_no_flags
Pass
test_one_file_several_matches_print_line_numbers_flag
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.