nicolargo /
glances
| 1 | #!/usr/bin/env python |
||
| 2 | # |
||
| 3 | # Check a CSV file. |
||
| 4 | # The input CSV file should be given as an input with the -i <file> option. |
||
| 5 | # Check the following thinks: |
||
| 6 | # - number of line (without the header) should be equal to the number given with the -l <number of lines> option |
||
| 7 | # - each line should have the same number of columns |
||
| 8 | # - if the optional -c <number of columns> option is given, each line should have the the same number of columns |
||
| 9 | |||
| 10 | import argparse |
||
| 11 | import csv |
||
| 12 | import sys |
||
| 13 | |||
| 14 | |||
| 15 | def check_csv(input_file, expected_lines, expected_columns=None): |
||
| 16 | try: |
||
| 17 | with open(input_file, newline='') as csvfile: |
||
| 18 | reader = csv.reader(csvfile) |
||
| 19 | |||
| 20 | # Read header |
||
| 21 | header = next(reader, None) |
||
| 22 | if header is None: |
||
| 23 | print("Error: CSV file is empty") |
||
| 24 | return False |
||
| 25 | |||
| 26 | header_columns = len(header) |
||
| 27 | print(f"Header has {header_columns} columns") |
||
| 28 | |||
| 29 | # Read all the data rows |
||
| 30 | rows = list(reader) |
||
| 31 | row_count = len(rows) |
||
| 32 | |||
| 33 | # Check 1: Number of lines |
||
| 34 | if row_count != expected_lines: |
||
| 35 | print(f"Error: Expected {expected_lines} lines, but found {row_count}") |
||
| 36 | return False |
||
| 37 | print(f"Line count check passed: {row_count} lines (excluding header)") |
||
| 38 | |||
| 39 | # Check 2: Consistent number of columns |
||
| 40 | column_counts = [len(row) for row in rows] |
||
| 41 | if len(set(column_counts)) > 1: |
||
| 42 | print("Error: Not all rows have the same number of columns") |
||
| 43 | for i, count in enumerate(column_counts): |
||
| 44 | if count != header_columns: |
||
| 45 | print(f"Row {i + 1} has {count} columns (different from header)") |
||
| 46 | return False |
||
| 47 | print("Column consistency check passed: All rows have the same number of columns") |
||
| 48 | |||
| 49 | # Check 3: Optional - specific number of columns |
||
| 50 | if expected_columns is not None: |
||
| 51 | if header_columns != expected_columns: |
||
| 52 | print(f"Error: Expected {expected_columns} columns, but found {header_columns}") |
||
| 53 | return False |
||
| 54 | print(f"Column count check passed: {header_columns} columns") |
||
| 55 | |||
| 56 | return True |
||
| 57 | |||
| 58 | except FileNotFoundError: |
||
| 59 | print(f"Error: File '{input_file}' not found") |
||
| 60 | return False |
||
| 61 | except Exception as e: |
||
| 62 | print(f"Error processing CSV file: {str(e)}") |
||
| 63 | return False |
||
| 64 | |||
| 65 | |||
| 66 | View Code Duplication | def main(): |
|
|
0 ignored issues
–
show
Duplication
introduced
by
Loading history...
|
|||
| 67 | parser = argparse.ArgumentParser(description='Check a CSV file for various properties.') |
||
| 68 | parser.add_argument('-i', '--input', required=True, help='Input CSV file') |
||
| 69 | parser.add_argument('-l', '--lines', type=int, required=True, help='Expected number of lines (excluding header)') |
||
| 70 | parser.add_argument('-c', '--columns', type=int, help='Expected number of columns (optional)') |
||
| 71 | |||
| 72 | args = parser.parse_args() |
||
| 73 | |||
| 74 | success = check_csv(args.input, args.lines, args.columns) |
||
| 75 | |||
| 76 | if success: |
||
| 77 | print("CSV - All checks passed successfully!") |
||
| 78 | sys.exit(0) |
||
| 79 | else: |
||
| 80 | print("CSV validation failed.") |
||
| 81 | sys.exit(1) |
||
| 82 | |||
| 83 | |||
| 84 | if __name__ == "__main__": |
||
| 85 | main() |
||
| 86 |