{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Python Review\n", "\n", "Before we review some Python basics, let us do a quick survey on what you expect from this course? What kinds of topics are you expecting in this course?\n", "https://docs.google.com/forms/d/e/1FAIpQLSebSoZZctyQQZ4asyhmIBt99aE0JcaPlXzLtIih78naC85TYQ/viewform?usp=sf_link\n", "\n", "## Python Basics\n", "\n", "### Objects and Types\n", "\n", "- All data treated as objects\n", " - An object is deleted (via garbage collection) once unreachable.\n", "- Strong typing\n", " - Every object has a fixed type, so that the interpreter does not allow things incompatible with that type (e.g., \"foo\" + 2)\n", " - type(object)\n", " - isinstance(object, type)\n", "- Dynamic typing\n", " - Variables come into existence when first assigned.\n", " - The type is automatically determined and updated after re-assignment.\n", " - Drawback: type errors are only caught at runtime. \n", "- Examples of Types\n", " - int, float\n", " - str, tuple, dict, list\n", " - bool: True/False\n", " - None, generator, function" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] } ], "source": [ "x = \"foo\"\n", "print(type(x))\n", "x = 2\n", "print(type(x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Math Basics\n", "\n", "- Literals:\n", " - Integers: 1, 2\n", " - Floats: 1.0, 2e10\n", " - Boolean: True/False\n", "- Operations:\n", " - Arithmetric: + - * /\n", " - Power: **\n", " - Modulus: %\n", " - Comparison: <=, >-, ==, !=\n", " - Logic: and, or, not\n", "- Assignment operators:\n", " - +=, *=, /=, &=,\n", " - ++, -- " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7\n", "12\n", "False\n", "True\n", "5\n", "2\n", "True\n" ] } ], "source": [ "x = 4\n", "y = 3\n", "\n", "print(x + y)\n", "print(x * y)\n", "print(x == y)\n", "print(not (x==y))\n", "\n", "x += 1\n", "print (x)\n", "print (x % y)\n", "\n", "y = y ** 2\n", "print((y >= x) or (y < x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Strings\n", "\n", "- Initialization\n", " - Use either single or double quotes\n", " - Triple quote for multiline string and docstring\n", "- Concatenating strings\n", " - By separating string literals with whitespace\n", " - Special use of '+'\n", "- Prefixing with r meaning raw.\n", " - No need to escape special characters.\n", "- String formatting\n", " - Special use of '%'\n", "- Immutable" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "artificial intelligence \n", "artificial intelligence is excellent\n", "concatenate1 takes 0.000141143798828125 s\n", "artificial intelligence is excellent\n", "concatenate2 takes 0.00011515617370605469 s\n", "INTELLIGENCE \n", "Intelligence \n", "11\n", "artificial_intelligence_\n", "hi\n", "artificial\tintelligence\n", "artificial\\tintelligence\n" ] } ], "source": [ "x = 'artificial '\n", "y = 'intelligence '\n", "\n", "# concatenation\n", "print(x + y)\n", "\n", "def concatenate1(strings):\n", " result = \"\"\n", " for s in strings:\n", " result += s\n", " return result\n", "\n", "def concatenate2(strings):\n", " return \"\".join(strings)\n", "\n", "import time\n", "start_time = time.time()\n", "print(concatenate1([x, y, 'is ', 'excellent']))\n", "print('concatenate1 takes %s s' % (time.time()-start_time))\n", "start_time = time.time()\n", "print(concatenate2([x, y, 'is ', 'excellent']))\n", "print('concatenate2 takes {0} s'.format(time.time()-start_time))\n", "\n", "# operations on strings\n", "print(y.upper())\n", "print(y.capitalize())\n", "print(len(x))\n", "strings = ((x + y).split(' '))\n", "print(\"_\".join(strings))\n", "print(' hi --'.strip(' -'))\n", "\n", "# raw strings\n", "x = 'artificial\\tintelligence'\n", "y = r'artificial\\tintelligence'\n", "print(x)\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Lists\n", "- Mutable ordered sequence of items of mixed types\n", "- Operations on lists\n", "- Slicing: return copy of a subsequence" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['reflex', 'model', 'goal', 'utility', 'learning']\n", "['reflex', 'goal', 'model', 'goal', 'utility', 'learning']\n", "2\n", "2\n", "6\n", "['reflex', 'model', 'goal', 'utility', 'learning']\n", "['learning', 'utility', 'goal', 'model', 'reflex']\n", "['goal', 'learning', 'model', 'reflex', 'utility']\n", "['goal', 'learning', 'model', 'reflex']\n", "reflex\n", "['goal', 'learning']\n", "[9, 36, 4, 49]\n", "[36, 49]\n" ] } ], "source": [ "agents = ['reflex', 'model', 'goal','utility']\n", "\n", "# operations\n", "agents.append('learning') # append\n", "print(agents)\n", "agents.insert(1, 'goal') # insert\n", "print(agents)\n", "print(agents.index('model')) # index of first occurrence\n", "print(agents.count('goal')) # number of occurrences\n", "print(len(agents)) # number of elements in the list\n", "agents.remove('goal') # remove the first occurrence\n", "print(agents)\n", "agents.reverse() # reverse the list\n", "print(agents)\n", "agents.sort() # sort the list\n", "print(agents)\n", "agents.pop() \n", "print(agents) # pop-up the last element\n", "\n", "# slicing\n", "print(agents[-1])\n", "print(agents[0:2])\n", "\n", "# list comprehensions instead of for-loops\n", "li = [3, 6, 2, 7]\n", "print([elem ** 2 for elem in li])\n", "print([elem ** 2 for elem in li if elem > 4])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tuples\n", "- A simple immutable ordered sequence of items\n", "- *Immutable*: a tuple cannot be modified once created\n", "- Items cannot be of mixed typs, including collection types" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0:reflex\n", "1:model\n", "2:goal\n", "3:utility\n", "[('reflex', 'rule'), ('model', 'representation and reasoning'), ('goal', 'problem-solving'), ('utility', 'problem-solving')]\n", "[('r', 'g'), ('u', 'o'), ('l', 'a'), ('e', 'l')]\n", "3\n", "3\n", "5\n" ] }, { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 16\u001b[0;31m \u001b[0mpair\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "source": [ "agents = ['reflex', 'model', 'goal','utility']\n", "\n", "for (index, agent) in enumerate(agents):\n", " print(str(index) + ':' + agent)\n", " \n", "module = ['rule', 'representation and reasoning', 'problem-solving', 'problem-solving']\n", "print(list(zip(agents, module)))\n", "\n", "print(list(zip('rule', 'goal')))\n", "\n", "pair = (3, 5)\n", "x, y = pair\n", "print(pair[0])\n", "print(x)\n", "print(y)\n", "pair[1] = 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sets\n", "- An unordered list with no duplicate items.\n", "- Common set operations:\n", " - Difference\n", " - Intersection\n", " - Union\n", "- **Note that since a set is unordered, the print order of a set could be different across different machines.**" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'goal', 'model', 'reflex'}\n", "{'goal', 'model', 'utility', 'reflex'}\n", "True\n", "False\n", "{'goal', 'utility'}\n", "{'reflex', 'model'}\n", "{'reflex', 'utility', 'intelligent', 'goal', 'learning', 'model'}\n", "{'x', 'y', 6}\n" ] } ], "source": [ "# creation\n", "agents = ['reflex', 'model', 'goal', 'goal']\n", "agents_set = set(agents)\n", "print(agents_set)\n", "\n", "# add an element to the set\n", "agents_set.add('utility')\n", "print(agents_set)\n", "\n", "# whether an element is in a set\n", "print('goal' in agents_set)\n", "print('learning' in agents_set)\n", "\n", "# set operations \n", "agents_set2 = set(['reflex', 'model', 'learning', 'intelligent'])\n", "print(agents_set - agents_set2)\n", "print(agents_set & agents_set2)\n", "print(agents_set | agents_set2)\n", "\n", "# set comprehensives instead of for-loops\n", "li = ['x', 'y', 'y', 6]\n", "d = {x for x in li}\n", "print(d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dictionaries\n", "- Stores a map from one type of object to another. \n", " - Key: must be an immutable type (string, number, or tuple).\n", " - Value: could be any Python data type.\n", "- Constant average time add, lookup, update" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "91.0\n", "{'Mark': 84.0, 'Jason': 69.0}\n", "70.0\n", "dict_keys(['Mark', 'Jason', 'John'])\n", "dict_values([84.0, 70.0, 88.0])\n", "dict_items([('Mark', 84.0), ('Jason', 70.0), ('John', 88.0)])\n", "3\n", "{'a': 1, 'b': 5, 'c': 'hi'}\n" ] } ], "source": [ "studentIds = {'Mark': 84.0, 'Jason': 69.0, 'Alice': 91.0}\n", "# access a key\n", "print(studentIds['Alice'])\n", "\n", "# delete a key\n", "del studentIds['Alice']\n", "print(studentIds)\n", "\n", "studentIds['John'] = 88.0\n", "\n", "# update a value\n", "studentIds['Jason'] = 70.0\n", "print(studentIds['Jason'])\n", "\n", "# Methods\n", "print(studentIds.keys()) # Keys\n", "print(studentIds.values()) # Values\n", "print(studentIds.items()) # Items\n", "print(len(studentIds))\n", "\n", "# Dictionary comprehensions instead of for-loops\n", "li = [('a', 1), ('b', 5), ('c', 'hi')]\n", "d = {k: v for k, v in li}\n", "print(d)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using generators for merging sequences\n", "- Problem: merge two sorted lists, using the output as a stream instead of storing it." ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "5\n", "6\n", "8\n", "9\n", "Mergine Done!\n", "[1, 5, 6, 8, 9]\n" ] } ], "source": [ "def merge(li1, li2):\n", " li1_len, li2_len, i, j = len(li1), len(li2), 0, 0\n", " while i < li1_len or j < li2_len:\n", " if j == li2_len or (i < li1_len and li1[i] < li2[j]):\n", " yield li1[i]\n", " i += 1\n", " else:\n", " yield li2[j]\n", " j += 1\n", " \n", "g = merge([5, 8], [1, 6, 9])\n", "while True:\n", " try:\n", " print(g.__next__())\n", " except StopIteration:\n", " print('Mergine Done!')\n", " break\n", "\n", "print([x for x in merge([1, 6, 9], [5, 8])])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python Package\n", "\n", "### Numpy\n", "- Install the package via `pip3 install numpy`\n", "- Import and use the package for matrix operations.\n", "- Please kindly refer to [this page](https://numpy.org/devdocs/user/quickstart.html) for a quick start.\n", "\n", "## Practice: Constructing A Graph Class\n", "![Image](https://uploadfiles.nowcoder.com/images/20161108/3814779_1478601521821_A4619219AAD6CEF924F940DFA6CDD697)" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 -> 2\n", "1 -> 4\n", "2 -> 5\n", "3 -> 1\n", "3 -> 6\n", "4 -> 2\n", "4 -> 6\n", "6 -> 5\n", "{1: [2, 4], 2: [5], 3: [1, 6], 4: [2, 6], 6: [5]}\n", "[1, 2, 5, 4, 6]\n", "[2, 5]\n", "[3, 1, 2, 5, 4, 6]\n", "[4, 2, 5, 6]\n", "[5]\n", "[6, 5]\n" ] } ], "source": [ "class DirGraph:\n", " def __init__(self, edges):\n", " self.adj = {}\n", " for u, v in edges:\n", " if u not in self.adj:\n", " self.adj[u] = [v]\n", " else:\n", " self.adj[u].append(v)\n", " def __str__(self):\n", " return '\\n'.join(['%s -> %s' % (u, v) for u in self.adj for v in self.adj[u]])\n", " \n", " # returns a generator for the nodes that can be reached from a given node by following arrows\n", " def search(self, u, visited):\n", " if u not in visited:\n", " yield u\n", " visited.add(u)\n", " \n", " if u in self.adj:\n", " for v in self.adj[u]:\n", " for w in self.search(v, visited):\n", " yield w\n", " \n", "d = DirGraph([(1,2), (1,4), (2,5), (3,1), (3,6), (4,2), (4,6), (6,5)])\n", "print(d)\n", "print(d.adj)\n", "print([v for v in d.search(1, set())])\n", "print([v for v in d.search(2, set())])\n", "print([v for v in d.search(3, set())])\n", "print([v for v in d.search(4, set())])\n", "print([v for v in d.search(5, set())])\n", "print([v for v in d.search(6, set())])" ] } ], "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.9.6" } }, "nbformat": 4, "nbformat_minor": 2 }