Fix the CSV parser in a contact import
Your task
An AI wrote a contact import that read the uploaded CSV with text.split('\n') and then line.split(','). It worked on a 20-row demo file. Real exports have quoted commas, quoted line breaks and Windows line endings, so names were mangled and the header row was imported as a contact. Your team is replacing it with a parser that reports every row's status and caps the number of rows.
An assistant wrote parse_contact_import(csv_text, max_rows). It is in the editor. It has a bug. Find it and fix it.
Input and output:
csv_text: the uploaded file's text, with a header line and then one contact per record: name, then email.max_rows: the most data rows to return.- Return one
[status, name, email]list per data row, in file order.
Rules the tests check:
- Read the text one character at a time, as CSV:
- Outside quotes,
,ends a field and a line break ends a record. A line break is\r\n,\nor\r. "starts a quoted part. Inside it,,and line breaks are ordinary characters and""stands for one". The next single"ends the quoted part. The quote marks are not part of the field.- A file that ends with a line break has no extra empty record after it.
- Outside quotes,
- If
max_rowsis 0 or less, return[]. - Skip blank records: a record with one field that is empty after trimming spaces, tabs and
\r. They do not count towardmax_rows. Rows with a bad status do count. - The first record that is not blank is the header. Drop it.
- Return the first
max_rowsdata rows at most. - The name is field 1 and the email is field 2, or
""when there is no field 2. Trim spaces, tabs and\rfrom both ends of each. - The status is the first of these that applies:
"bad_field_count": the record does not have exactly 2 fields."bad_name": the name is empty."bad_email": the email contains a space, a tab, a line break or,; or it does not have exactly one@; or nothing comes before the@; or the domain, the part after the@, has no., or its last.is its first or last character."ok"otherwise.
Examples
parse_contact_import(csv_text: str, max_rows: int) -> list[list[str]]Example 1
Input
parse_contact_import("name,email\nAda Lovelace,ada@example.com\nAlan Turing,alan@example.org\n", 100)Output
[["ok", "Ada Lovelace", "ada@example.com"], ["ok", "Alan Turing", "alan@example.org"]]Example 2
Input
parse_contact_import("name,email\r\n\"Lovelace, Ada\",ada@example.com\r\nGrace Hopper,grace@navy.mil\r\n", 100)Output
[["ok", "Lovelace, Ada", "ada@example.com"], ["ok", "Grace Hopper", "grace@navy.mil"]]Example 3
Input
parse_contact_import("name,email\nAda,ada@example.com\nBob,not-an-email\n", 100)Output
[["ok", "Ada", "ada@example.com"], ["bad_email", "Bob", "not-an-email"]]