From 22481882192166554e2de99246d2522a72815ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Fernando=20S=C3=A1nchez?= Date: Thu, 20 Feb 2020 11:28:55 +0100 Subject: [PATCH] Updated URL rdf and LOD --- lod/01_SPARQL_Introduction.ipynb | 283 +++--- lod/02_SPARQL_Custom_Endpoint.ipynb | 50 +- lod/03_SPARQL_Writers.ipynb | 1417 +++++++++++++++++++++++++++ lod/04_SPARQL_Advanced.ipynb | 661 +++++++++++++ lod/helpers.py | 12 +- lod/upload.sh | 53 + rdf/RDF.ipynb | 113 ++- 7 files changed, 2406 insertions(+), 183 deletions(-) create mode 100644 lod/03_SPARQL_Writers.ipynb create mode 100644 lod/04_SPARQL_Advanced.ipynb create mode 100644 lod/upload.sh diff --git a/lod/01_SPARQL_Introduction.ipynb b/lod/01_SPARQL_Introduction.ipynb index 3f275e5..b375dbe 100755 --- a/lod/01_SPARQL_Introduction.ipynb +++ b/lod/01_SPARQL_Introduction.ipynb @@ -6,11 +6,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "7276f055a8c504d3c80098c62ed41a4f", "grade": false, "grade_id": "cell-0bfe38f97f6ab2d2", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -56,11 +57,12 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "99aecbad8f94966d92d72dc911d3ff99", + "cell_type": "markdown", + "checksum": "40ccd05ad0704781327031a84dfb9939", "grade": false, "grade_id": "cell-4f8492996e74bf20", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -69,7 +71,7 @@ "\n", "* This notebook\n", "* External SPARQL editors (optional)\n", - " * YASGUI-GSI http://yasgui.cluster.gsi.dit.upm.es\n", + " * YASGUI-GSI http://yasgui.gsi.upm.es\n", " * DBpedia virtuoso http://dbpedia.org/sparql\n", "\n", "Using the YASGUI-GSI editor has several advantages over other options.\n", @@ -93,18 +95,19 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "99e3107f9987cdddae7866dded27f165", + "cell_type": "markdown", + "checksum": "81894e9d65e5dd9f3b6e1c5f66804bf6", "grade": false, "grade_id": "cell-70ac24910356c3cf", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, "source": [ "## Instructions\n", "\n", - "We will be using a semantic server, available at: http://fuseki.cluster.gsi.dit.upm.es/sitc.\n", + "We will be using a semantic server, available at: http://fuseki.gsi.upm.es/sitc.\n", "\n", "This server contains a dataset about [Beatles songs](http://www.snee.com/bobdc.blog/2017/11/sparql-queries-of-beatles-reco.html), which we will query with SPARQL.\n", "\n", @@ -122,11 +125,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "1d332d3d11fd6b57f0ec0ac3c358c6cb", "grade": false, "grade_id": "cell-eb13908482825e42", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -144,11 +148,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "code", "checksum": "aca7c5538b8fc53e99c92e94e6818c83", "grade": false, "grade_id": "cell-b3f3d92fa2100c3d", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -163,11 +168,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "e896b6560e45d5c385a43aa85e3523c7", "grade": false, "grade_id": "cell-04410e75828c388d", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -193,11 +199,12 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "96ca90572d6b275fa515c6b976115257", + "cell_type": "markdown", + "checksum": "34710d3bb8e2cf826833a43adb7fb448", "grade": false, "grade_id": "cell-2a44c0da2c206d01", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -210,7 +217,7 @@ "Some examples are:\n", "\n", "* DBpedia's virtuoso query editor https://dbpedia.org/sparql\n", - "* A javascript based client hosted at GSI: http://yasgui.cluster.gsi.dit.upm.es/\n", + "* A javascript based client hosted at GSI: http://yasgui.gsi.upm.es/\n", "\n", "[^1]: http://www.snee.com/bobdc.blog/2017/11/sparql-queries-of-beatles-reco.html" ] @@ -221,11 +228,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "79c60bd3d4c13f380aae5778c5ce7245", "grade": false, "grade_id": "cell-d645128d3af18117", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -241,11 +249,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "f7428fe79cd33383dfd3b09a0d951b6e", "grade": false, "grade_id": "cell-8391a5322a9ad4a7", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -260,11 +269,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "f6b5da583694dd5cc9326c670830875d", "grade": false, "grade_id": "cell-4f56a152e4d70c02", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -313,17 +323,18 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "7a9dc62ab639143c9fc13593e50500d4", + "cell_type": "code", + "checksum": "3bc71f851a33fa401d18ea3ab02cf61f", "grade": false, "grade_id": "cell-8ce8c954513f17e7", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "SELECT ?entity ?type\n", "WHERE {\n", @@ -338,11 +349,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "d6a79c2f5fd005a9e15a8f67dcfd4784", "grade": false, "grade_id": "cell-3d6d622c717c3950", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -375,17 +387,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "69e016b0224f410f03f6217ac30c03a8", + "cell_type": "code", + "checksum": "65be7168bedb4f6dc2f19e2138bab232", "grade": false, "grade_id": "cell-6e904d692b5facad", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "SELECT ?entity ?prop\n", "WHERE {\n", @@ -401,12 +414,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "97bd5d5383bd94a72c7452bc33e4b0f9", + "cell_type": "code", + "checksum": "e78b57fa9baab578f5a4bd22dc499fca", "grade": true, "grade_id": "cell-3fc0d3c43dfd04a3", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -440,7 +454,7 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "SELECT ?type\n", "WHERE {\n", @@ -465,7 +479,7 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "SELECT DISTINCT ?type\n", "WHERE {\n", @@ -507,17 +521,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "47c4f68e342ffe59a3804de7b6a3909b", + "cell_type": "code", + "checksum": "35563ff455c7e8b1c91f61db97b2011b", "grade": false, "grade_id": "cell-e615f9a77c4bc9a5", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "SELECT DISTINCT ?property\n", "WHERE {\n", @@ -532,12 +547,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "c9ffeba2d4ffc3e0b95f15a0ec6012c5", + "cell_type": "code", + "checksum": "7603c90d8c177e2e6678baa2f1b6af36", "grade": true, "grade_id": "cell-9168718938ab7347", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -569,7 +585,7 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX rdfs: \n", @@ -638,17 +654,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "8b0faf938efc1a64a70515da3c132605", + "cell_type": "code", + "checksum": "069811507dbac4b86dc5d3adc82ba4ec", "grade": false, "grade_id": "cell-0223a51f609edcf9", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX rdfs: \n", @@ -667,12 +684,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "e93d7336fd125d95996e60fd312a4e4d", + "cell_type": "code", + "checksum": "9833a3efa75c7e2784ef5d60aae2a13e", "grade": true, "grade_id": "cell-3c7943c6382c62f5", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -706,17 +724,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "271f2b194c2db4c558a46e8312b593e6", + "cell_type": "code", + "checksum": "b68a279085a1ed087f5e474a6602299e", "grade": false, "grade_id": "cell-8f43547dd788bb33", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX rdfs: \n", @@ -735,12 +754,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "9f1f7cec8ce4674971543728ada86674", + "cell_type": "code", + "checksum": "b4461d243cc058b1828769cc906d4947", "grade": true, "grade_id": "cell-e13a1c921af2f6eb", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -790,17 +810,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "9dcd9c6d51a61ac129cffa06e1463c66", + "cell_type": "code", + "checksum": "335403f01e484ce5563ff059e9764ff4", "grade": false, "grade_id": "cell-a0f0b9d9b05c9631", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX rdfs: \n", @@ -820,12 +841,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "a044b3fd6b8bd4e098bbe4d818cb4e9f", + "cell_type": "code", + "checksum": "45530eb91cbc5b3fddcc93d96f07e579", "grade": true, "grade_id": "cell-bc012ca9d7ad2867", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -867,17 +889,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "9da7a62b6237078f5eab7e593a8eb590", + "cell_type": "code", + "checksum": "8fb253675d2e8510e2c6780b960721e5", "grade": false, "grade_id": "cell-523b963fa4e288d0", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX rdfs: \n", @@ -898,12 +921,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "c8e3a929faf2afa72207c6921382654c", + "cell_type": "code", + "checksum": "f4474b302bc2f634b3b2ee6e1c7e7257", "grade": true, "grade_id": "cell-aa9a4e18d6fda225", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -945,17 +969,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "d8419711d2db43ad657e2658a1ea86c4", + "cell_type": "code", + "checksum": "c7b6620f5ba28b482197ab693cb7142a", "grade": false, "grade_id": "cell-e89d08031e30b299", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX m: \n", @@ -975,12 +1000,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "29404e07edf639cdc0ce0d82e654ec31", + "cell_type": "code", + "checksum": "c90e1427d7e48d9ae8abab40ff92e3b0", "grade": true, "grade_id": "cell-903d2be00885e1d2", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -1021,17 +1047,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "7a0a7206384e7e1d9eb4450dd9e9871f", + "cell_type": "code", + "checksum": "7556bacb20c1fbd059dec165c982908d", "grade": false, "grade_id": "cell-1429e4eb5400dbc7", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX m: \n", @@ -1053,12 +1080,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "bd4dc379fea969d513be0ea97ee75922", + "cell_type": "code", + "checksum": "34a8432e8d4cea70994c8214ed0e5eb6", "grade": true, "grade_id": "cell-907aaf6001e27e50", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -1094,7 +1122,7 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX rdfs: \n", @@ -1124,17 +1152,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "4a231b4d6874dad435512b988c17c39e", + "cell_type": "code", + "checksum": "2d0633303eedd0655e9b64bb00317dba", "grade": false, "grade_id": "cell-ee208c762d00da9c", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX rdfs: \n", @@ -1156,12 +1185,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "8118099bf14d9f0eb241c4d93ea6f0b9", + "cell_type": "code", + "checksum": "301aa479241fa02534ee047cf7577eee", "grade": true, "grade_id": "cell-ddeec32b8ac3d894", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -1193,7 +1223,7 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX i: \n", @@ -1228,7 +1258,7 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX i: \n", @@ -1261,17 +1291,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "4b0a0854457c37640aad67f375ed3a17", + "cell_type": "code", + "checksum": "3bc508872193750d57d07efbf334c212", "grade": false, "grade_id": "cell-dcd68c45c1608a28", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX i: \n", @@ -1294,12 +1325,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "f7122b2284b5d59d59ce4a2925f0bb21", + "cell_type": "code", + "checksum": "69edef3121b8dfab385a00cd181c956f", "grade": true, "grade_id": "cell-1e706b9c1c1331bc", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -1343,17 +1375,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "09621e7af911faf39a834e8281bc6d1f", + "cell_type": "code", + "checksum": "300df0a3cf9729dd4814b3153b2fedb4", "grade": false, "grade_id": "cell-0c7cc924a13d792a", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX s: \n", "PREFIX i: \n", @@ -1379,12 +1412,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "cebff8ce42f3f36923e81e083a23d24c", + "cell_type": "code", + "checksum": "22d6fcdb72a8b2c5ab496cdbb5e2740a", "grade": true, "grade_id": "cell-2541abc93ab4d506", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -1416,17 +1450,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "ea9797f3b2d001ea41d7fa7a5170d5fb", + "cell_type": "code", + "checksum": "e4e898c8a16b8aa5865dfde2f6e68ec6", "grade": false, "grade_id": "cell-d750b6d64c6aa0a7", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX rdfs: \n", "PREFIX s: \n", @@ -1478,17 +1513,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "2d82df272d43f678d3b19bf0b41530c1", + "cell_type": "code", + "checksum": "fade6ab714376e0eabfa595dd6bd6a8b", "grade": false, "grade_id": "cell-2f5aa516f8191787", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX rdfs: \n", "PREFIX s: \n", @@ -1513,12 +1549,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "bc83dd9577c9111b1f0ef5bd40c4ec08", + "cell_type": "code", + "checksum": "33e93ec2a3d1f9eb4b0310d4651b74c2", "grade": true, "grade_id": "cell-bcd0f7e26b6c11c2", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -1567,17 +1604,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "a1e20e2be817a592683dea89eed0120e", + "cell_type": "code", + "checksum": "09262d81449c498c37e4b9d9b1dcdfed", "grade": false, "grade_id": "cell-d3a742bd87d9c793", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX rdfs: \n", "PREFIX s: \n", @@ -1597,12 +1635,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "087630476d73bb415b065fafbd6024f0", + "cell_type": "code", + "checksum": "d583b30a1e00960df3a4411b6854c8c8", "grade": true, "grade_id": "cell-409402df0e801d09", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -1648,17 +1687,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "1d2cb88412c89c35861a4f9fccea3bf2", + "cell_type": "code", + "checksum": "9ddd2d1f50f841b889bfd29b175d06da", "grade": false, "grade_id": "cell-9d1ec854eb530235", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "\n", "PREFIX rdfs: \n", "\n", @@ -1680,12 +1720,13 @@ "deletable": false, "editable": false, "nbgrader": { - "checksum": "aa20aa4d11632ea5bd6004df3187d979", + "cell_type": "code", + "checksum": "0ea5496acd1c3edd9e188b351690a533", "grade": true, "grade_id": "cell-a79c688b4566dbe8", "locked": true, - "points": 0, - "schema_version": 1, + "points": 1, + "schema_version": 3, "solution": false } }, @@ -1738,17 +1779,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "508b7f8656e849838aa93cd38f1c6635", + "cell_type": "code", + "checksum": "d18e8b6e1d32aed395a533febb29fcb5", "grade": false, "grade_id": "cell-7ea1f5154cdd8324", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "PREFIX rdfs: \n", "PREFIX s: \n", "PREFIX i: \n", @@ -1782,17 +1824,18 @@ "metadata": { "deletable": false, "nbgrader": { - "checksum": "cff1f9c034393f8af055e1f930d5fe32", + "cell_type": "code", + "checksum": "f926fa3a3568d122454a12312859cda1", "grade": false, "grade_id": "cell-b6bee887a1b1fc60", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/sitc/\n", + "%%sparql http://fuseki.gsi.upm.es/sitc/\n", "PREFIX rdfs: \n", "PREFIX s: \n", "PREFIX i: \n", @@ -1844,7 +1887,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.2" + "version": "3.8.1" } }, "nbformat": 4, diff --git a/lod/02_SPARQL_Custom_Endpoint.ipynb b/lod/02_SPARQL_Custom_Endpoint.ipynb index 3e95636..37b2b89 100644 --- a/lod/02_SPARQL_Custom_Endpoint.ipynb +++ b/lod/02_SPARQL_Custom_Endpoint.ipynb @@ -6,11 +6,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "7276f055a8c504d3c80098c62ed41a4f", "grade": false, "grade_id": "cell-0bfe38f97f6ab2d2", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -31,11 +32,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "42642609861283bc33914d16750b7efa", "grade": false, "grade_id": "cell-0cd673883ee592d1", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -59,11 +61,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "a3ecb4b300a5ab82376a4a8cb01f7e6b", "grade": false, "grade_id": "cell-10264483046abcc4", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -80,11 +83,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "2fedf0d73fc90104d1ab72c3413dfc83", "grade": false, "grade_id": "cell-4f8492996e74bf20", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -100,11 +104,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "c5f8646518bd832a47d71f9d3218237a", "grade": false, "grade_id": "cell-eb13908482825e42", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -148,7 +153,7 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/hotels\n", + "%%sparql http://fuseki.gsi.upm.es/hotels\n", " \n", "SELECT ?g (COUNT(?s) as ?count) WHERE {\n", " GRAPH ?g {\n", @@ -160,14 +165,12 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ "You should see many graphs, with different triple counts.\n", "\n", - "The biggest one should be http://fuseki.cluster.gsi.dit.upm.es/synthetic" + "The biggest one should be http://fuseki.gsi.upm.es/synthetic" ] }, { @@ -183,11 +186,11 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/hotels\n", + "%%sparql http://fuseki.gsi.upm.es/hotels\n", " \n", "SELECT *\n", "WHERE {\n", - " GRAPH {\n", + " GRAPH {\n", " ?s ?p ?o .\n", " }\n", "}\n", @@ -233,13 +236,13 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/hotels\n", + "%%sparql http://fuseki.gsi.upm.es/hotels\n", "\n", "PREFIX schema: \n", " \n", "SELECT ?s ?o\n", "WHERE {\n", - " GRAPH {\n", + " GRAPH {\n", " ?s a ?o .\n", " }\n", "\n", @@ -264,11 +267,11 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/hotels\n", + "%%sparql http://fuseki.gsi.upm.es/hotels\n", " \n", "SELECT *\n", "WHERE {\n", - " GRAPH {\n", + " GRAPH {\n", " ?s ?p ?o .\n", " }\n", "}\n", @@ -295,7 +298,7 @@ "metadata": {}, "outputs": [], "source": [ - "%%sparql http://fuseki.cluster.gsi.dit.upm.es/hotels\n", + "%%sparql http://fuseki.gsi.upm.es/hotels\n", "\n", "PREFIX schema: \n", " \n", @@ -308,7 +311,7 @@ " SELECT ?g\n", " WHERE {\n", " GRAPH ?g {}\n", - " FILTER (str(?g) != 'http://fuseki.cluster.gsi.dit.upm.es/synthetic')\n", + " FILTER (str(?g) != 'http://fuseki.gsi.upm.es/synthetic')\n", " }\n", " }\n", "\n", @@ -339,12 +342,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "code", "checksum": "860c3977cd06736f1342d535944dbb63", "grade": true, "grade_id": "cell-9bd08e4f5842cb89", "locked": false, "points": 0, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -366,12 +370,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "code", "checksum": "1946a7ed4aba8d168bb3fad898c05651", "grade": true, "grade_id": "cell-9dc1c9033198bb18", "locked": false, "points": 0, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -393,12 +398,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "code", "checksum": "6714abc5226618b76dc4c1aaed6d1a49", "grade": true, "grade_id": "cell-6c18003ced54be23", "locked": false, "points": 0, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -449,7 +455,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.2" + "version": "3.8.1" } }, "nbformat": 4, diff --git a/lod/03_SPARQL_Writers.ipynb b/lod/03_SPARQL_Writers.ipynb new file mode 100644 index 0000000..887108b --- /dev/null +++ b/lod/03_SPARQL_Writers.ipynb @@ -0,0 +1,1417 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "7276f055a8c504d3c80098c62ed41a4f", + "grade": false, + "grade_id": "cell-0bfe38f97f6ab2d2", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "
\n", + "
\n", + "

Course Notes for Learning Intelligent Systems

\n", + "

Department of Telematic Engineering Systems

\n", + "
Universidad Politécnica de Madrid
\n", + "
\n", + " \"UPM\"\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "2387a77db61721ecc375a8275111ecaf", + "grade": false, + "grade_id": "cell-0cd673883ee592d1", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "## Introduction to Linked Open Data\n", + "\n", + "In this lecture, we will apply the same SPARQL concepts as in previous notebooks.\n", + "This time, instead of using a database specifically built for the exercise, we will be using DBpedia.\n", + "DBpedia is a semantic version of Wikipedia.\n", + "\n", + "The language we will use to query DBpedia is SPARQL, a semantic query language inspired by SQL.\n", + "For convenience, the examples in the notebook are executable, and they are accompanied by some code to test the results.\n", + "If the tests pass, you probably got the answer right.\n", + "\n", + "However, you can also use any other method to write and send your queries.\n", + "You may find online query editors particularly useful.\n", + "In addition to running queries from your browser, they provide useful features such as syntax highlighting and autocompletion.\n", + "Some examples are:\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "bc0ca2e21254707344c60f895cb204b4", + "grade": false, + "grade_id": "cell-10264483046abcc4", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "## Objectives\n", + "\n", + "* Learning SPARQL and the Linked Data principles by defining queries to answer a set of problems of increasing difficulty\n", + "* Learning how to use integrated SPARQL editors and programming interfaces to SPARQL." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "2fedf0d73fc90104d1ab72c3413dfc83", + "grade": false, + "grade_id": "cell-4f8492996e74bf20", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "## Tools\n", + "\n", + "See [the SPARQL notebook](./01_SPARQL_Introduction.ipynb#Tools)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Instructions\n", + "\n", + "As in previous notebooks, the exercises can be done in the notebook, using the `%%sparql` magic, and the set of tests.\n", + "\n", + "\n", + "After every query, you will find some python code to test the results of the query.\n", + "**Make sure you've run the tests before moving to the next exercise**.\n", + "If the test gives you an error, you've probably done something wrong.\n", + "You **do not need to understand or modify the test code**.\n", + "\n", + "If you prefer to edit your queries in a different editor, here are some options:\n", + "\n", + "* DBpedia's virtuoso query editor https://dbpedia.org/sparql\n", + "* A javascript based client hosted at GSI: http://yasgui.gsi.upm.es/\n", + "\n", + "If you use an editor, make sure to copy it to the notebook and run the tests, once you are getting the expected results." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "c5f8646518bd832a47d71f9d3218237a", + "grade": false, + "grade_id": "cell-eb13908482825e42", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "Run this line to enable the `%%sparql` magic command." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from helpers import sparql, solution, show_photos" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `%%sparql` magic command will allow us to use SPARQL inside normal jupyter cells.\n", + "\n", + "For instance, the following code:\n", + "\n", + "```python\n", + "%%sparql\n", + "\n", + "\n", + "``` \n", + "\n", + "Is the same as `run_query('', endpoint='http://dbpedia.org/sparql')` plus some additional steps, such as saving the results in a nice table format so that they can be used later and storing the results in a variable (`solution()`), which we will use in our tests.\n", + "\n", + "You do not need to worry about it, and **you can always use one of the suggested online editors if you wish**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exercises" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### First Select" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's start with a simple query. We will get a list of cities and towns in Madrid.\n", + "If we take a look at the DBpedia ontology or the page of any town we already know, we discover that the property that links towns to their community is [`isPartOf`](http://dbpedia.org/ontology/isPartOf), and [the Community of Madrid is also a resource in DBpedia](http://dbpedia.org/resource/Community_of_Madrid)\n", + "\n", + "Since there are potentially many cities to get, we will limit our results to the first 10 results:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "SELECT ?localidad\n", + "WHERE {\n", + " ?localidad \n", + "}\n", + "LIMIT 10" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, that query is very verbose because we are using full URIs.\n", + "To simplify it, we will make use of SPARQL prefixes:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX dbo: \n", + "PREFIX dbr: \n", + " \n", + "SELECT ?localidad\n", + "WHERE {\n", + " ?localidad dbo:isPartOf dbr:Community_of_Madrid.\n", + "}\n", + "LIMIT 10" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To make sure that the query returned something sensible, we can test it with some python code:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "assert 'localidad' in solution()['columns']\n", + "assert len(solution()['tuples']) == 10" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that you have some experience under your belt, it is time to design your own query.\n", + "\n", + "Your first task it to get a list of Spanish Novelits, using the skeleton below and the previous query to guide you.\n", + "\n", + "Pages for Spanish novelists are grouped in the *Spanish novelists* DBpedia category. You can use that fact to get your list.\n", + "In other words, the difference from the previous query will be using `dct:subject` instead of `dbo:isPartOf`, and `dbc:Spanish_novelists` instead of `dbr:Community_of_Madrid`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "eef1c62e2797bd3ef01f2061da6f83c4", + "grade": false, + "grade_id": "cell-7a9509ff3c34127e", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "\n", + "SELECT ?escritor\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "LIMIT 10" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "5a57d16cb2b53925f6e39fba429b7ef2", + "grade": true, + "grade_id": "cell-91240ded2cac7b6d", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert len(solution()['columns']) == 1 # We only use one variable, ?escritor\n", + "assert len(solution()['tuples']) == 10 # There should be 10 results" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using more criteria\n", + "\n", + "We can get more than one property in the same query. Let us modify our query to get the population of the cities as well." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dbo: \n", + "PREFIX dbr: \n", + "PREFIX dbp: \n", + " \n", + "SELECT ?localidad ?pop ?when\n", + "\n", + "WHERE {\n", + " ?localidad dbo:populationTotal ?pop .\n", + " ?localidad dbo:isPartOf dbr:Community_of_Madrid.\n", + " ?localidad dbp:populationAsOf ?when .\n", + "}\n", + "\n", + "LIMIT 100" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "assert 'localidad' in solution()['columns']\n", + "assert 'http://dbpedia.org/resource/Parla' in solution()['columns']['localidad']\n", + "assert ('http://dbpedia.org/resource/San_Sebastián_de_los_Reyes', '75912', '2009') in solution()['tuples']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Time to try it yourself.\n", + "\n", + "Get the list of Spanish novelists AND their name (using rdfs:label)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "9d4193612dea95da2d91762b638ad5e6", + "grade": false, + "grade_id": "cell-83dcaae0d09657b5", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs:\n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "\n", + "SELECT ?escritor ?name\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "LIMIT 10" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "86115c2a8982ad12b7250cf4341ae9c3", + "grade": true, + "grade_id": "cell-8afd28aada7a896c", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'escritor' in solution()['columns']\n", + "assert 'http://dbpedia.org/resource/Eduardo_Mendoza_Garriga' in solution()['columns']['escritor']\n", + "assert ('http://dbpedia.org/resource/Eduardo_Mendoza_Garriga', 'Eduardo Mendoza') in solution()['tuples']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Filtering and ordering" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the previous example, we saw that we got what seemed to be duplicated answers.\n", + "\n", + "This happens because entities can have labels in different languages (e.g. English, Spanish).\n", + "To restrict the search to only those results we're interested in, we can use filtering.\n", + "\n", + "We can also decide the order in which our results are shown.\n", + "\n", + "For instance, this is how we could use filtering to get only large cities in our example, ordered by population:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dbo: \n", + "PREFIX dbr: \n", + " \n", + "SELECT ?localidad ?pop ?when\n", + "\n", + "WHERE {\n", + " ?localidad dbo:populationTotal ?pop .\n", + " ?localidad dbo:isPartOf dbr:Community_of_Madrid.\n", + " ?localidad dbp:populationAsOf ?when .\n", + " FILTER(?pop > 100000)\n", + "}\n", + "ORDER BY ?pop\n", + "LIMIT 100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that ordering happens before limits." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "a38cb1aea7b1f01f6b37c088384e0a3d", + "grade": true, + "grade_id": "cell-cb7b8283568cd349", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "# We still have the biggest city\n", + "assert ('http://dbpedia.org/resource/Madrid', '3141991', '2014') in solution()['tuples']\n", + "# But the smaller ones are gone\n", + "assert 'http://dbpedia.org/resource/Tres_Cantos' not in solution()['columns']['localidad']\n", + "assert 'http://dbpedia.org/resource/San_Sebastián_de_los_Reyes' not in solution()['columns']['localidad']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, try filtering to get a list of novelists and their name in Spanish, ordered by name `(FILTER (LANG(?nombre) = \"es\") y ORDER BY`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "b6aaac8ab30d52a042c1efefbbff7550", + "grade": false, + "grade_id": "cell-ff3d611cb0304b01", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "\n", + "SELECT ?escritor ?nombre\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 1000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "3441fbd2267002acbb0d46d9ce94ba97", + "grade": true, + "grade_id": "cell-d70cc6ea394741bc", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert len(solution()['tuples']) >= 50\n", + "assert 'Adelaida García Morales' in solution()['columns']['nombre']\n", + "assert sum(1 for k in solution()['columns']['escritor'] if k == 'http://dbpedia.org/resource/Adelaida_García_Morales') == 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Optional" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From now on, we will focus on our Writers example.\n", + "\n", + "First, we will search for writers born in the XX century, using the [20th-century Spanish novelists](http://dbpedia.org/page/Category:20th-century_Spanish_novelists) category." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "e3ff089c983be1ae937f254b8d9d229a", + "grade": false, + "grade_id": "cell-ab7755944d46f9ca", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "# YOUR ANSWER HERE" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "cacdd08a8a267c1173304e319ffff563", + "grade": true, + "grade_id": "cell-cf3821f2d33fb0f6", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'Camilo José Cela' in solution()['columns']['nombre']\n", + "assert 'Javier Marías' in solution()['columns']['nombre']\n", + "assert all(x > '1850-12-31' and x < '2001-01-01' for x in solution()['columns']['nac'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In our last example, we were missing many novelists that are do not have birth information in DBpedia.\n", + "\n", + "We can specify optional values in a query using the `OPTIONAL` keyword.\n", + "When a set of clauses are inside an OPTIONAL group, the SPARQL endpoint will try to use them in the query.\n", + "If there are no results for that part of the query, the variables it specifies will not be bound (i.e. they will be empty).\n", + "\n", + "Using that, let us retrieve all the novelists, their birth and death date (if they are available)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "f4170cbbf042644e394d1eb9acf12ce3", + "grade": false, + "grade_id": "cell-254a18dd973e82ed", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbo:\n", + "\n", + "SELECT ?escritor ?nombre ?fechaNac ?fechaDef\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 200" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "29c6362adbdb5606e158f696594e1052", + "grade": true, + "grade_id": "cell-4d6a64dde67f0e11", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'Wenceslao Fernández Flórez' in solution()['columns']['nombre']\n", + "assert '1879-2-11' in solution()['columns']['fechaNac']\n", + "assert '' in solution()['columns']['fechaNac'] # Not all birthdates are defined\n", + "assert '' in solution()['columns']['fechaDef'] # Some deathdates are not defined" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bound" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can check whether the optional value for a key was bound in a SPARQL query using `BOUND(?key)`.\n", + "\n", + "This is very useful for two purposes.\n", + "First, it allows us to look for patterns that **do not occur** in the graph, such as missing properties.\n", + "For instance, we could search for the authors with missing birth information so we can add it.\n", + "Secondly, we can use bound in filters to get conditional filters.\n", + "We will explore both uses in this exercise." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get the list of Spanish novelists that are still alive.\n", + "A person is alive if their death date is not defined and the were born less than 100 years ago" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "f3c11121eb0d1328d2f5da3580f8d648", + "grade": false, + "grade_id": "cell-474b1a72dec6827c", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbo:\n", + "\n", + "SELECT ?escritor, ?nombre, year(?fechaNac) as ?nac\n", + "\n", + "WHERE {\n", + " \n", + "# YOUR ANSWER HERE\n", + "}\n", + "\n", + "# YOUR ANSWER HERE\n", + "LIMIT 1000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "770bbddef5210c28486a1929e4513ada", + "grade": true, + "grade_id": "cell-46b62dd2856bc919", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'Fernando Arrabal' in solution()['columns']['nombre']\n", + "assert 'Albert Espinosa' in solution()['columns']['nombre']\n", + "for year in solution()['columns']['nac']:\n", + " assert int(year) >= 1918" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, get the list of Spanish novelists that died before their fifties (i.e. younger than 50 years old), or that aren't 50 years old yet.\n", + "\n", + "Hint: you can use boolean logic in your filters (e.g. `&&` and `||`).\n", + "\n", + "Hint 2: Some dates are not formatted properly, which makes some queries fail when they shouldn't. You might need to convert between different types as a workaround. For instance, you could get the year from a date like this: `year(xsd:dateTime(str(?date)))`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "ed34857649c9a6926eb0a3a0e1d8198d", + "grade": false, + "grade_id": "cell-ceefd3c8fbd39d79", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbo:\n", + "\n", + "SELECT ?escritor, ?nombre, YEAR(?fechaNac) as ?nac, ?fechaDef\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 100" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "18bb2d8d586bf4a5231973e69958ab75", + "grade": true, + "grade_id": "cell-461cd6ccc6c2dc79", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'Javier Sierra' in solution()['columns']['nombre']\n", + "assert 'http://dbpedia.org/resource/Sanmao_(author)' in solution()['columns']['escritor']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Finding unique elements" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In our last example, our results show some authors more than once.\n", + "This is because some properties are defined more than once.\n", + "For instance, birth date is giving using different formats.\n", + "Even if we exclude that property from our results by not adding it in our `SELECT`, we will get duplicated lines.\n", + "\n", + "To solve this, we can use the `DISTINCT` keyword." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Modify your last query to remove duplicated lines.\n", + "In other words, authors should only appear once." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "34163ddb0400cd8ddd2c2e2cdf29c20b", + "grade": false, + "grade_id": "cell-2a39adc71d26ae73", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbo:\n", + "\n", + "SELECT DISTINCT ?escritor, ?nombre, year(?fechaNac) as ?nac\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 100" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "84ab7d64a45e03e6dd902216a2aad030", + "grade": true, + "grade_id": "cell-542e0e36347fd5d1", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'Javier Sierra' in solution()['columns']['nombre']\n", + "assert 'http://dbpedia.org/resource/Albert_Espinosa' in solution()['columns']['escritor']\n", + "\n", + "from collections import Counter\n", + "c = Counter(solution()['columns']['nombre'])\n", + "for count in c.values():\n", + " assert count == 1\n", + " \n", + "c1 = Counter(solution()['columns']['escritor'])\n", + "assert all(count==1 for count in c1.values())\n", + "# c = Counter(solution()['columns']['nombre'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using other resources" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get the list of living Spanish novelists born in Madrid.\n", + "\n", + "Hint: use `dbr:Madrid` and `dbo:birthPlace`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "25c8edcee216d536aac98fc9aa2b6422", + "grade": false, + "grade_id": "cell-d175e41da57c889b", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbr:\n", + "PREFIX dbo:\n", + "\n", + "SELECT DISTINCT ?escritor, ?nombre, ?lugarNac, year(?fechaNac) as ?nac\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 100" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "443608e177f514f2cddafa6c1d1e3cc7", + "grade": true, + "grade_id": "cell-fadd095862db6bc8", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'José Ángel Mañas' in solution()['columns']['nombre']\n", + "assert 'http://dbpedia.org/resource/Madrid' in solution()['columns']['lugarNac']\n", + "MADRID_QUERY = solution()['columns'].copy()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Traversing the graph" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get the list of works of the authors in the previous query (i.e. authors born in Madrid), if they have any.\n", + "\n", + "Hint: use `dbo:author`, which is a **property of a literary work** that points to the author." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "c1f22b82c4d0bd4102a6c38f7f933dc6", + "grade": false, + "grade_id": "cell-e4b99af9ef91ff6f", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbr:\n", + "PREFIX dbo:\n", + "\n", + "SELECT DISTINCT ?escritor, ?nombre, ?obra\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 10000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "51acaeb26379c6bd2f8c767001ef79ec", + "grade": true, + "grade_id": "cell-68661b73c2140e4f", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'http://dbpedia.org/resource/A_Heart_So_White' in solution()['columns']['obra']\n", + "assert 'http://dbpedia.org/resource/Tomorrow_in_the_Battle_Think_on_Me' in solution()['columns']['obra']\n", + "assert '' in solution()['columns']['obra'] # Some authors don't have works in dbpedia" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Traversing the graph" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get a list of living Spanish novelists born in Madrid, their name in Spanish, a link to their foto and a website (if they have one).\n", + "\n", + "If the query is right, you should see a list of writers after running the test code.\n", + "\n", + "Hint: `foaf:depiction` and `foaf: homepage`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "e3f8e18a006a763f5cdbe49c97b73f5f", + "grade": false, + "grade_id": "cell-b1f71c67dd71dad4", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbr:\n", + "PREFIX dbo:\n", + "\n", + "SELECT ?escritor ?web ?foto\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "ORDER BY ?nombre\n", + "LIMIT 100" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "2d40e7ceb7774b29a709092ee8dfa9f5", + "grade": true, + "grade_id": "cell-8b8ba7cca701c652", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "fotos = set(filter(lambda x: x != '', solution()['columns']['foto']))\n", + "assert len(fotos) > 2\n", + "show_photos(fotos) #show the pictures of the writers!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Union" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can merge the results of several queries, just like using `JOIN` in SQL.\n", + "The keyword in SPARQL is `UNION`, because we are merging graphs.\n", + "\n", + "`UNION` is useful in many situations.\n", + "For instance, when there are equivalent properties, or when you want to use two search terms and FILTER would be too inefficient.\n", + "\n", + "The syntax is as follows:\n", + "\n", + "```sparql\n", + "SELECT ?title\n", + "WHERE {\n", + " { ?book dc10:title ?title }\n", + " UNION\n", + " { ?book dc11:title ?title }\n", + " \n", + " ... REST OF YOUR QUERY ...\n", + "\n", + "}\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using UNION, get a list of distinct spanish novelists AND poets.\n", + "\n", + "Hint: Category: Spanish_poets" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "9c0da379841474601397f5623abc6a9c", + "grade": false, + "grade_id": "cell-21eb6323b6d0011d", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbr:\n", + "PREFIX dbo:\n", + "\n", + "SELECT DISTINCT ?escritor, ?nombre\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 10000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "f22c7db423410fcf3e8fce4ec0a8e9f9", + "grade": true, + "grade_id": "cell-004e021e877c6ace", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'Garcilaso de la Vega' in solution()['columns']['nombre']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also get the count of results either by inspecting the result (we will not cover this) or by aggregating the results using the `COUNT` operation.\n", + "\n", + "The syntax is:\n", + " \n", + "```sparql\n", + "SELECT COUNT(?variable) as ?count_name\n", + "```\n", + "\n", + "Try it yourself with our previous example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "cd7ce9212f587afe311c7631b3908de2", + "grade": false, + "grade_id": "cell-e35414e191c5bf16", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql http://dbpedia.org/sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbr:\n", + "PREFIX dbo:\n", + "\n", + "# YOUR ANSWER HERE\n", + "\n", + "WHERE {\n", + "# YOUR ANSWER HERE\n", + "}\n", + "LIMIT 10000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "68609fa02dcf7480e16f0e5eb7849e65", + "grade": true, + "grade_id": "cell-7a7ef8255a5662e2", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert len(solution()['columns']) == 1\n", + "column_name = list(solution()['columns'].keys())[0]\n", + "assert int(solution()['columns'][column_name][0]) > 200" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Additional exercises" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Find out if there are more dbpedia entries for writers (dbo:Writer) than for football players (dbo:SoccerPlayers)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get a list of European countries with a population higher than 20 million, in decreasing order of population, including their URI, name in English and population." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Find the country in the world that speaks the most languages. Show its name in Spanish, if available." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* [RDFLib documentation](https://rdflib.readthedocs.io/en/stable/).\n", + "* [Wikidata Query Service query examples](https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service/queries/examples)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Licence\n", + "The notebook is freely licensed under under the [Creative Commons Attribution Share-Alike license](https://creativecommons.org/licenses/by/2.0/). \n", + "\n", + "© 2018 Universidad Politécnica de Madrid." + ] + } + ], + "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.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lod/04_SPARQL_Advanced.ipynb b/lod/04_SPARQL_Advanced.ipynb new file mode 100644 index 0000000..20d399b --- /dev/null +++ b/lod/04_SPARQL_Advanced.ipynb @@ -0,0 +1,661 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "7276f055a8c504d3c80098c62ed41a4f", + "grade": false, + "grade_id": "cell-0bfe38f97f6ab2d2", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "
\n", + "
\n", + "

Course Notes for Learning Intelligent Systems

\n", + "

Department of Telematic Engineering Systems

\n", + "
Universidad Politécnica de Madrid
\n", + "
\n", + " \"UPM\"\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "bd478e6253226d24ba7f33cb9f6ba706", + "grade": false, + "grade_id": "cell-0cd673883ee592d1", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "## Advanced SPARQL\n", + "\n", + "This notebook complements [the SPARQL notebook](./01_SPARQL.ipynb) with some advanced commands.\n", + "\n", + "If you have not completed the exercises in the previous notebook, please do so before continuing.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "9ea4fd529653214745b937d5fc4559e5", + "grade": false, + "grade_id": "cell-10264483046abcc4", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "## Objectives\n", + "\n", + "* To cover some SPARQL concepts that are less frequently used " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "2fedf0d73fc90104d1ab72c3413dfc83", + "grade": false, + "grade_id": "cell-4f8492996e74bf20", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "## Tools\n", + "\n", + "See [the SPARQL notebook](./01_SPARQL_Introduction.ipynb#Tools)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "c5f8646518bd832a47d71f9d3218237a", + "grade": false, + "grade_id": "cell-eb13908482825e42", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "Run this line to enable the `%%sparql` magic command." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from helpers import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exercises" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Working with dates" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To explore dates, we will focus on our Writers example.\n", + "\n", + "First, search for writers born in the XX century.\n", + "You can use a special filter, knowing that `\"2000\"^^xsd:date` is the first date of year 2000." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "69e23e6e3dc06ca9d2b5d878c2baba94", + "grade": false, + "grade_id": "cell-ab7755944d46f9ca", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbo:\n", + "\n", + "SELECT ?escritor, ?nombre, year(?fechaNac) as ?nac\n", + "\n", + "WHERE {\n", + " ?escritor dct:subject dbc:Spanish_novelists .\n", + " ?escritor rdfs:label ?nombre .\n", + " ?escritor dbo:birthDate ?fechaNac .\n", + " FILTER(lang(?nombre) = \"es\") .\n", + " # YOUR ANSWER HERE\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 1000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "211c632634327a1fd805326fa0520cdd", + "grade": true, + "grade_id": "cell-cf3821f2d33fb0f6", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'Camilo José Cela' in solution()['columns']['nombre']\n", + "assert 'Javier Marías' in solution()['columns']['nombre']\n", + "assert all(int(x) > 1899 and int(x) < 2001 for x in solution()['columns']['nac'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, get the list of Spanish novelists that are still alive.\n", + "\n", + "A person is alive if their death date is not defined and the were born less than 100 years ago.\n", + "\n", + "Remember, we can check whether the optional value for a key was bound in a SPARQL query using `BOUND(?key)`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "e4579d551790c33ba4662562c6a05d99", + "grade": false, + "grade_id": "cell-474b1a72dec6827c", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbo:\n", + "\n", + "SELECT ?escritor, ?nombre, year(?fechaNac) as ?nac\n", + "\n", + "WHERE {\n", + " ?escritor dct:subject dbc:Spanish_novelists .\n", + " ?escritor rdfs:label ?nombre .\n", + " ?escritor dbo:birthDate ?fechaNac .\n", + "# YOUR ANSWER HERE\n", + " FILTER(lang(?nombre) = \"es\") .\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 1000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "770bbddef5210c28486a1929e4513ada", + "grade": true, + "grade_id": "cell-46b62dd2856bc919", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'Fernando Arrabal' in solution()['columns']['nombre']\n", + "assert 'Albert Espinosa' in solution()['columns']['nombre']\n", + "for year in solution()['columns']['nac']:\n", + " assert int(year) >= 1918" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Working with badly formatted dates (OPTIONAL!)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, get the list of Spanish novelists that died before their fifties (i.e. younger than 50 years old), or that aren't 50 years old yet.\n", + "\n", + "For the sake of simplicity, you can use the `year()` function.\n", + "\n", + "Hint: you can use boolean logic in your filters (e.g. `&&` and `||`).\n", + "\n", + "Hint 2: Some dates are not formatted properly, which makes some queries fail when they shouldn't. As a workaround, you could convert the date to string, and back to date again: `xsd:dateTime(str(?date))`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "2a24f623c23116fd23877facb487dd16", + "grade": false, + "grade_id": "cell-ceefd3c8fbd39d79", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbo:\n", + "\n", + "SELECT ?escritor, ?nombre, year(?fechaNac) as ?nac, ?fechaDef\n", + "\n", + "WHERE {\n", + " ?escritor dct:subject dbc:Spanish_novelists .\n", + " ?escritor rdfs:label ?nombre .\n", + " ?escritor dbo:birthDate ?fechaNac .\n", + " # YOUR ANSWER HERE\n", + "}\n", + "# YOUR ANSWER HERE\n", + "LIMIT 100" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "18bb2d8d586bf4a5231973e69958ab75", + "grade": true, + "grade_id": "cell-461cd6ccc6c2dc79", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert 'Javier Sierra' in solution()['columns']['nombre']\n", + "assert 'http://dbpedia.org/resource/Sanmao_(author)' in solution()['columns']['escritor']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Regular expressions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[Regular expressions](https://www.w3.org/TR/rdf-sparql-query/#funcex-regex) are a very powerful tool, but we will only cover the basics in this exercise.\n", + "\n", + "In essence, regular expressions match strings against patterns.\n", + "In their simplest form, they can be used to find substrings within a variable.\n", + "For instance, using `regex(?label, \"substring\")` would only match if and only if the `?label` variable contains `substring`.\n", + "But regular expressions can be more complex than that.\n", + "For instance, we can find patterns such as: a 10 digit number, a 5 character long string, or variables without whitespaces.\n", + "\n", + "The syntax of the regex function is the following:\n", + "\n", + "```\n", + "regex(?variable, \"pattern\", \"flags\")\n", + "```\n", + "\n", + "Flags are optional configuration options for the regular expression, such as *do not care about case* (`i` flag).\n", + "\n", + "As an example, let us find the cities in Madrid that contain \"de\" in their name." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sparql\n", + "\n", + "SELECT ?localidad\n", + "WHERE {\n", + " ?localidad .\n", + " ?localidad rdfs:label ?nombre .\n", + " FILTER (lang(?nombre) = \"es\" ).\n", + " FILTER regex(?nombre, \"de\", \"i\")\n", + "}\n", + "LIMIT 10" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, use regular expressions to find Spanish novelists whose **first name** is Juan.\n", + "In other words, their name **starts with** \"Juan\"." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "6e444c20b411033a6c45fd5a566018fa", + "grade": false, + "grade_id": "cell-a57d3546a812f689", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbr:\n", + "PREFIX dbo:\n", + "\n", + "# YOUR ANSWER HERE\n", + "\n", + "WHERE {\n", + " {\n", + " ?escritor dct:subject dbc:Spanish_poets .\n", + " }\n", + " UNION {\n", + " ?escritor dct:subject dbc:Spanish_novelists .\n", + " }\n", + " ?escritor rdfs:label ?nombre\n", + " FILTER(lang(?nombre) = \"es\") .\n", + "# YOUR ANSWER HERE\n", + "}\n", + "ORDER BY ?nombre\n", + "LIMIT 1000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "66db9abddfafa91c2dc25577457f71fb", + "grade": true, + "grade_id": "cell-c149fe65008f39a9", + "locked": true, + "points": 0, + "schema_version": 3, + "solution": false + } + }, + "outputs": [], + "source": [ + "assert len(solution()['columns']['nombre']) > 15\n", + "for i in solution()['columns']['nombre']:\n", + " assert 'Juan' in i\n", + "assert \"Robert Juan-Cantavella\" not in solution()['columns']['nombre']" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "1be6d6e4d8e74240ef07deffcbe5e71a", + "grade": false, + "grade_id": "cell-0c2f0113d97dc9de", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "## Group concat" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "c8dbb73a781bd24080804f289a1cea0b", + "grade": false, + "grade_id": "asdasdasdddddddddddasdasdsad", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "Sometimes, it is useful to aggregate results from form different rows.\n", + "For instance, we might want to get a comma-separated list of the names in each each autonomous community in Spain.\n", + "\n", + "In those cases, we can use the `GROUP_CONCAT` function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dbo: \n", + "PREFIX dbr: \n", + " \n", + "SELECT ?com, GROUP_CONCAT(?name, \",\") as ?places # notice how we rename the variable\n", + "\n", + "WHERE {\n", + " ?localidad dbo:isPartOf ?com .\n", + " ?com dbo:type dbr:Autonomous_communities_of_Spain .\n", + " ?localidad rdfs:label ?name .\n", + " FILTER (lang(?name)=\"es\")\n", + "}\n", + "\n", + "ORDER BY ?com\n", + "LIMIT 100" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "e100e2f89c832cf832add62c107e4008", + "grade": false, + "grade_id": "asdiopjasdoijasdoijasd", + "locked": true, + "schema_version": 3, + "solution": false + } + }, + "source": [ + "Try it yourself, to get a list of works by each of these authors:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "9f6e26faab2be98c72fb7a917ac5a421", + "grade": false, + "grade_id": "cell-2e3de17c75047652", + "locked": false, + "schema_version": 3, + "solution": true + } + }, + "outputs": [], + "source": [ + "%%sparql\n", + "\n", + "PREFIX rdfs: \n", + "PREFIX dct:\n", + "PREFIX dbc:\n", + "PREFIX dbr:\n", + "PREFIX dbo:\n", + "\n", + "# YOUR ANSWER HERE\n", + "\n", + "WHERE {\n", + " ?escritor dct:subject dbc:Spanish_novelists .\n", + " ?escritor rdfs:label ?nombre .\n", + " ?escritor dbo:birthDate ?fechaNac .\n", + " ?escritor dbo:birthPlace dbr:Madrid .\n", + " OPTIONAL {\n", + " ?obra dbo:author ?escritor .\n", + " ?obra rdfs:label ?titulo .\n", + " }\n", + " OPTIONAL {\n", + " ?escritor dbo:deathDate ?fechaDef .\n", + " }\n", + " FILTER (?fechaNac <= \"2000\"^^xsd:date).\n", + " FILTER (?fechaNac >= \"1918\"^^xsd:date).\n", + " FILTER (!bound(?fechaDef) || (?fechaNac >= \"1918\"^^xsd:date)) .\n", + " FILTER(lang(?nombre) = \"es\") .\n", + " FILTER(!bound(?titulo) || lang(?titulo) = \"en\") .\n", + "\n", + "}\n", + "ORDER BY ?nombre\n", + "LIMIT 10000" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Licence\n", + "The notebook is freely licensed under under the [Creative Commons Attribution Share-Alike license](https://creativecommons.org/licenses/by/2.0/). \n", + "\n", + "© 2018 Universidad Politécnica de Madrid." + ] + } + ], + "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.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lod/helpers.py b/lod/helpers.py index 7798189..e73a0d5 100644 --- a/lod/helpers.py +++ b/lod/helpers.py @@ -20,7 +20,9 @@ display_javascript(js, raw=True) def send_query(query, endpoint): - FORMATS = ",".join(["application/sparql-results+json", "text/javascript", "application/json"]) + FORMATS = ",".join(["application/sparql-results+json", + "text/javascript", + "application/json"]) data = {'query': query} # b = quote_plus(query) @@ -33,7 +35,11 @@ def send_query(query, endpoint): res = urlopen(r) data = res.read().decode('utf-8') if res.getcode() == 200: - return json.loads(data) + try: + return json.loads(data) + except Exception: + print('Got: ', data, file=sys.stderr) + raise raise Exception('Error getting results: {}'.format(data)) @@ -60,7 +66,7 @@ def solution(): def query(query, endpoint=None, print_table=False): global LAST_QUERY - endpoint = endpoint or "http://fuseki.cluster.gsi.dit.upm.es/sitc/" + endpoint = endpoint or "http://fuseki.gsi.upm.es/sitc/" results = send_query(query, endpoint) tuples = to_table(results) diff --git a/lod/upload.sh b/lod/upload.sh new file mode 100644 index 0000000..01a70a9 --- /dev/null +++ b/lod/upload.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +# This is a bit messy +if [ "$#" -lt 1 ]; then + graph="http://example.com/sitc/submission/" + endpoint="http://fuseki.gsi.upm.es/hotels/data" +else if [ "$#" -lt 2 ]; then + endpoint=$1 + graph_base="http://example.com/sitc" + else + if [ "$#" -lt 3 ]; then + endpoint=$1 + graph=$2 + else + echo "Usage: $0 [] []" + echo + exit 1 + fi + fi +fi + + +upload(){ + name=$1 + file=$2 + echo '###' + echo "Uploading: $graph" + echo "Graph: $graph" + echo "Endpoint: $endpoint" + curl -X POST \ + --digest -u admin:$PASSWORD \ + -H Content-Type:text/turtle \ + -T "$file" \ + --data-urlencode graph=$graph_base/$name \ + -G $endpoint + +} + + +total=0 +echo -n "Password: " +read -s PASSWORD + +echo "Uploading synthethic" +upload "synthetic" synthetic/reviews.ttl || exit 1 + +for i in *.ttl; do + identifier=$(echo ${i%.ttl} | md5sum | awk '{print $1}') + echo "Uploading $i" + upload $identifier $i + total=$((total + 1)) +done +echo Uploaded $total diff --git a/rdf/RDF.ipynb b/rdf/RDF.ipynb index 1dc4938..07c4a6e 100644 --- a/rdf/RDF.ipynb +++ b/rdf/RDF.ipynb @@ -6,11 +6,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "1fba29f718bbaa14890b305223712474", "grade": false, "grade_id": "cell-2bd9e19ffed99f81", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -31,11 +32,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "845cf125f1c5eb7aa3653ef461bffc67", "grade": false, "grade_id": "cell-51338a0933103db9", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -86,11 +88,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "5c2cccdf6463262a0f8bc89c64f97fb2", "grade": false, "grade_id": "cell-d8db3c16cee92ac1", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -175,11 +178,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "d2849a6154d4807b405e6ec84601c231", "grade": false, "grade_id": "cell-14e2327285737802", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -222,11 +226,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "fe9a246ba580c71385e9b83d414a1216", "grade": false, "grade_id": "cell-a1b60daabb1a9d00", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -240,11 +245,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "63879c425ec11742c95c728a578d109e", "grade": false, "grade_id": "cell-d9289e96b2b0f265", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -258,11 +264,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "32f1f607adb584aaea9fb90ae4d805b5", "grade": false, "grade_id": "cell-bb418e9bae1fef1a", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -277,11 +284,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "code", "checksum": "892f8491591c25defdea5fdcdd289489", "grade": false, "grade_id": "cell-4a1b60bd9974bbb1", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -295,12 +303,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "a855d3d63be5ea7f73fd85d645b21bfe", "grade": true, "grade_id": "cell-9ac392294d5708a1", "locked": false, "points": 0, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -320,11 +329,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "9a73f79f8f282874fb60011e6019e387", "grade": false, "grade_id": "cell-57f67d1e662b7f09", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -341,11 +351,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "18ad887c2f326ee59139b96860ce8893", "grade": false, "grade_id": "cell-16214ea73a9b689e", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -359,11 +370,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "ed2466715f57356f22ddeabfb101eb11", "grade": false, "grade_id": "cell-da88c2f8170436fe", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -382,11 +394,12 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "code", "checksum": "69182e8fadb9c9751f76786e0fcb8803", "grade": false, "grade_id": "cell-808cfcbf3891f39f", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -403,11 +416,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "60a9934c544eee9fc2c3745c36beb049", "grade": false, "grade_id": "cell-1c2ca86de107dec3", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -424,11 +438,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "code", "checksum": "12b5c7170326932ff3c7e1688a5769b2", "grade": false, "grade_id": "cell-0154f8481bf393e8", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -444,11 +459,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "b534d998c6d2e9f6bef8c2d88687a96b", "grade": false, "grade_id": "cell-adc7e6b7e96e8788", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -478,11 +494,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "67540252804835faea83d96aab87aa29", "grade": false, "grade_id": "cell-e73f1933742f7ab3", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -528,11 +545,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "d6f1bf2230282256e5fcb85dba0eef45", "grade": false, "grade_id": "cell-3241bf07ae153beb", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -563,11 +581,12 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "code", "checksum": "44f8be14db3d3e42b5b85f0485206346", "grade": false, "grade_id": "definition", "locked": false, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -594,12 +613,13 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "code", "checksum": "e8ba71b32e6d4f15aef9dc7fe70387fe", "grade": true, "grade_id": "cell-2fb6e144a6691ede", "locked": true, "points": 10, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -615,11 +635,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "75d90c9a83c694f61e51bd5c47a672d9", "grade": false, "grade_id": "cell-63a55e7b8b195d59", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -633,11 +654,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "23632182da48df109721378408e57f01", "grade": false, "grade_id": "cell-3843c3ce98a77c56", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -660,11 +682,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "6c4b25718f493ad5964370f412519543", "grade": false, "grade_id": "cell-f42c087c9065bb23", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -706,12 +729,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "code", "checksum": "c7af0b9af5a64773785cc890f2431c78", "grade": true, "grade_id": "cell-c2e5b58ea74e8276", "locked": false, "points": 1, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -728,11 +752,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "a29112f51cc3299c7cae27841feb7410", "grade": false, "grade_id": "cell-9bf9c7d7516fae75", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -750,12 +775,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "56a77e133b532997723bf2f8116389e4", "grade": true, "grade_id": "cell-17508ecf96884653", "locked": false, "points": 1, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -769,11 +795,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "9311bca044d7057c86dd753f5343e19b", "grade": false, "grade_id": "cell-d36826d6323c96e8", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -786,12 +813,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "ba7b24b557d627e2665ca31c75c24c23", "grade": true, "grade_id": "cell-17508ecf96884655", "locked": false, "points": 1, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -805,11 +833,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "853651c95cbcd69cd5f495f03d29d19a", "grade": false, "grade_id": "cell-e25a0db3fe8a6b4b", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -822,12 +851,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "779f0f750508eb52b2d98b92689e426b", "grade": true, "grade_id": "cell-30797c9ac87cc7e1", "locked": false, "points": 1, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -841,11 +871,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "f8fff644855ca50a5219598322aa9b32", "grade": false, "grade_id": "cell-33862c8e38173d9c", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -858,12 +889,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "8ef0ebd54eefb44ff7019f17f58be3ec", "grade": true, "grade_id": "cell-17508ecf96884657", "locked": false, "points": 1, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -877,11 +909,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "33e1ec78415c85a795e86211d88316c2", "grade": false, "grade_id": "cell-5f922dc14ad3236a", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -894,12 +927,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "b5f208a95a8803e97f82c5f2cdf319dd", "grade": true, "grade_id": "answer-missing", "locked": false, "points": 1, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -913,11 +947,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "26eb04e562aa6c7d29efa8318982a337", "grade": false, "grade_id": "cell-7a3c1553c4d6a9b7", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -961,12 +996,13 @@ "metadata": { "deletable": false, "nbgrader": { + "cell_type": "code", "checksum": "bf8d215c42321236b783601e7d072a05", "grade": true, "grade_id": "cell-ff2413f45311f086", "locked": false, "points": 0, - "schema_version": 1, + "schema_version": 3, "solution": true } }, @@ -981,11 +1017,12 @@ "deletable": false, "editable": false, "nbgrader": { + "cell_type": "markdown", "checksum": "cffc12120c51a7d994063f66d788570a", "grade": false, "grade_id": "cell-ec8df1a53c3d3f23", "locked": true, - "schema_version": 1, + "schema_version": 3, "solution": false } }, @@ -1027,7 +1064,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.2" + "version": "3.8.1" } }, "nbformat": 4,