Validating Sequence Records

Intermediate Python Foundations Python Error Handling Validation Data Quality
Significance:

Real datasets contain malformed records, and a script that crashes on the first bad
line is useless for a file with fifty thousand entries. Defensive validation — checking each record,
reporting what failed and why, and carrying on — is what separates a throwaway script from a tool a lab
can actually rely on. This is the habit that saves you when a collaborator sends a file with three
different problems in it.

Statement

You are given records, one per line, each supposed to contain an identifier and a DNA
sequence separated by a single space.

Validate each record against these rules, checked in this order:

  1. The line must contain exactly two space-separated fields — otherwise the error is MALFORMED.
  2. The sequence must contain only the characters A, C, G, T — otherwise the error is BADCHARS.
  3. The sequence length must be a multiple of 3 — otherwise the error is NOTCODON.

For each valid record print <identifier> OK. For each invalid record print <identifier> <ERROR>,
using the first rule it violates. If a record is MALFORMED and has no usable identifier, use the
literal ? as the identifier.

On the final line print the number of valid records.

Input — read from standard input
Variable Type Description
n
line 1
int The number of records
1 <= n <= 200
records
line 2..n+1
str One record per line, identifier and sequence separated by a space
each line 1 to 500 characters

These variables are already read for you in the starter code on the right.

Output

str one verdict line per record, then a final line with the count of valid records

Sample Cases
Sample 1
Input
4
g1 ATGGCC
g2 ATGNCC
g3 ATGG
g4
Expected Output
g1 OK
g2 BADCHARS
g3 NOTCODON
g4 MALFORMED
1
One valid record, then a bad-character record, a non-codon record, and a malformed line.
Sample 2
Input
2
good ACGACG
bad
Expected Output
good OK
bad MALFORMED
1
One passing record and one line with a single field.

Submit also runs your code against 3 hidden test cases. Hidden inputs are never shown — if one fails you'll get its number and a description of the mismatch, not the data.

Constraints
  • Rules are checked in the stated order and only the first failure is reported
  • A line with zero, one, or three or more fields is MALFORMED
  • For a MALFORMED line, use the first field as the identifier if one exists, otherwise ?
  • An empty line counts as a record and is MALFORMED with identifier ?
Further Reading
  • line.split() collapses runs of whitespace, which is what you want for field counting.
  • Use set(seq) <= set("ACGT") to test character validity in a single expression.
  • Check the rules in order and return early on the first failure rather than collecting all errors.

My Notes
Log in to save personal notes.
Console output will appear here when you click Run Code or Submit...
Expected: n (int), records (remaining lines)
Next Problem
Count Sequences in a FASTA Stream