cs107-lecture-examples

Example codes used during Harvard CS107 lectures
git clone https://git.0xfab.ch/cs107-lecture-examples.git
Log | Files | Refs | README | LICENSE

presidential.py (4972B)


      1 #!/usr/bin/env python3
      2 # vim: foldmethod=marker
      3 # File       : presidential.py
      4 # Description: SQLite database class demo for presidential candidates in 2008
      5 # Copyright 2022 Harvard University. All Rights Reserved.
      6 import sqlite3
      7 
      8 
      9 # main() {{{1
     10 def main():
     11     # create a connection to the database {{{2
     12     # https://www.python.org/dev/peps/pep-0249/#connection-objects
     13     db = sqlite3.connect('presidential.sqlite')
     14 
     15     # obtain a cursor object for the `db` database {{{2
     16     # https://www.python.org/dev/peps/pep-0249/#cursor-objects
     17     cursor = db.cursor()
     18 
     19     # drop existing tables to start fresh for the purpose of this demo
     20     cursor.execute('DROP TABLE IF EXISTS candidates')
     21     cursor.execute('DROP TABLE IF EXISTS contributors')
     22 
     23     # turn on FOREIGN KEY support in SQLite (off by default).  If
     24     # foreign_keys=1, a sqlite3.IntegrityError will be raised if a FOREIGN KEY
     25     # constraint fails.
     26     cursor.execute('PRAGMA foreign_keys=1')
     27 
     28     # create a table for the `candidates` {{{2
     29     cursor.execute(
     30         '''CREATE TABLE candidates (
     31     id INTEGER PRIMARY KEY NOT NULL,
     32     first_name TEXT,
     33     last_name TEXT,
     34     middle_initial TEXT,
     35     party TEXT NOT NULL)'''
     36     )
     37     db.commit()  # commit the changes to the database
     38 
     39     # insert rows {{{2
     40     cursor.execute(
     41         '''INSERT INTO candidates
     42     (id, first_name, last_name, middle_initial, party)
     43     VALUES (?, ?, ?, ?, ?)''', (16, 'Mike', 'Huckabee', '', 'R')
     44     )
     45 
     46     cursor.execute(
     47         '''INSERT INTO candidates
     48             (id, first_name, last_name, middle_initial, party)
     49             VALUES (?, ?, ?, ?, ?)''', (32, 'Ron', 'Paul', '', 'R')
     50     )
     51 
     52     cursor.execute(
     53         '''INSERT INTO candidates
     54             (id, first_name, last_name, middle_initial, party)
     55             VALUES (?, ?, ?, ?, ?)''', (20, 'Barack', 'Obama', '', 'D')
     56     )
     57 
     58     db.commit()  # commit the changes to the database
     59 
     60     # queries {{{2
     61     # getting all columns returned in rows {{{3
     62     cursor.execute("SELECT * FROM candidates")
     63     rows = cursor.fetchall()
     64     print(f'All rows and columns: got {len(rows)} rows')
     65     for row in rows:
     66         print(row)
     67 
     68     # explicit selects with WHERE {{{3
     69     cursor.execute("SELECT * FROM candidates WHERE first_name = 'mike'")
     70     # cursor.execute("SELECT * FROM candidates WHERE LOWER(first_name) = 'mike'")
     71     rows = cursor.fetchall()
     72     print(f"Looking for 'mike': got {len(rows)} rows")
     73     for row in rows:
     74         print(row)
     75 
     76     # explicit select of specified column {{{3
     77     cursor.execute("SELECT first_name FROM candidates")
     78     rows = cursor.fetchall()
     79     print(f"Looking for first_name: got {len(rows)} rows")
     80     for row in rows:
     81         print(row)
     82 
     83     # create a table for the `contributors` {{{2
     84     cursor.execute(
     85         '''CREATE TABLE contributors (
     86               id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
     87               last_name TEXT,
     88               first_name TEXT,
     89               middle_name TEXT,
     90               street_1 TEXT,
     91               street_2 TEXT,
     92               city TEXT,
     93               state TEXT,
     94               zip TEXT, 
     95               amount FLOAT(7,3),
     96               date DATETIME,
     97               candidate_id INTEGER NOT NULL,
     98               FOREIGN KEY(candidate_id) REFERENCES candidates(id))'''
     99     )
    100     db.commit()  # commit the changes to the database
    101 
    102     # add contributors {{{2
    103     contributors = [
    104         (
    105             "Agee", "Steven", "", "549 Laurel Branch Road", "", "Floyd", "VA",
    106             int(24091), 500.0, '2007-06-30', 16
    107         ),
    108         (
    109             "Buck", "Jay", "K.", "1855 Old Willow Rd Unit 322", "",
    110             "Northfield", "IL", int(600932918), 200.0, '2007-09-12', 20
    111         ),
    112         (
    113             "Choe", "Hyeokchan", "", "207 Bridle Way", "", "Fort Lee", "NJ",
    114             int(70246302), -39.50, '2008-04-21', 32
    115         ),
    116     ]
    117 
    118     cursor.executemany(
    119         '''INSERT INTO contributors
    120     (last_name, first_name, middle_name, street_1, street_2, city, state, zip,
    121     amount, date, candidate_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
    122         contributors
    123     )
    124     db.commit()
    125 
    126     cursor.execute('SELECT last_name FROM contributors WHERE amount <= 200')
    127     for row in cursor.fetchall():
    128         print(row)
    129 
    130     # foreign key violation {{{2
    131     try:
    132         cursor.execute(
    133             '''INSERT INTO contributors
    134         (last_name, first_name, middle_name, street_1, street_2, city, state, zip,
    135         amount, date, candidate_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
    136             (
    137                 "Buckler", "Steve", "", "24351 Armada Dr.", "", "Dana Point",
    138                 "CA", int(926291), 50, '2007-07-30', 34
    139             )
    140         )
    141     except sqlite3.IntegrityError as e:
    142         # we expect this error and allow to pass such that we can close the
    143         # database in the next section
    144         print(e)
    145         pass
    146 
    147     # close database when done {{{2
    148     db.close()
    149 
    150 
    151 # __main__ {{{1
    152 if __name__ == "__main__":
    153     main()