diff --git a/year4/semester2/CS4423/materials/CS4423-W01-1.pdf b/year4/semester2/CS4423/materials/CS4423-W01-1.pdf deleted file mode 100644 index 34459002..00000000 Binary files a/year4/semester2/CS4423/materials/CS4423-W01-1.pdf and /dev/null differ diff --git a/year4/semester2/CS4423/materials/CS4423-W01-2.html b/year4/semester2/CS4423/materials/CS4423-W01-2.html deleted file mode 100644 index 5f2aa5f6..00000000 --- a/year4/semester2/CS4423/materials/CS4423-W01-2.html +++ /dev/null @@ -1,9934 +0,0 @@ -None - - - - -CS4423-W01-2 - - - - - - - - - - - - - - - - - - -
-
- -
-
- -
- -
-
- -
-
- -
-
- -
-
- -
- - -
-
- -
-
- -
- - -
-
- -
-
- -
-
- -
-
- -
- -
- - -
-
- -
- -
-
- -
- - -
-
- -
- - -
- - -
- - -
- - -
-
- -
- - -
-
- -
- - -
- - -
- - -
- - -
-
- -
- - -
-
- -
-
- -
- - -
-
- -
- - -
-
- -
- - -
- - -
-
- -
- - -
- -
-
- -
- - -
-
- -
- - -
- - -
-
- -
- - -
- - -
- - -
- - -
- - -
-
- -
- - -
- - -
-
- -
-
- -
-
- -
- - -
- - -
- - -
-
- -
- - -
- - -
- - -
-
- -
-
- -
-
- -
- - -
- - -
- - -
-
- -
- - -
- - -
- -
- - -
-
- -
- -
- - -
- - -
- - -
- - -
- - -
-
- -
- - -
-
- -
- - -
- - -
- - -
- - -
- -
- - -
-
- -
- -
- - -
-
- -
-
- -
-
- -
-
- -
-
- -
- - -
- - -
-
- -
- - -
-
- -
- - -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
- - -
- -
-
- - diff --git a/year4/semester2/CS4423/materials/CS4423-W02-1.ipynb b/year4/semester2/CS4423/materials/CS4423-W02-1.ipynb deleted file mode 100644 index 69393763..00000000 --- a/year4/semester2/CS4423/materials/CS4423-W02-1.ipynb +++ /dev/null @@ -1,1106 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "toc": true - }, - "source": [ - "

Table of Contents

\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "# CS4423 : Week 02 - Lecture 1 - Networks [$\\color{red}{\\text{DRAFT}}$]\n", - "# More on Graphs, and `networkx`\n", - "\n", - "Niall Madden, \n", - "School of Mathematical and Statistical Sciences \n", - "University of Galway\n", - "\n", - "(These notes are adapted from Angela Carnevale's work)\n", - "\n", - "This notebook is at https://www.niallmadden.ie/2425-CS4423/W02/CS4423-W02-1.ipynb\n", - "You can read the HTML version at https://www.niallmadden.ie/2425-CS4423/W02/CS4423-W02-1.html\n", - "\n", - "
This version of this notebook was written by Niall Madden, adapted from notebooks by Angela Carnevale.
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "## News: \n", - "### Labs\n", - "\n", - "Labs start next week, and an (reintroduction) to Python. This will run:\n", - "* Tuesday at 4 in AC215 (slight chance this might get moved to Tuesday at 3), and\n", - "* Wednesday at 10am in CA116a. \n", - "\n", - "These rooms are not labs: BYoD! (Bring Your Own Device)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Website\n", - "I now plan to post all notes to https://www.niallmadden.ie/2425-CS4423/ as well as to Canvas." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "## `networkx`\n", - "Last week we learned a little about the `networkx` package. We'll return to that now, while also revisiting some key ideas about graphs." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As ever, we'll start with importing the `networkx` module, as well as `numpy`: more about that later. And we'll define the `opts` option dictionary." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "slide" - } - }, - "outputs": [], - "source": [ - "import networkx as nx\n", - "import numpy as np\n", - "opts = { \"with_labels\": True, \"node_color\": 'y' } # show labels; yellow noodes" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "To create a graph with nodes $1$, $2$, $3$, $4$, $5$, and edges between all even and odd labelled nodes:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [], - "source": [ - "K32 = nx.Graph()\n", - "K32.add_edges_from([(1, 2), (1,4), (2,3), (2,5), (3,4), (4,5)])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We'll later learn this is the graph $K_{3,2}$. Now draw it:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [], - "source": [ - "nx.draw(K32, **opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "We can also be lazy, and just give $2$-letter strings for the edges: this implicitly defines the nodes too. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [], - "source": [ - "K33 = nx.Graph([\"A1\", \"A2\", \"A3\", \"B1\", \"B2\", \"B3\", \"C1\", \"C2\", \"C3\"])\n", - "nx.draw(K33, **opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "### Check basic properties:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(f\"K33 has {K33.number_of_nodes()} nodes and {K33.number_of_edges()} edges\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "print(f\"This is the same as saying K33 order {K33.order()} and size {K33.size()}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To list the nodes and edges (as lists)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "list(K33.nodes)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "list(K33.edges)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "A **loop** over a graph `G` will effectively loop over `G`'s nodes. As an example, (recall?) that the **degree** of a node is the number of edges incident to it (or, if you prefer, the number of neighbours)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "for node in K33:\n", - " print(f\"node {node} has neighbours {list(K33.neighbors(node))}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "### Adding and removing nodes and edges\n", - "\n", - "We say that \n", - "* `G.add_node('v')` adds a node to $G$ called 'v'\n", - "* `G.add_nodes_from([2, 3, 5])` adds all the nodes from a list\n", - "* `G.add_nodes_from(H])` adds all the nodes from Graph $H$ to Graph $G$\n", - "* `G.add_edge('x','y')` add edge from Node $x$ to Node $y$, adding one or both nodes, if needed.\n", - "* `G.add_edges_from([(1,5), (2,5), (3,5)])` add edges from a list\n", - "* `G.add_edges_from(H.edges)` add edges from another graph\n", - "* `G.remove_edge('x','y')` remove edge from $x$ to $y$, but keep the nodes\n", - "* `G.remove_node('x')` remove node $x$ and any edge it was incident to." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "## Neighbours and degree\n", - "\n", - "(As we've seen) \n", - "* The neighbours of a node are those that it shares an edge with\n", - "* the degree of a node is the number of edges incident to it (or, if you prefer, the number of neighbours).\n", - "\n", - "Let's look at an example:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Edges1 = [('Aoife', 'Brian'), ('Aoife', 'Ciara'), ('Aoife', 'Daire'), ('Aoife', 'Ella'), \n", - " ('Aoife', 'Finn'), ('Brian', 'Ciara'), ('Brian', 'Finn'), ('Ciara', 'Daire'), \n", - " ('Daire', 'Ella'), ('Ella', 'Finn') ]\n", - "G1 = nx.Graph(Edges1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "nx.draw(G1, **opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "This is example, which is known as a *wheel graph\" is chosen because it exhibits a famous concept in Network Science: *The Friendship Paradox*: your friends (probably) have more friends, on average, than you do!\n", - "\n", - "Explanation:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "slideshow": { - "slide_type": "notes" - } - }, - "outputs": [], - "source": [ - "#pos = nx.nx_agraph.graphviz_layout(G1)\n", - "#nx.draw(G1, pos=pos,**opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "## Important Graphs\n", - "\n", - "In this section we'll discuss some important examples of graphs, which we'll return to later as key examples of networks. These include\n", - "* Complete Graphs\n", - "* Bipartite and complete bipartite graphs\n", - "* Path graphs" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "### Complete Graphs\n", - "\n", - "The [**complete graph**](https://en.wikipedia.org/wiki/Complete_graph)\n", - "on a vertex set $X$ is the graph with edge set all of $\\binom{X}{2}$. That is: every node is a neighbour of every other node. It is denoted $K_n$ where $n=|X|$. E.g., if $X=\\{0,1,2,3\\}$, then $K_4$ (\"the complete graph on 4 nodes\") has edges $E=\\{01, 02, 03, 12, 13, 23\\}$." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [], - "source": [ - "nodes = range(4)\n", - "list(nodes)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "E4 = [(x, y) for x in nodes for y in nodes if x < y]\n", - "print(E4)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "K4 = nx.Graph(E4)\n", - "nx.draw(K4)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "While it is somewhat straightforward to find all $2$-element\n", - "subsets of a given set $X$ with a short `python` program,\n", - "it is probably more convenient (and possibly efficient) to use a function from the\n", - "`itertools` package for this purpose." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [], - "source": [ - "from itertools import combinations\n", - "nodes5 = range(5)\n", - "combinations(nodes5, 2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "print(list(combinations(nodes5, 2)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "K5 = nx.Graph(combinations(nodes5, 2))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [], - "source": [ - "nx.draw(K5, **opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "`networkx` has a built-in function to create complete graphs: `complete_graph` [[doc]](https://networkx.org/documentation/stable//reference/generated/networkx.generators.classic.complete_graph.html)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "nx.draw(nx.complete_graph(\"NETWORKS\"), **opts)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "nx.draw(nx.complete_graph(22), **opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "### Bipartite Graphs\n", - "\n", - "A graph is **bipartite** if we can divide the node set, $X$, into two subsets $X_1$ and $X_2$ such that \n", - "* $X_1 \\cap X_2 = \\emptyset$ (the sets have no edge in common)\n", - "* $X_1 \\cup X_2 = X$ \n", - "* For any edge $(u_1,u_2)$ we have $u_1 \\in X_1$ and $u_2 \\in X_2$. That is we only ever have edges between nodes from different sets. \n", - "\n", - "Such graphs are very common in Network Science, where nodes in the network represent two different types of entities. For example, we might have a graph where nodes represent students and modules, with edges between students and modules they are enrolled in (often called an affiliation network)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Edges2 = [('Aoife', 'CS4423'), ('Aoife', 'CS319'), ('Aoife', 'MA432'), \n", - " ('Brian', 'CS4423'), ('Brian', 'CS319'), \n", - " ('Ciara', 'CS319'), ('Ciara', 'MA432'), \n", - " ('Daire', 'MA432') ]\n", - "G2 = nx.Graph(Edges2)\n", - "nx.draw(G2, **opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "Somehow that previous graph did not catch the essence of the network: there are two different types of node. We could make that clearer, by colouring the nodes. Here we'll do it manually (later, automatically)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [], - "source": [ - "print(G2.nodes)\n", - "color_list= ['c','y','y','y','c', 'c','c'] # y=yellow; c=cyan\n", - "nx.draw(G2, node_color=color_list, with_labels=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "### Complete Bipartite Graphs\n", - "\n", - "A **complete bipartite graph** is a particular bipartite graph where there is an edge between every node in $X_1$ and every node in $X_2$. Such graphs are denoted $K_{m,n}$ where $|X_1|=m$ and $|X_2|=n$. (We met $K_{2,2}$ and $K_{3,3}$ earlier). \n", - "\n", - "As usual, there is a built-in generator: `complete_bipartite_graph` [[doc]](https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.bipartite.generators.complete_bipartite_graph.html)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "K33 = nx.complete_bipartite_graph(3,3)\n", - "nx.draw(K33,**opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "### Path Graphs\n", - "\n", - "The **Path Graph** with $n$ nodes, denoted $P_n$, is one where two nodes have degree 1, and the other $n-2$ have degree 2:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "P4 = nx.Graph([\"ab\", \"bc\", \"cd\", \"de\"])\n", - "nx.draw(P4)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "The built-in `nerworkx`generator is called `path_graph` [[doc]](https://networkx.org/documentation/stable/reference/generated/networkx.generators.classic.path_graph.html)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "P10 = nx.path_graph(10)\n", - "nx.draw(P10)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "### Cycle Graphs\n", - "\n", - "Our last example: the **cycle** graph, which as a path graph, but with an edge between the two \"end\" nodes. If it has $n$ nodes, we denote it $C_n$. You can make one with `cycle_graph(n)`, but here we'll do it manually.\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "C5 = nx.Graph(['01', '12', '23', '34', '40'])\n", - "nx.draw(C5, **opts) " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "nx.draw(nx.cycle_graph(6))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "### Petersen Graph\n", - "\n", - "The [Petersen Graph](https://en.wikipedia.org/wiki/Petersen_graph)\n", - "is a graph on $10$ vertices with $15$ edges.\n", - "\n", - "It can be constructed \n", - "as the complement of the line graph of the complete graph $K_5$,\n", - "i.e.,\n", - "as the graph with vertex set\n", - "$$X = \\binom{\\{0,1,2,3,4\\}}{2}$$ (the edge set of $K_5$) and\n", - "with an edge between $x, y \\in X$ whenever $x \\cap y = \\emptyset$." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "nx.draw(K5, **opts)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "lines = K5.edges\n", - "print(list(lines))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "print(list(combinations(lines, 2)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "edges = [e for e in combinations(lines, 2) \n", - " if not set(e[0]) & set(e[1])]\n", - "len(edges)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "P = nx.Graph(edges)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "nx.draw(P, **opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "Even though there is no parameter involved in this example,\n", - "it might be worth wrapping the construction up into a `python`\n", - "function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "def petersen_graph():\n", - " nodes = combinations(range(5), 2)\n", - " G = nx.Graph()\n", - " for e in combinations(nodes, 2):\n", - " if not set(e[0]) & set(e[1]):\n", - " G.add_edge(*e)\n", - " return G" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "nx.draw(petersen_graph(), **opts)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "## Code Corner" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "### `python`" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "* **list unpacking** operator `*e`: if `e` is a list, an\n", - "argument `*e` passes the elements of `e` as individual arguments\n", - "to a function call." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "* **dictionary unpacking** operator `**opts`: `python` function calls take **positional** arguments and **keyword** arguments. The keyword arguments can be collected in a dictionary `opts` (with the keywords as keys). This dictionary can then be passed into the function call in its \"unwrapped\" form `**opts`." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "* **set intersection**: if `a` and `b` are sets then `a & b` represents the intersection of `a` and `b`. In a boolean context, an empty set counts as `False`, and a non-empty set as `True`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "a = set([1,2,3])\n", - "b = set([3,4,5])\n", - "a & b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "bool({}), bool({3})" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "* `list` [[doc]](https://docs.python.org/3/library/stdtypes.html#list) turns its argument into a `python` list (if possible)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "list(\"networks\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "source": [ - "* **list comprehension** [[doc]](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions) allows the construction of new list from old ones\n", - "without explicit `for` loops (or `if` statements)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "hideCode": false, - "hidePrompt": false - }, - "outputs": [], - "source": [ - "[(x, y) for x in range(4) for y in range(4) if x < y]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "hideCode": false, - "hidePrompt": false, - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "## Exercises\n", - "\n", - "1. For what values of $n$ is $K_n$ bipartite?\n", - "2. For what values of $m$ and $n$ is $K_{m,n}$ bipartite?\n", - "3. For what values of $n$ is $P_n$ bipartite?\n", - "4. For what values of $n$ is $C_n$ bipartite?\n", - "5. In this class we looked at a few graph generators in `networkx`. Explore the following: `barbell_graph`, `ladder_graph`, `lollipop_graph`, `star_graph` and `wheel_graph`.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
Finished here Wednesday
" - ] - } - ], - "metadata": { - "celltoolbar": "Slideshow", - "hide_code_all_hidden": false, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "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.13.1" - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": true, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": true, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": false - }, - "varInspector": { - "cols": { - "lenName": 16, - "lenType": 16, - "lenVar": 40 - }, - "kernels_config": { - "python": { - "delete_cmd_postfix": "", - "delete_cmd_prefix": "del ", - "library": "var_list.py", - "varRefreshCmd": "print(var_dic_list())" - }, - "r": { - "delete_cmd_postfix": ") ", - "delete_cmd_prefix": "rm(", - "library": "var_list.r", - "varRefreshCmd": "cat(var_dic_list()) " - } - }, - "types_to_exclude": [ - "module", - "function", - "builtin_function_or_method", - "instance", - "_Feature" - ], - "window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 4 -}