{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "

Data Science

\n", "

Lesson 15

\n", "

Data from a Database

\n", "\n", "
\n", "\n", "
Create a Database
\n", "\n", "
Retrieve All Records
\n", "\n", "
Challenge
\n", "\n", "
Scaling Up
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "OVERVIEW\n", "
\n", "\n", "
\n", "Although we've learned to work with data, clean it, prepare it, and model it, we still need to learn how to reliably use it from a database. We'll be covering this in this lesson. \n", "

\n", "We will be using Python to create a database file and interact with it. We will use a software called sqlite browser, which you should download and install here: http://sqlitebrowser.org/\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "CREATE A DATABASE\n", "
\n", "\n", "First, we will create our new database with the code below. Note the import required for interacting with a db file (sqlite3)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import sqlite3\n", "\n", "db_name = \"users\"\n", "\n", "connection = sqlite3.connect('{}.db'.format(db_name))\n", "c = connection.cursor()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you note the files in your current folder, you will see that this code created a new `.db` file called `test.db`. If you don't have the db created already, it will create one for you and connect to it. Otherwise, it will just connect. We will discuss how to connect to a remote database later.\n", "\n", "

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "NOTE\n", "
\n", "\n", ">- For the purposes of this exercise, I've already created a database with users in it for you. However, if you wanted to create a table of your own, the following example code would be helpful:\n", "\n", "```python\n", "def create_table():\n", "\tc.execute(\"\"\"CREATE TABLE IF NOT EXISTS users\n", "\t\t\t(id TEXT PRIMARY KEY,\n", "\t\t\tfirst_name TEXT, \n", "\t\t\tlast_name TEXT, \n", "\t\t\temail TEXT, \n", "\t\t\tgender TEXT)\"\"\")```\n", " \n", ">where `users` is your table name and `id` is your primary key.\n", "\n", "
\n", "
\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "RETRIEVE ALL THE RECORDS\n", "
\n", "\n", "We'll now grab all the records from the database and observe what they look like so we can interact with them a little bit. Run the following code for all the results." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "sql = \"SELECT * FROM users;\"\n", "c.execute(sql)\n", "result = c.fetchall()\n", "\n", "print(result)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can observe from the output above that all the records have been returned to us, just like we asked. How do we interact with them though? Just like an array!\n", "\n", "```python\n", "result[1] # will return ('1', 'Noemi', 'Penwright', 'npenwright0@prweb.com', 'Female')\n", "result[1][1] # will return 'Noemi'\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "CHALLENGE\n", "
\n", "\n", "What if we wanted to grab a record with a specific id?\n", "\n", "*In the code block before, write an sql statement that will get the user with id 3.*\n", "\n", "
\n", "\n", "
\n", "SCALING UP\n", "
\n", "Now, this is great and all, but what happens when we have a huge database full of records? We want to be able to only get a few records at a time, work with them, and then request some more (i.e., streaming the data into memory). If we continue trying to work with this large amount of data, our computer won't have enough RAM to support it. Let's see how this is done!" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Noemi\n", "Scott\n", "Torey\n", "Hillel\n", "Sammy\n", "Gregorius\n", "Carlene\n", "Sean\n", "Kerwinn\n", "Earl\n", "Bruce\n", "Dominica\n", "Chickie\n", "Nancy\n", "Alard\n", "Emmet\n", "Malachi\n", "Wendeline\n", "Valaria\n", "Krishnah\n", "Linus\n", "Jessa\n", "Denys\n", "Clarke\n", "Danell\n", "Ennis\n", "Jordan\n", "Benedict\n", "Mame\n", "Lars\n", "Leoine\n", "Maddy\n", "Megan\n", "Patricio\n", "Conroy\n", "Neill\n", "Mychal\n", "Krysta\n", "Isaac\n", "Elladine\n", "Yelena\n", "Amalita\n", "Johny\n", "Yankee\n", "Holly\n", "Anna-diane\n", "Carmela\n", "Freda\n", "Darbie\n", "Darcee\n", "Pooh\n", "Josefa\n", "Harriott\n", "Fayette\n", "Albertina\n", "Felita\n", "Agustin\n", "Bathsheba\n", "Fernandina\n", "Didi\n", "Hamid\n", "Ellery\n", "Torrance\n", "Donnajean\n", "Asa\n", "Lorinda\n", "Howey\n", "Willow\n", "Rena\n", "Foster\n", "Sholom\n", "Vladimir\n", "Goraud\n", "Justis\n", "Ted\n", "Beverlie\n", "Vernen\n", "Guillermo\n", "Rouvin\n", "Chevalier\n", "Conn\n", "Ninetta\n", "Isabel\n", "Bernie\n", "Michelle\n", "Donnie\n", "Marlene\n", "Kip\n", "Alister\n", "Gray\n", "Merrili\n", "Patsy\n", "Alexina\n", "Thacher\n", "Marilee\n", "Holli\n", "Ferdinande\n", "Luther\n", "Tasia\n", "Bernette\n", "Robinetta\n", "Helenka\n", "Knox\n", "Vonni\n", "Erek\n", "June\n", "Floria\n", "Jesselyn\n", "Dirk\n", "Babette\n", "Bethanne\n", "Britteny\n", "Mathew\n", "Danielle\n", "Galvin\n", "Skye\n", "Eddi\n", "Yolanda\n", "Falkner\n", "Temple\n", "Felipe\n", "Jessalyn\n", "Terrel\n", "Efrem\n", "Ede\n", "Melany\n", "Randolf\n", "Oby\n", "Tuesday\n", "Alley\n", "Clovis\n", "Shane\n", "Josiah\n", "Yorke\n", "Horatio\n", "Roxane\n", "Irma\n", "Purcell\n", "Stevana\n", "Alfonse\n", "Lacee\n", "Hersh\n", "Somerset\n", "Boote\n", "Granger\n", "Taffy\n", "Willi\n", "Perla\n", "Evin\n", "Bobbi\n", "Camella\n", "Adan\n", "Lonny\n", "Linnea\n", "Kaine\n", "Samuele\n", "Jessa\n", "Martina\n", "Mavis\n", "Fergus\n", "Cesaro\n", "Shir\n", "Rani\n", "Teodoro\n", "Eduard\n", "Nani\n", "Major\n", "Hester\n", "Rowland\n", "Jany\n", "Leicester\n", "Town\n", "Berte\n", "Freida\n", "Franklyn\n", "Georgianna\n", "Fey\n", "Gerek\n", "Orren\n", "Isiahi\n", "Lola\n", "De witt\n", "Aldous\n", "Julian\n", "Lucienne\n", "Aleen\n", "Octavius\n", "Alaric\n", "Jacky\n", "Gerick\n", "Delainey\n", "Harri\n", "Oriana\n", "Maryellen\n", "Sosanna\n", "Kele\n", "Dorthea\n", "Ellis\n", "Lissa\n", "Lexi\n", "Marlow\n", "Arlinda\n", "Jaimie\n", "Melesa\n", "Skelly\n", "Moina\n", "Tomkin\n", "Trula\n", "Cchaddie\n", "Wilhelmine\n", "Thomasa\n", "Yvor\n", "Evered\n", "Mozelle\n", "Elsy\n", "Marnie\n", "Mano\n", "Darcie\n", "Andros\n", "Stillmann\n", "Remus\n", "Radcliffe\n", "Eduard\n", "Jacquette\n", "Scottie\n", "Steve\n", "Bill\n", "Karrie\n", "Rosamond\n", "Osgood\n", "Guenevere\n", "Marillin\n", "Car\n", "Merry\n", "Adair\n", "Farrand\n", "Carey\n", "Welbie\n", "Carlye\n", "Jody\n", "Devinne\n", "Jae\n", "Flem\n", "Bertrand\n", "Latisha\n", "Cobb\n", "Berget\n", "Alma\n", "Mair\n", "Pierette\n", "Vanessa\n", "Dill\n", "Finlay\n", "Whittaker\n", "Humfried\n", "Read\n", "Warner\n", "Hamid\n", "Wendel\n", "Bram\n", "Conway\n", "Jacquelin\n", "Gilda\n", "Tabb\n", "Dory\n", "Sonya\n", "Mathew\n", "Zacharia\n", "Claudius\n", "Denver\n", "Brandon\n", "Christian\n", "Lombard\n", "Rolland\n", "Kesley\n", "Felicity\n", "Sanford\n", "Georgy\n", "Bonnee\n", "Pierce\n", "Klara\n", "Remus\n", "Odette\n", "Annalise\n", "Josefa\n", "Elane\n", "Luther\n", "Betta\n", "Latia\n", "Mikol\n", "Giselle\n", "Gavrielle\n", "Corena\n", "Mikel\n", "Vito\n", "Walden\n", "Oliy\n", "Henryetta\n", "Brook\n", "Keri\n", "Tomi\n", "Modestia\n", "Kate\n", "Shara\n", "Edsel\n", "Crissie\n", "Barbi\n", "Harlie\n", "Keary\n", "Denny\n", "Marshall\n", "Dion\n", "Liva\n", "Salvidor\n", "Delainey\n", "Francene\n", "Arleyne\n", "Greta\n", "Candis\n", "Kathy\n", "Josi\n", "Kaycee\n", "Edouard\n", "Brendon\n", "Nealy\n", "Selma\n", "Marijo\n", "Kimble\n", "Mohandis\n", "Tann\n", "Lennard\n", "Nicholas\n", "Nerita\n", "Wye\n", "Colline\n", "Carly\n", "Christoffer\n", "Roderick\n", "Mathian\n", "Smitty\n", "Jessie\n", "Megan\n", "Julietta\n", "Robb\n", "Tiffany\n", "Claudina\n", "Lyndel\n", "Agneta\n", "Maiga\n", "Valle\n", "Christyna\n", "Muffin\n", "Byrann\n", "Shaughn\n", "Erin\n", "Emiline\n", "Ranna\n", "Bone\n", "Smith\n", "Herschel\n", "Jocelyne\n", "Carmencita\n", "Ricca\n", "Natale\n", "Horst\n", "Staffard\n", "Martina\n", "Emalee\n", "Gabrila\n", "Mauricio\n", "Madge\n", "Milicent\n", "Merna\n", "Florie\n", "Kesley\n", "Joela\n", "Wendell\n", "Roxy\n", "Gennie\n", "Thomas\n", "Davis\n", "Brook\n", "Kelila\n", "Gasparo\n", "Malissia\n", "Jerry\n", "Bobbe\n", "Danika\n", "Wrennie\n", "Danny\n", "Charlene\n", "Mikel\n", "Imojean\n", "Aurlie\n", "Chrissy\n", "Harlin\n", "Araldo\n", "Staford\n", "Barb\n", "Cedric\n", "Hedy\n", "Jess\n", "Nathan\n", "Chris\n", "Meredeth\n", "Daria\n", "Wallache\n", "Saraann\n", "Cherilyn\n", "Robbie\n", "Doretta\n", "Cele\n", "Baldwin\n", "Maryann\n", "Julius\n", "Norine\n", "Bryce\n", "Carin\n", "Bonnibelle\n", "Kerwinn\n", "Rickert\n", "Curtice\n", "Tessie\n", "Zaneta\n", "Hartwell\n", "Terry\n", "Crista\n", "Alain\n", "Claretta\n", "Jabez\n", "Adria\n", "Clyde\n", "Gail\n", "Culley\n", "Elisha\n", "Kristos\n", "Stefanie\n", "Ted\n", "Raf\n", "Wilden\n", "Ewan\n", "Brina\n", "Fabian\n", "Astrix\n", "Isadore\n", "Mollie\n", "Osbourn\n", "Freddi\n", "Bobbi\n", "Muire\n", "Daniel\n", "Cull\n", "Jacquenette\n", "Jeremias\n", "Brook\n", "Roberta\n", "Genevieve\n", "Vincenty\n", "Juliann\n", "Rozalie\n", "Leonidas\n", "Salomo\n", "Liliane\n", "Gard\n", "Buiron\n", "Astrid\n", "Lauritz\n", "Wain\n", "Raimondo\n", "Reinaldo\n", "Colas\n", "Sharyl\n", "Fidel\n", "Oren\n", "Webster\n", "Mason\n", "Davin\n", "Germana\n", "Skipp\n", "Emmie\n", "Edyth\n", "Derward\n", "Agatha\n", "Kristyn\n", "Lanny\n", "Gabi\n", "Mile\n", "Vanna\n", "Bert\n", "Monro\n", "Paige\n", "Carrol\n", "Christean\n", "Zedekiah\n", "Collen\n", "Eal\n", "Corine\n", "Dennis\n", "Siobhan\n", "Davis\n", "Anna-diane\n", "Kary\n", "Tory\n", "Sukey\n", "Jamaal\n", "Ragnar\n", "Hayward\n", "Hansiain\n", "Cheri\n", "Preston\n", "Emylee\n", "Jesse\n", "Gabie\n", "Lanny\n", "Corbin\n", "Brendan\n", "Tania\n", "Nester\n", "Franciska\n", "Genvieve\n", "Garvin\n", "Jamill\n", "Herculie\n", "Nap\n", "Avery\n", "Muffin\n", "Sophey\n", "Marion\n", "Cleo\n", "Merrielle\n", "Constancia\n", "Fiona\n", "Malynda\n", "Gibb\n", "Caron\n", "Lyda\n", "Charil\n", "Nisse\n", "Shep\n", "Ansell\n", "Shanda\n", "Jeremiah\n", "Felisha\n", "Thatch\n", "Beryle\n", "Zollie\n", "Nickey\n", "Stacee\n", "Prent\n", "Casey\n", "Mathian\n", "Giovanni\n", "Peg\n", "Marris\n", "Charlton\n", "Penn\n", "Bellanca\n", "Rochell\n", "Maire\n", "Leontyne\n", "Petronia\n", "Patty\n", "Katha\n", "Rex\n", "Grady\n", "Elaine\n", "Melvyn\n", "Jarrod\n", "Daria\n", "Tymothy\n", "Muffin\n", "Burton\n", "Kassie\n", "Ruy\n", "Kelcy\n", "Ulric\n", "Delinda\n", "Stepha\n", "Henrik\n", "Trace\n", "Lorrie\n", "Cindelyn\n", "Pierre\n", "Carole\n", "Wren\n", "Kane\n", "Chan\n", "Sterling\n", "Derry\n", "Lynnet\n", "Anestassia\n", "Waly\n", "Vicky\n", "Sebastiano\n", "Jozef\n", "Georgeanna\n", "Silas\n", "Daphne\n", "Emmy\n", "Sal\n", "Michele\n", "Elmer\n", "Violet\n", "Berna\n", "Gerome\n", "Emory\n", "Janice\n", "Bessy\n", "Yehudit\n", "Farrell\n", "Melisandra\n", "Kareem\n", "Fair\n", "Tyrone\n", "Jorgan\n", "Lynne\n", "Melinde\n", "Rakel\n", "Gerek\n", "Alicea\n", "Skippy\n", "Guglielmo\n", "Alejoa\n", "Blinny\n", "Chrissy\n", "Gail\n", "Sibylle\n", "Arabele\n", "Addison\n", "Spenser\n", "Shaughn\n", "Shelley\n", "Brade\n", "Staffard\n", "Andie\n", "Elane\n", "Myron\n", "Heinrick\n", "Sherline\n", "Abba\n", "Modesta\n", "Sidonnie\n", "Chaim\n", "Johann\n", "Rebekah\n", "Leilah\n", "Lilly\n", "Winthrop\n", "Nisse\n", "Brannon\n", "Elmira\n", "Emily\n", "Helli\n", "Sidnee\n", "Leanna\n", "Clarine\n", "Quintilla\n", "Blakeley\n", "Raviv\n", "Anthony\n", "Marlowe\n", "Berne\n", "Carolan\n", "Giulio\n", "Taylor\n", "Mandie\n", "Isidor\n", "Cherianne\n", "Colly\n", "Thorpe\n", "Lek\n", "Osbourne\n", "Myles\n", "Scottie\n", "Jackie\n", "Eduino\n", "Errol\n", "Murial\n", "Obed\n", "Gar\n", "Farrel\n", "Micaela\n", "Berty\n", "Kliment\n", "Cece\n", "Maurits\n", "Benita\n", "Cherice\n", "Vera\n", "Ogdon\n", "Sigismondo\n", "Farrel\n", "Raoul\n", "Rania\n", "Alvina\n", "Marcella\n", "Loren\n", "Eadith\n", "Isidora\n", "Annnora\n", "Gibby\n", "Francklin\n", "Emelita\n", "Toinette\n", "Filide\n", "Shermie\n", "Kit\n", "Ivy\n", "Angeli\n", "Evangelina\n", "Perry\n", "Winn\n", "Osbourne\n", "Lemmie\n", "Rubin\n", "Brier\n", "Cazzie\n", "Hailee\n", "Deb\n", "Selene\n", "Farand\n", "Rodney\n", "Lynnea\n", "Daphne\n", "Kaja\n", "Ric\n", "Gwen\n", "Claude\n", "Janie\n", "Magnum\n", "Sidoney\n", "Malinda\n", "Cristal\n", "Tait\n", "Sebastien\n", "Roman\n", "Birdie\n", "Vite\n", "Kory\n", "Tobye\n", "Jo\n", "Rhys\n", "Trevar\n", "Herschel\n", "Durant\n", "Willard\n", "Jacinthe\n", "Vinita\n", "Loralie\n", "Kendall\n", "Car\n", "Marjy\n", "Leroy\n", "Ondrea\n", "Brennen\n", "Nelle\n", "Kassia\n", "Rahal\n", "Ara\n", "Katuscha\n", "Doris\n", "Miller\n", "Vannie\n", "Gustie\n", "Ninette\n", "Smitty\n", "Say\n", "Roxi\n", "Shawn\n", "Oswald\n", "Kerwin\n", "Tudor\n", "Salomone\n", "Marrilee\n", "Christophorus\n", "Lucio\n", "Roselia\n", "Husain\n", "Colene\n", "Shandie\n", "Glennie\n", "Sena\n", "Dietrich\n", "Madella\n", "Berny\n", "Loraine\n", "Dianne\n", "Nickolaus\n", "Deloria\n", "Haven\n", "Mason\n", "Jerry\n", "Rudyard\n", "Fanny\n", "Faulkner\n", "Witty\n", "Ivor\n", "Llewellyn\n", "Vannie\n", "Marys\n", "Ddene\n", "Joyce\n", "Dela\n", "Sibby\n", "Emanuele\n", "Eb\n", "Judon\n", "Archibald\n", "Sol\n", "Antony\n", "Phylis\n", "Cornelia\n", "Sandra\n", "Jessica\n", "Katti\n", "Max\n", "Marys\n", "Jayne\n", "Wallie\n", "Merilyn\n", "Keriann\n", "Christos\n", "Everard\n", "Dionisio\n", "Lilly\n", "Calla\n", "Vivyanne\n", "Tonya\n", "Quentin\n", "Barbaraanne\n", "Thorin\n", "Panchito\n", "Hazel\n", "Kate\n", "Derk\n", "Pauli\n", "Colet\n", "Zondra\n", "Nata\n", "Wake\n", "Stacia\n", "Perla\n", "Ardis\n", "Hedda\n", "Blondelle\n", "Natka\n", "Gordie\n", "Gabrila\n", "Verena\n", "Langsdon\n", "Ebeneser\n", "Chrysa\n", "Dana\n", "Gusella\n", "Hillary\n", "Sally\n", "Celia\n", "Vinnie\n", "Angelo\n", "Dav\n", "Jay\n", "Yard\n", "Teodoro\n", "Eleen\n", "Wait\n", "Flory\n", "Kalila\n", "Massimiliano\n", "Alvie\n", "Cindy\n", "Abby\n", "Lou\n", "Dannye\n", "Shannon\n", "Huey\n", "Leontyne\n", "Roger\n", "Mead\n", "Adlai\n", "Keeley\n", "Early\n", "Ailey\n", "Martainn\n", "Dagny\n", "Quinton\n", "Maurie\n", "Eada\n", "Neysa\n", "Jeni\n", "Titus\n", "Rudd\n", "Tobit\n", "Gayla\n", "Hobard\n", "Glynn\n", "Adamo\n", "Pam\n", "Vinny\n", "Alejandra\n", "Tiphani\n", "Sydelle\n", "Nikolaos\n", "Jamal\n", "Trina\n", "Zacharia\n", "Paulo\n", "Timothee\n", "Ronnie\n", "Marcy\n" ] } ], "source": [ "# create an array to hold all of our sql statements so we can execute them all at once.\n", "sql_transaction = []\n", "\n", "# we then define a function that will help us build the huge sql transaction to execute all at once.\n", "# in this case, it will execute after it sees 100 sql queries in the array, dump the array and begin\n", "# collecting again.\n", "def transaction_bldr(sql):\n", " # hint: we have to put the global keyword before sql_transaction so the function knows we're\n", " # going to be working with an outer scope variable. Similarly, we can just pass the\n", " # sql_transaction variable to this function through an argument.\n", " global sql_transaction\n", " sql_transaction.append(sql)\n", " \n", " if len(sql_transaction) > 100:\n", " # The 'BEING TRANSACTION' execution script tells the connection that you will be starting\n", " # a huge transaction.\n", " c.execute('BEGIN TRANSACTION')\n", " for s in sql_transaction:\n", " try:\n", " c.execute(s)\n", " result = c.fetchone()\n", " print(result[0])\n", " except:\n", " pass\n", " connection.commit()\n", " sql_transaction = []\n", " \n", "\n", "# loop through all the users and populate sql queries getting only their first name\n", "for i in range(1, 1001):\n", " # we will have to wrap this in a try/except because we pass that error in the transaction_bldr function\n", " try:\n", " sql = \"SELECT first_name FROM users WHERE id = '{}'\".format(i)\n", " transaction_bldr(sql)\n", " except Exception as e:\n", " print('select error', str(e))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

\n", "\n", "\n", "
\n", "AWESOME SAUCE\n", "
\n", "\n", "You now know how to pipe streams of data into your memory so you can begin working with it. As you can imagine from the above, a use case for this would be to pause after every 100 transactions, put all the data you need into an array and work with it accordingly. Once you're finished, run the next set of 100 transactions and replace the old results in your array with the new ones!\n", "\n", "
\n", "\n", "
\n", "NOTE\n", "
\n", ">- **The code to connect to a remote MySQL database is as follows:**\n", "\n", "```python\n", "import MySQLdb\n", "\n", "# connect to the database\n", "db = MySQLdb.connect(\"localhost\",\"inmoti6_pytest\",\"pytest\",\"inmoti6_pytest\" )\n", "\n", "# setup a cursor object using cursor() method\n", "c = db.cursor()\n", "\n", "# run an sql question\n", "c.execute(\"SELECT VERSION()\")\n", "\n", "# grab one result\n", "data = c.fetchone()\n", "```" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "

\n", "\n", "\n", "
\n", "CONGRATULATIONS\n", "
\n", "\n", "You made it to the end of this bootcamp!\n", "\n", "Hopefully you were able to learn a bit and become a step closer to becoming a pro Data Scientist. \n", "\n", "If you're interested in learning more about Machine Learning and Artificial Intelligence, feel free to contact Amit Maraj (amit.maraj@durhamcollege.ca) for more information!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }