1INSERT parent, DELETE child — Add the parent row before its child rows, and delete child rows before their parent. Otherwise the foreign key rule is broken and SQL gives a foreign key error.
2sqlite3.connect() — Opens a SQLite database file from Python and returns a connection. Call conn.cursor() on it to get a cursor for running SQL, and conn.close() when finished.
3cursor.fetchall() — Returns every row from the SELECT that cursor.execute() ran, as a list of tuples. An empty result gives an empty list []. fetchone() returns just one row.
4for row in rows: print(f"{row[0]:<10}{row[1]}") — Loops over each fetched row and prints its fields with an f-string, padded into columns so results are readable. Check for an empty list to show a no records message.
5cur.execute(join_sql) — Runs a JOIN query stored in one string. Each row fetched back is a tuple holding fields from both tables, which you can unpack into variables.
6cursor.execute("INSERT INTO products (name, price) VALUES (?, ?)", (n, p)) — Adds a new record using ? placeholders filled safely from a tuple of values. The new row is only saved to the database file once conn.commit() is called.
7DELETE FROM students WHERE studentId = ? — A parameterised DELETE or UPDATE run from code: the ? in WHERE is filled by a value so only that record changes. cursor.rowcount of 0 means record not found.
8while choice != "q": — A menu loop repeats: show the menu, read a choice, call that option's function, and stop only when the user picks quit. Other input gets an invalid choice message.
9if is_valid(points): — Run the validation function first and only execute the INSERT or UPDATE when it returns True, so bad data is rejected before SQL runs and never reaches the database.
10except sqlite3.Error: — Catches a failed database call, such as an IntegrityError from a broken constraint, so the program shows a friendly message instead of crashing. Call rollback() to undo.
11useability principles — Six criteria for judging an interface: accessibility, effectiveness, ease of learning, efficiency, error tolerance and engagement. A good interface does well on all of them.
12SELECT * FROM students; — Run a SELECT before and after an INSERT, UPDATE or DELETE, then compare both results with the expected data and check that no other rows changed.
13reliability — A reliable solution gives correct results every time and keeps working when input is bad or an error occurs, so no data is lost.
14SELECT name FROM products WHERE stock > 0 — An efficient query asks only for the fields and rows it needs: name fields instead of SELECT *, WHERE to filter early, and an index or key to find records fast.
15completeness — Data quality where every record has a value in each required field and no needed records are missing. In SQL, a missing value shows as NULL.
16IS NULL — Tests whether a field has no value. Use WHERE field IS NULL, often with COUNT(*), to find and count incomplete records when checking data quality.