2024-09-30 04:53:43 +00:00
{
"cells": [
{
"cell_type": "markdown",
"id": "4444d9dd",
"metadata": {
"slideshow": {
"slide_type": "slide"
},
"tags": []
},
"source": [
"# Week 2: Python Basics (Part 2)\n",
"\n",
"\n",
"- Compound Data Types\n",
"- Mutability, Variables & References\n",
"- Functions\n",
"- Input/Output (I/O)"
]
},
{
"cell_type": "markdown",
"id": "a5918cff-1c93-41bd-811a-69d97c797f49",
"metadata": {
"tags": [],
"toc-hr-collapsed": true
},
"source": [
"## Iteration\n",
"\n",
2024-09-30 05:23:37 +00:00
"Last week we introduced `for` loops.\n",
2024-09-30 04:53:43 +00:00
"\n",
"```\n",
"for var_name in iterable:\n",
" statement # presumably using var_name\n",
"```\n",
"\n",
"What is an **iterable**? Why not just say **sequence**?\n",
"\n",
2024-09-30 05:23:37 +00:00
"What **sequences** have we seen?\n",
"\n",
2024-09-30 04:53:43 +00:00
"### More Iterables"
]
},
{
"cell_type": "markdown",
"id": "c0f1720d-937e-4030-b3a4-18c1382fb3ec",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### range\n",
"\n",
"Another iterable!\n",
"\n",
"`range(stop)` # goes from 0 to (stop-1)\n",
"\n",
"`range(start, stop)` # goes from start to (stop-1)\n",
"\n",
"Same rules as slice, always **inclusive** of start, **exclusive** of stop.\n",
"\n",
2024-09-30 05:23:37 +00:00
"or as you might write: ```[start, stop)``` -- we've seen this before with slicing"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "66d82d83-b8b8-4ad4-9f5a-b237d8bbe1d8",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"9\n",
"10\n",
"11\n"
]
}
],
"source": [
"for x in range(12):\n",
" print(x)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "4f6334e0-eeaa-45f7-a3c0-f975911f5ddb",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"8\n",
"9\n",
"10\n",
"11\n"
]
}
],
"source": [
"for x in range(8, 12):\n",
" print(x)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "8280f1b2-1935-496c-b372-3ccc3d1bc7f2",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'range'>\n"
]
}
],
"source": [
2024-09-30 05:42:17 +00:00
"z = range(12) # hmm\n",
2024-09-30 04:53:43 +00:00
"print(type(z))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "58dc9fc1-9056-4be4-9f91-8747aa7e7925",
"metadata": {
"tags": []
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
2024-09-30 05:23:37 +00:00
"execution_count": 1,
2024-09-30 04:53:43 +00:00
"id": "7ed88d5c-e848-46f8-8fc5-8d48fadc303e",
"metadata": {
"tags": []
},
2024-09-30 05:23:37 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 A\n",
"1 B\n",
"2 C\n"
]
}
],
2024-09-30 04:53:43 +00:00
"source": [
"i = 0\n",
"for x in [\"A\", \"B\", \"C\"]:\n",
" print(i, x)\n",
" i += 1"
]
},
{
"cell_type": "markdown",
"id": "c241b5fd-d0b6-4d72-a554-238931d28d36",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### `enumerate`\n",
"\n",
"Another function that returns an iterable, for when we need the index along with the object.\n",
"\n",
"`enumerate(original_iterable)` yields two element tuples: `(index, element)` for every item in the original."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "f8a79062-4012-4700-9611-83a4cdcd641c",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# find using range/len - as you might think to write it based on past experience\n",
"def find_r(s, letter_to_find):\n",
" for i in range(len(s)):\n",
" if s[i] == letter_to_find:\n",
" return i\n",
" return -1"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "844ce2af-b8f2-4dd3-b1fe-46ff050b2664",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n"
]
},
{
"data": {
"text/plain": [
"6"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"find_r(\"Hello World\", \"W\")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "21715b8f-4ce2-4c63-879b-69e06e9cef00",
"metadata": {
"scrolled": true,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"# find using enumerate - better\n",
"def find_e(s, letter_to_find):\n",
" for i, letter in enumerate(s): # tuple unpacking\n",
" print(i, letter)\n",
" if letter == letter_to_find:\n",
" return i\n",
" return -1"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "9b37d43a-bb10-420f-b86e-c70a8c56c55e",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 H\n",
"1 e\n",
"2 l\n",
"3 l\n",
"4 o\n",
"5 \n",
"6 w\n"
]
},
{
"data": {
"text/plain": [
"6"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"find_e(\"Hello world\", \"w\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "75e6a9da-e5a9-4f8a-93f2-ee0964a6efb4",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"find_r(\"Hello world\", \"?\")"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "04a6fdb6-f136-47a8-b6dc-c32c87a40542",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"6"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s = \"Hello world\"\n",
"s.find(\"w\") # built-ins are best"
]
},
{
"cell_type": "markdown",
"id": "527d4283-34bb-4a44-86c8-d1bee46be555",
"metadata": {},
"source": [
"Note: For HW#0 it is OK to use range for iteration, for future HWs if you are using the index & value, `enumerate` is the Pythonic way to do this."
]
},
{
"cell_type": "markdown",
"id": "13234aa7-ec30-44f1-8453-778db6ecd6ce",
"metadata": {
"tags": []
},
"source": [
"### aside: sequence unpacking\n",
"\n",
"When you know exactly how many elements are in a sequence, you can use this syntax to \"unpack\" them into variables:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "bedcf76f-d5f9-42d3-bc01-a845dd2e75b1",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 2 3\n"
]
}
],
"source": [
"tup = (1, 2, 3)\n",
"lst = [\"a\", \"b\", \"c\"]\n",
"\n",
2024-09-30 05:42:17 +00:00
"(x, y, z) = tup\n",
2024-09-30 04:53:43 +00:00
"print(x, y, z)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "dc82927d-c336-4eff-abde-4d9dc1507bc5",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = 7\n",
2024-09-30 05:42:17 +00:00
"y = 8"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f1e0714f-5d7b-426b-9748-a82b5c179251",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 20,
"id": "7646739a-8b0e-45cb-b63d-f1e54a9aa05b",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x, y = y, x"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "e1d328df-5016-4f82-9f8c-8c425f47146c",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"8 7\n"
]
}
],
"source": [
"print(x, y)"
]
},
{
"cell_type": "markdown",
"id": "2b894ba7",
"metadata": {
"slideshow": {
"slide_type": "slide"
},
"tags": [],
"toc-hr-collapsed": true
},
"source": [
"## `dict`\n",
"\n",
"A collection of key-value pairs. (aka map/hashmap in other languages)\n",
"\n",
"- Keys must be hashable. `tuple`, `str`, scalars -- why?\n",
"- Values are references, can be any type.\n",
"- Dynamically resizable\n",
"- Implemented using a hashtable, lookup is constant-time. **O(1)**\n",
"\n",
"- Iterable? Yes\n",
"- Mutable? Yes\n",
"- Sequence? No. (Why not?)"
]
},
{
"cell_type": "code",
"execution_count": 57,
"id": "b5123db7",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# declaration\n",
"record1 = {\n",
" \"name\": \"Anna\",\n",
" \"age\": 42,\n",
"}\n",
"\n",
"empty = {}\n",
"\n",
"# alternate form\n",
"record2 = dict(age=42, name=\"Anna\")\n",
2024-09-30 05:42:17 +00:00
"# list(\"a\", \"b\")\n",
2024-09-30 04:53:43 +00:00
"\n",
"# can also construct from sequence of tuples\n",
"\n",
"record3 = dict([(\"name\", \"Anna\"), (\"age\", 42)])\n",
"\n",
"# can compare for equality\n",
"record1 == record2"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9948e31b-aff8-4ce4-8a28-50d0d07dc18a",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"print(record1, record2)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "af8c64ca",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Anna\n"
]
}
],
"source": [
"# indexing by key\n",
"print(record1[\"name\"])"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "903268d7-73e0-4a63-9404-0c52936c6e9c",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
2024-09-30 05:42:17 +00:00
"record1[\"name\"] = \"Anne\""
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "7f1c685a",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'name': 'Anne', 'age': 42}\n",
"True\n",
"False\n"
]
}
],
"source": [
"# 'in' tests if a key exists (not a value!)\n",
"print(record1)\n",
"print(\"name\" in record1)\n",
"print(42 in record1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "41b1f5a1",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"# keys, values, items\n",
"print(record1.keys())\n",
2024-09-30 05:42:17 +00:00
"# print(record1.values())\n",
"# print((record1.items()))"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "300408f0-e9f2-4cdc-96ba-7db185154f16",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"name Anne\n",
"age 42\n"
]
}
],
"source": [
"for k, v in record1.items():\n",
" print(k, v)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0f6a9550-84b0-4f2d-8cb6-e48272be69a7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
2024-09-30 05:42:17 +00:00
"hash([1, 2, 3, 4])"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "37c96ad5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"hash('abc')=-2965309071663683053\n",
"hash(1234.3)=691752902764004562\n",
"hash((1,2,3))=529344067295497451\n"
]
},
{
"ename": "TypeError",
"evalue": "unhashable type: 'list'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[42], line 7\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mhash\u001b[39m(\u001b[38;5;241m1234.3\u001b[39m)\u001b[38;5;132;01m=}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mhash\u001b[39m((\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m2\u001b[39m,\u001b[38;5;241m3\u001b[39m))\u001b[38;5;132;01m=}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m----> 7\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28;43mhash\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;241;43m3\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;241;43m4\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;132;01m=}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
"\u001b[0;31mTypeError\u001b[0m: unhashable type: 'list'"
]
}
],
"source": [
"## hashable?\n",
"\n",
"print(f\"{hash('abc')=}\")\n",
"print(f\"{hash(1234.3)=}\")\n",
"print(f\"{hash((1,2,3))=}\")\n",
"\n",
"print(f\"{hash([1,2,3,4])=}\")"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "007eeb5c-550b-4ede-9c87-a411d75d1dcd",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"-2965309071663683053"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hash(\"abc\")"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "98e1b75f-f9a2-47f4-822a-57c2053295ad",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"-5007272861000900082"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hash(\"abd\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d9939e43",
"metadata": {},
"outputs": [],
"source": [
"d2 = {}\n",
2024-09-30 05:42:17 +00:00
"d2[[1, 2, 3]] = \"OK\""
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "90ea61ba",
"metadata": {},
"outputs": [],
"source": [
"hash(\"Python\")"
]
},
{
"cell_type": "markdown",
"id": "9b3ffe31",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Mutability\n",
"\n",
"Dictionaries are *mutable*, you can change, expand, and shrink them in place.\n",
"\n",
"This means we aren't copying/creating new dictionaries on every edit."
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "56ada375",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'spam': 5, 'eggs': 2, 'coffee': 1}\n"
]
}
],
"source": [
"order = {\"spam\": 1, \"eggs\": 2, \"coffee\": 1}\n",
"\n",
"order[\"spam\"] = 5\n",
"print(order)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "aa6d1aed",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'spam': 5, 'coffee': 1}\n"
]
}
],
"source": [
"del order[\"eggs\"]\n",
"print(order)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "8450549b",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'spam': 5, 'coffee': 1, 'bagel': 1}\n"
]
}
],
"source": [
"order[\"bagel\"] = 1\n",
"print(order)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "ae853627",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(6782175541370292817, 3424461145589330772)"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hash(\"bagel\"), hash(\"Bagel\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f5d1307f",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"## dictionaries are iterable\n",
"\n",
"for key in order:\n",
" print(key)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "96ece38d",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"# can use .items() or .values() to loop over non-keys\n",
"for key, value in order.items():\n",
" print(f\"{key=} {value=}\")\n",
2024-09-30 05:42:17 +00:00
"\n",
"\n",
2024-09-30 04:53:43 +00:00
"print(order.items())"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "182bd434",
"metadata": {},
"outputs": [],
"source": [
"# can use .items() or .values() to loop over non-keys\n",
"for a_tuple in order.items():\n",
" print(a_tuple[0], a_tuple[1])"
]
},
{
"cell_type": "markdown",
"id": "01a7d316",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### common dictionary methods\n",
"\n",
"| Operation | Meaning |\n",
"|-----------|---------|\n",
"| `d.keys()` | View of all keys. |\n",
"| `d.values()` | View of all values. |\n",
"| `d.items()` | View of key, value tuples. |\n",
"| `d.copy()` | Make a (shallow) copy. |\n",
"| `d.clear()` | Remove all items. |\n",
"| `d.get(key, default=None)` | Same as d[key] except if item isn't present, default will be returned. |\n",
"| `d.pop(key, default=None)` | Fetch item & remove it from dict. |\n",
"| `len(d)` | Number of stored entries. |\n",
"\n",
"See all at https://docs.python.org/3/library/stdtypes.html#dict"
]
},
{
"cell_type": "code",
"execution_count": 54,
"id": "d5801652-9284-4a55-8f94-53f4a1cce0cf",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'spam': 5, 'coffee': 1, 'bagel': 1}\n",
"None fish\n"
]
}
],
"source": [
"d = order\n",
"print(order)\n",
"key = \"fish\"\n",
"\n",
2024-09-30 05:42:17 +00:00
"# print(d.get(key), key)"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": 58,
"id": "ca4b8660-8307-4f52-a9e9-154d51c7ab94",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"42\n"
]
}
],
"source": [
"age = record1.pop(\"age\")\n",
"print(age)"
]
},
{
"cell_type": "code",
"execution_count": 59,
"id": "462515ae-a3e3-4886-bfab-d95b6c847b84",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(record1)"
]
},
{
"cell_type": "code",
"execution_count": 60,
"id": "567de037-1184-4814-9be1-15a7b66db504",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"{'name': 'Anna'}"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"record1"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bef0fcac",
"metadata": {},
"outputs": [],
"source": [
"order\n",
"\n",
"number_ordered = order.pop(\"spam\", 0)\n",
"print(number_ordered)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bd5364b0",
"metadata": {},
"outputs": [],
"source": [
"print(order)"
]
},
{
"cell_type": "markdown",
"id": "6cf39963",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Dictionary View Objects\n",
"\n",
"As noted above, `keys(), values() and items()` return \"view objects.\"\n",
"\n",
"The returned object is a dynamic view, so when the dictionary changes, the view changes."
]
},
{
"cell_type": "code",
"execution_count": 61,
"id": "0f1881a1",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"dict_keys(['eggs', 'sausage', 'bacon', 'spam'])\n",
"dict_values([2, 1, 1, 500])\n",
"dict_items([('eggs', 2), ('sausage', 1), ('bacon', 1), ('spam', 500)])\n"
]
}
],
"source": [
2024-09-30 05:42:17 +00:00
"dishes = {\"eggs\": 2, \"sausage\": 1, \"bacon\": 1, \"spam\": 500}\n",
2024-09-30 04:53:43 +00:00
"\n",
"# Keys is a view object of the keys from the dishes dictionary\n",
"keys = dishes.keys()\n",
"values = dishes.values()\n",
2024-09-30 05:42:17 +00:00
"items = dishes.items()\n",
2024-09-30 04:53:43 +00:00
"\n",
"print(keys)\n",
"print(values)\n",
"print(items)"
]
},
{
"cell_type": "code",
"execution_count": 62,
"id": "674cc686",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"dict_keys(['sausage', 'bacon', 'spam'])\n",
"dict_values([1, 1, 500])\n",
"dict_items([('sausage', 1), ('bacon', 1), ('spam', 500)])\n"
]
}
],
"source": [
2024-09-30 05:42:17 +00:00
"# View objects are dynamic and reflect dictionary changes\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:42:17 +00:00
"# Lets delete the 'eggs' entry\n",
"del dishes[\"eggs\"]\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:42:17 +00:00
"# Notice the both the views have removed key and its value\n",
2024-09-30 04:53:43 +00:00
"print(keys)\n",
"print(values)\n",
"print(items)"
]
},
{
"cell_type": "code",
"execution_count": 64,
"id": "b6658174",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'BLT': 3.99, 'Chicken': 5.99, 'Salad': 4.5}\n",
"4.5\n"
]
}
],
"source": [
"# Nested Dictionaries Example\n",
"\n",
"menu = {\n",
" \"Breakfast\": {\"Eggs\": 2.19, \"Toast\": 0.99, \"Orange Juice\": 1.99},\n",
" \"Lunch\": {\"BLT\": 3.99, \"Chicken\": 5.99, \"Salad\": 4.50},\n",
2024-09-30 05:42:17 +00:00
" \"Dinner\": {\"Cheeseburger\": 9.99, \"Salad\": 7.50, \"Special\": 8.49},\n",
2024-09-30 04:53:43 +00:00
"}\n",
"\n",
"print(menu[\"Lunch\"])\n",
"\n",
"print(menu[\"Lunch\"][\"Salad\"])"
]
},
{
"cell_type": "markdown",
"id": "da42d6b5",
"metadata": {},
"source": [
"### Caveats\n",
"\n",
"- Downsides of mutables?\n",
"- Modifying a `dict` while iterating through it."
]
},
{
"cell_type": "code",
"execution_count": 68,
"id": "ecb495c8-ac3a-4b70-9e74-1bfed1d4b466",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'A': 100}\n"
]
}
],
"source": [
"def something(d):\n",
" to_remove = []\n",
2024-09-30 05:42:17 +00:00
"\n",
" # d_copy = d.copy()\n",
2024-09-30 04:53:43 +00:00
" for k, v in d.items():\n",
" if v < 50:\n",
2024-09-30 05:42:17 +00:00
" # d.pop(k)\n",
2024-09-30 04:53:43 +00:00
" to_remove.append(k)\n",
2024-09-30 05:42:17 +00:00
"\n",
2024-09-30 04:53:43 +00:00
" for item in to_remove:\n",
" d.pop(item)\n",
2024-09-30 05:42:17 +00:00
" # ...\n",
"\n",
"\n",
2024-09-30 04:53:43 +00:00
"scores = {\"A\": 100, \"B\": 20, \"C\": 48}\n",
"something(scores)\n",
"print(scores)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c988c56",
"metadata": {},
"outputs": [],
"source": [
"# iteration example\n",
"d = {\"A\": 1, \"B\": 2, \"C\": 3}\n",
"to_remove = []\n",
"for key, value in d.items():\n",
" if value == 2:\n",
" to_remove.append(key)\n",
"for key in to_remove:\n",
" d.pop(key)\n",
2024-09-30 05:42:17 +00:00
"\n",
2024-09-30 04:53:43 +00:00
"print(d)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "410613ac",
"metadata": {},
"outputs": [],
"source": [
"students = {\n",
" \"Anne\": 98,\n",
" \"Mitch\": 13,\n",
" \"Zach\": 65,\n",
"}\n",
"\n",
"below_60 = []\n",
"\n",
"for student in students:\n",
" grade = students[student]\n",
" if grade < 60:\n",
" below_60.append(student)\n",
"\n",
"below_60\n",
"for name in below_60:\n",
" students.pop(name)\n",
2024-09-30 05:42:17 +00:00
"\n",
2024-09-30 04:53:43 +00:00
"print(students)"
]
},
{
"cell_type": "markdown",
"id": "976e988f",
"metadata": {
"slideshow": {
"slide_type": "slide"
},
"toc-hr-collapsed": true
},
"source": [
"## `set`\n",
"\n",
"Sets contain an unordered collection of *unique* & *immutable* values.\n",
"\n",
" - Unique: no duplicates\n",
"\n",
" - Immutable: values cannot be `dict`, `set`, `list`.\n",
"\n",
"\n",
"Sets themselves are *mutable*."
]
},
{
"cell_type": "code",
"execution_count": 69,
"id": "3a3db482",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'panda', 'ostrich', 'llama'}\n",
"{'ostrich', 'panda', 'llama'}\n"
]
}
],
"source": [
"# defining a set\n",
"animals = {\"llama\", \"panda\", \"ostrich\"}\n",
"print(animals)\n",
"\n",
"# or can be made from an iterable\n",
"animals = set([\"llama\", \"panda\", \"ostrich\"])\n",
"print(animals)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b240ba8b-2e54-464c-8003-bca5b66c532e",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "2bb720e8-5830-4fd3-a7a5-cf50af5a0868",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"s = set()"
]
},
{
"cell_type": "code",
"execution_count": 70,
"id": "4628529f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'ostrich', 'panda', 'llama'}\n"
]
}
],
"source": [
"# no duplicates\n",
"animals = set([\"llama\", \"panda\", \"ostrich\", \"ostrich\", \"panda\"])\n",
"print(animals)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"id": "bbe43b2e-d95d-4e16-be98-ac03f227003d",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"lst = [1, 23, 4920, 2091, 4920, 4920, 4920, 23]"
]
},
{
"cell_type": "code",
"execution_count": 73,
"id": "1fd3e328-c0f5-4fd0-8407-b1cd33010f90",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[4920, 1, 2091, 23]\n"
]
}
],
"source": [
"deduped = list(set(lst))\n",
"print(deduped)"
]
},
{
"cell_type": "markdown",
"id": "56cb6bab",
"metadata": {},
"source": [
"\n",
"### Set Theory Operations\n",
"\n",
"Sets are fundamentally mathematical in nature and contain operations based on set theory. They allow the following operations:\n",
"\n",
" - Union (`union()` or `|`}: A set containing all elements that are in both sets\n",
"\n",
" - Difference (`difference()` or `-`): A set that consists of elements that are in one set but not the other.\n",
"\n",
" - Intersection (`intersection` or `&`): A set that consists of all elements that are in both sets.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9ef87b91",
"metadata": {},
"outputs": [],
"source": [
2024-09-30 05:42:17 +00:00
"# The following creates a set of single strings 'a','b','c','d','e'\n",
2024-09-30 04:53:43 +00:00
"# and another set of single strings 'b','d','x','y','z'\n",
2024-09-30 05:42:17 +00:00
"A = set(\"abcde\")\n",
2024-09-30 04:53:43 +00:00
"B = set([\"b\", \"d\", \"x\", \"y\", \"z\"])\n",
"\n",
"print(\"A = \", A)\n",
"print()\n",
"print(\"B = \", B)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cd7cd6d7",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
2024-09-30 05:42:17 +00:00
"# Union Operation\n",
"new_set = A | B\n",
2024-09-30 04:53:43 +00:00
"print(new_set)\n",
2024-09-30 05:42:17 +00:00
"print(\"---\")\n",
"new_set = A.union(B) # Same operation as above but using method\n",
2024-09-30 04:53:43 +00:00
"print(new_set)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb6bd2f9",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
2024-09-30 05:42:17 +00:00
"# Difference Operation\n",
"new_set = A - B\n",
2024-09-30 04:53:43 +00:00
"print(new_set)\n",
"print(\"---\")\n",
"new_set = B.difference(A) # note that order matters for difference\n",
"print(new_set)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4e516175",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
2024-09-30 05:42:17 +00:00
"# Intersection Operation\n",
"new_set = A & B\n",
2024-09-30 04:53:43 +00:00
"print(new_set)\n",
2024-09-30 05:42:17 +00:00
"print(\"---\")\n",
"new_set = A.intersection(B) # same operation as above but using method\n",
2024-09-30 04:53:43 +00:00
"print(new_set)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6d6fcff7",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
2024-09-30 05:42:17 +00:00
"# Symmetric Difference Operation\n",
"new_set = A ^ B\n",
2024-09-30 04:53:43 +00:00
"print(new_set)\n",
2024-09-30 05:42:17 +00:00
"print(\"---\")\n",
"new_set = A.symmetric_difference(B) # same operation as above but using method\n",
2024-09-30 04:53:43 +00:00
"print(new_set)"
]
},
{
"cell_type": "markdown",
"id": "2558302f",
"metadata": {},
"source": [
"### Other Set Methods\n",
"\n",
"| Method | Purpose | \n",
"|--------|---------|\n",
"| `s.add(item)` | Adds an item to set. |\n",
"| `s.update(iterable)` | Adds all items from iterable to the set. |\n",
"| `s.remove(item)` | Remove an item from set. |\n",
"| `s.discard(item)` | Remove an item from set if it is present, fail silently if not. |\n",
"| `s.pop()` | Remove an arbitrary item from the set. |\n",
"| `s.clear()` | Remove all items from the set. |"
]
},
{
"cell_type": "code",
"execution_count": 74,
"id": "e7be6cfb-5778-4106-a454-ab13cbd96e30",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"s = {1, 2, 3}\n",
"s.discard(2)"
]
},
{
"cell_type": "code",
"execution_count": 78,
"id": "322c8f1a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Removed Ace\n",
"{'7', 'K', '6', 'J', '4', '3', 'Q', '9', '5', '8', '2'}\n"
]
}
],
"source": [
"s = set() # why not {}?\n",
"\n",
"s.update([\"A\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"J\", \"Q\", \"K\"])\n",
"\n",
"s.remove(\"A\")\n",
"print(\"Removed Ace\")\n",
"print(s)"
]
},
{
"cell_type": "code",
"execution_count": 81,
"id": "41a8ea98-1ffe-43b9-9548-fa43197cad94",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"'7'"
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s.pop()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2555b568",
"metadata": {},
"outputs": [],
"source": [
"s.discard(\"9\")\n",
2024-09-30 05:42:17 +00:00
"# print(\"Discarded Ace\")\n",
2024-09-30 04:53:43 +00:00
"print(s)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ccc84afc",
"metadata": {},
"outputs": [],
"source": [
"card = s.pop()\n",
"print(\"Popped\", card)\n",
"print(s)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eb3ed63b",
"metadata": {},
"outputs": [],
"source": [
"print(\"---\")\n",
"s.add(\"Joker\")\n",
"print(s)\n",
"\n",
"\n",
2024-09-30 05:42:17 +00:00
"\"Honda Civic\" in [\n",
" \"Honda Civic\",\n",
" \"Ford Focus\",\n",
" \"Honda Civic\",\n",
" \"Honda Civic\",\n",
" \"Honda Civic\",\n",
" \"Honda Civic\",\n",
" \"Honda Civic\",\n",
" \"Escalade\",\n",
"]"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": 76,
"id": "c1ec32b4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"All 3 ordered: {'eggs'}\n",
"Only ordered by #1: {'pancakes', 'juice'}\n"
]
}
],
"source": [
"d1 = {\"eggs\": 2, \"pancakes\": 100, \"juice\": 1}\n",
"d2 = {\"eggs\": 3, \"waffles\": 1, \"coffee\": 1}\n",
"d3 = {\"eggs\": 1, \"fruit salad\": 1}\n",
"\n",
"print(\"All 3 ordered:\", set(d1) & set(d2) & set(d3))\n",
"print(\"Only ordered by #1:\", set(d1) - set(d2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "434fc861",
"metadata": {},
"outputs": [],
"source": [
"set(d1.items())"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "32718b95",
"metadata": {},
"outputs": [],
"source": [
"s = {\"one\", \"two\", \"three\", \"four\"}\n",
"for x in s:\n",
" print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c86b847d",
"metadata": {},
"outputs": [],
"source": [
"students = [\n",
" {\"name\": \"adam\", \"num\": 123},\n",
" {\"name\": \"quynh\", \"num\": 456},\n",
" {\"name\": \"quynh\", \"num\": 456},\n",
"]\n",
"\n",
"s = set()\n",
"for student in students:\n",
" s.add(tuple(student.items()))\n",
"s"
]
},
{
"cell_type": "code",
"execution_count": 77,
"id": "236f3706",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{1, 3}"
]
},
"execution_count": 77,
"metadata": {},
"output_type": "execute_result"
}
],
"source": []
},
{
"cell_type": "markdown",
"id": "5ddacfcf",
"metadata": {
"slideshow": {
"slide_type": "slide"
},
"toc-hr-collapsed": true
},
"source": [
"## Discussion\n",
"\n",
"#### Are sets sequences?\n",
"\n",
"#### Why do set members need to be immutable?\n",
"\n",
"#### How can we store compound values in sets?\n",
"\n",
"#### Why do dictionary keys have the same restrictions?"
]
},
{
"cell_type": "code",
"execution_count": 82,
"id": "042df160",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"frozenset({1, 2, 3})\n",
"{frozenset({1, 2, 3}), frozenset({'C', 'A', 'B'})}\n"
]
}
],
"source": [
"# frozenset demo\n",
"nums = [1, 2, 3]\n",
"frozen_nums = frozenset(nums)\n",
"print(frozen_nums)\n",
"\n",
"nested = {frozen_nums, frozenset(\"ABC\")}\n",
"\n",
"print(nested)\n",
"\n",
2024-09-30 05:42:17 +00:00
"# frozen_nums.add(4)"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": 84,
"id": "690909f7-5bd4-4040-94ee-fad99d4e6c85",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"{'e', 'h', 'l', 'o'}"
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"set([\"h\", \"e\", \"l\", \"l\", \"o\"])"
]
},
{
"cell_type": "code",
"execution_count": 86,
"id": "72ed3c15-7a07-40a1-b5bd-af08213283a9",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'u', 'a', 'i', 'o', 'e'}\n"
]
}
],
"source": [
"vowels = set(\"aeiou\")\n",
"print(vowels)"
]
},
{
"cell_type": "markdown",
"id": "3037023e",
"metadata": {
"slideshow": {
"slide_type": "slide"
},
"toc-hr-collapsed": true
},
"source": [
"## Mutability\n",
"\n",
"Mutable values can be changed in place.\n",
"\n",
"We've seen that `list` was mutable, and `dict` and `set` as well now.\n",
"\n",
"#### Mutable\n",
" - `list`\n",
" - `dict`\n",
" - `set`\n",
" \n",
"#### Immutable\n",
" - `str`\n",
" - `tuple`\n",
" - `frozenset`\n",
" - scalars: `int`, `float`, `complex`, `bool`, `None`"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "38a9d1bf",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4]\n"
]
}
],
"source": [
"# list\n",
"d = [1, 2, 3]\n",
"d.append(4)\n",
"print(d)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "62198c82",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Hello World'"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# str\n",
"s = \"Hello\"\n",
"s = s + \" World\"\n",
2024-09-30 05:42:17 +00:00
"s\n",
2024-09-30 04:53:43 +00:00
"\n",
"# how did s change?"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "b52f9779-83e9-4781-a785-3c8fff6341cf",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello World\n",
"hello world\n"
]
}
],
"source": [
"s = \"Hello World\"\n",
"t = s.lower()\n",
"print(s)\n",
"print(t)"
]
},
{
"cell_type": "markdown",
"id": "be45e1b1",
"metadata": {
"slideshow": {
"slide_type": "slide"
},
"toc-hr-collapsed": true
},
"source": [
"## Python Objects & References\n",
"\n",
"Everything in Python is an `object`. An object is a piece of memory with values & associated operations.\n",
"\n",
"We've seen plenty of methods on `str`, `list`, `dict`, etc. \n",
"\n",
"`a_string.lower()`, `dict.pop(val)`, etc.\n",
"\n",
"As we'll see in time, every type in Python works this way. \n",
"\n",
"Operators like `+`, `-`, `and` and `or` are \"associated operations\" when we're using scalars like `int` or `bool`."
]
},
{
"attachments": {
"shared_ref1.png": {
"image/png": "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
}
},
"cell_type": "markdown",
"id": "44c7e909",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Variables in python are referred to as *names* or *identifiers*.\n",
"\n",
"![shared_ref1.png](attachment:shared_ref1.png)\n",
"\n",
" -- Learning Python 2013\n",
" \n",
"A name does not uniquely identify an object!"
]
},
{
"attachments": {
"shared_ref2.png": {
"image/png": "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
}
},
"cell_type": "markdown",
"id": "04c18489",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"#### objects are typed, not variables\n",
"\n",
"![shared_ref2.png](attachment:shared_ref2.png)\n",
" -- Learning Python 2013"
]
},
{
"cell_type": "markdown",
"id": "7ca5ee49",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Shared references\n",
"\n",
"Setting a variable to a new value does not alter the original.\n",
"\n",
"It causes the variable to reference a brand new object."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "faa23947",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"20 10\n"
]
}
],
"source": [
"x = 10\n",
"y = x\n",
"x = 20\n",
"print(x, y)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "ef7e492b",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4]\n",
"[1, 2, 3, 4]\n"
]
}
],
"source": [
"# what does this mean for mutable objects?\n",
"x = [1, 2, 3]\n",
"y = x\n",
"y.append(4)\n",
"print(x)\n",
"print(y)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b43f3aa7",
"metadata": {},
"outputs": [],
"source": [
"a = 3\n",
"b = a\n",
"a *= 2\n",
"print(a, b)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "2e7648d4-a1f8-466f-9ba5-d9675c1797e0",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"4425741616"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = 3113\n",
"id(a)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "bb3c3c8e-5f9d-43d2-95c4-1d942dacd84c",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"4425741552"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b = 39209328\n",
"id(b)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "232513ac-e7ef-4bb0-b6bd-2e79ccb372c2",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"4347370440"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id(1)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "5de9cff6-ee68-4d3d-8d98-1934c5ae8e89",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"4347370440"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id(1)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "1c857ad7-cd72-45d8-b198-f4e4d243bba5",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"4425741552"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c = b\n",
"id(c)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "b7796200-062c-4200-b364-d5cdd50f1909",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"4421355824"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id(\"hello\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "e20f9375-d204-43fa-b0ee-11c9e11c3467",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"4421355824"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id(\"hello\")"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "882c3574-cb0e-4f64-8292-4cccf3b5afec",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = []"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "9f3d57bc-70c5-4f0b-9c9b-983a02d30f8a",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"y = []"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "14266b2d-8daa-4ea9-9852-14299bdace53",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"4426830976"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id(x)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "14efc6ea-6cf4-4688-9d89-0b670f94dbed",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"4426547712"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id(y)"
]
},
{
"cell_type": "markdown",
"id": "de047635",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### Identity\n",
"\n",
"The built-in `id(...)` function returns the identity of an object, which is an integer value guaranteed to be unique and constant for lifetime of object\n",
"\n",
"In the CPython Interpeter (the one we are using in this class), it is the address of the memory location storing the object."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "091ab50e",
"metadata": {},
"outputs": [],
"source": [
"x = \"MPCS\"\n",
2024-09-30 05:42:17 +00:00
"print(id(x)) # Unique integer-value for the object pointed by x"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "b91a5fc1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Fruit1 id = 4426067328 \n",
" Fruit2 id = 4426732544\n",
"Fruit3 id= 4426732544\n"
]
}
],
"source": [
2024-09-30 05:42:17 +00:00
"fruit1 = (\"Apples\", 4)\n",
"fruit2 = (\"Apples\", 4)\n",
2024-09-30 04:53:43 +00:00
"fruit3 = fruit2\n",
2024-09-30 05:42:17 +00:00
"print(f\"Fruit1 id = {id(fruit1)} \\n Fruit2 id = {id(fruit2)}\")\n",
2024-09-30 04:53:43 +00:00
"print(f\"Fruit3 id= {id(fruit3)}\")"
]
},
{
"cell_type": "markdown",
"id": "27515ae0",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"#### Equality vs. Identity\n",
"\n",
"Two different ways of testing if objects are the \"same\":\n",
"\n",
"- Equality operator (`==`): Returns true if two objects are equal (i.e., have the same value)\n",
"- Identity operator (`is`): Returns true if two objects identities are the same.\n",
"\n",
"`a is b` means `id(a) == id(b)`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f3dbb745",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"a = [1, 2, 3]\n",
"b = [1, 2, 3]\n",
"print(\"a == b\", a == b)\n",
"\n",
"print(id(a))\n",
"print(id(b))\n",
2024-09-30 05:42:17 +00:00
"print(\"a is b\", a is b) # The id values are different"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "markdown",
"id": "5d188a92",
"metadata": {},
"source": [
"#### `is None`\n",
"\n",
"If you ever need to check if a value is `None`, you'd use `is None` or `is not None`"
]
},
{
"cell_type": "markdown",
"id": "58212b98",
"metadata": {},
"source": [
"### list / string example revisited"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "df31e67b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"4426806720\n",
"[1, 2, 3, 4]\n",
"4426806720\n"
]
}
],
"source": [
"# list d\n",
"d = [1, 2, 3]\n",
"print(id(d))\n",
"d.append(4)\n",
"print(d)\n",
"print(id(d))"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "db8c92ac",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"4426858352\n",
"Hello World\n",
"4426857072\n"
]
}
],
"source": [
"# str D\n",
"s = \"Hello\"\n",
"print(id(s))\n",
"s += \" World\"\n",
"print(s)\n",
"\n",
"# did s change?\n",
"print(id(s))"
]
},
{
"cell_type": "markdown",
"id": "8422f5aa",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Object Creation\n",
"\n",
" Each time you generate a new value in your script by running an expression, Python creates a new object (i.e., a chunk of memory) to represent that value.\n",
" \n",
"-- Learning Python 2013\n",
"\n",
"Not quite! CPython does not guarantee this, and in fact sometimes caches & reuses immutable objects for efficiency.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cbe3c8c6",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"a = 1000\n",
"b = 1000\n",
"\n",
"# Two different objects, two different ids.\n",
2024-09-30 05:42:17 +00:00
"print(a is b)\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:42:17 +00:00
"# a = 100\n",
"# b = 100\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:42:17 +00:00
"# However, for small integer objects, CPython caches them\n",
"# this means that a and b point to the same object\n",
"# print(a is b)\n",
2024-09-30 04:53:43 +00:00
"\n",
"for i in range(200, 300):\n",
" print(i, i is i)"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "21e26569",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"4424259520 4424259520\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2024-09-30 05:42:17 +00:00
"# CPython does the same for short strings\n",
"str1 = \"MPCS\" * 100\n",
"str2 = \"MPCS\" * 100\n",
2024-09-30 04:53:43 +00:00
"print(id(str1), id(str2))\n",
2024-09-30 05:42:17 +00:00
"str1 is str2"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "markdown",
"id": "de2eec4a",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Copying\n",
"\n",
"If `y = x` does not make a copy, how can we get one?\n",
"\n",
"We've seen the `.copy()` method on a few of our types. Which ones?\n",
"\n",
"We can also use the `copy` module:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2aae8fb4",
"metadata": {},
"outputs": [],
"source": [
"x = [1, 2, 3]\n",
"y = x.copy()\n",
"\n",
"print(id(x))\n",
"print(id(y))\n",
"\n",
"x.append(4)\n",
"print(x, y)"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "9d344044",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x is y False\n",
"x[0] is y[0] True\n",
"[[1, 2, 5], [3, 4]] \n",
" [[1, 2, 5], [3, 4]]\n"
]
}
],
"source": [
2024-09-30 05:42:17 +00:00
"# shallow copy example\n",
2024-09-30 04:53:43 +00:00
"\n",
"x = [[1, 2], [3, 4]]\n",
"y = x.copy() # or copy.copy(x)\n",
"\n",
"print(\"x is y\", x is y)\n",
2024-09-30 05:42:17 +00:00
"print(\"x[0] is y[0]\", x[0] is y[0])\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:42:17 +00:00
"# print(x, y)\n",
2024-09-30 04:53:43 +00:00
"x[0].append(5)\n",
2024-09-30 05:42:17 +00:00
"print(x, \"\\n\", y)"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "eb936a3f",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x[0] is z[0] False\n"
]
}
],
"source": [
"# deep copy\n",
"import copy\n",
2024-09-30 05:42:17 +00:00
"\n",
2024-09-30 04:53:43 +00:00
"# copy.copy(obj) --> same as obj.copy()\n",
"z = copy.deepcopy(x)\n",
"print(\"x[0] is z[0]\", x[0] is z[0])"
]
},
{
"cell_type": "markdown",
"id": "bdcde4d9",
"metadata": {},
"source": [
"### Garbage Collection\n",
"\n",
"Python is a garbage collected language. \n",
"\n",
"We don't free our own memory, Python does instead.\n",
"\n",
"Behind the scenes, Python stores a reference counter on each `object`. How many names/objects reference the object.\n",
"\n",
"When reference count drops to zero, Python can reclaim the memory."
]
},
{
"cell_type": "markdown",
"id": "7a425057-a65d-4d41-b1b4-1c73dfbeb325",
"metadata": {
"slideshow": {
"slide_type": "slide"
},
"toc-hr-collapsed": true
},
"source": [
2024-09-30 05:23:37 +00:00
"## Functions Revisited\n",
2024-09-30 04:53:43 +00:00
"\n",
"A function is a set of statements that can be called more than once.\n",
"\n",
"Benefits of functions:\n",
"\n",
"- Encapsulation: package logic for use in multiple places\n",
"- Allows programmer to avoid copy/paste to repeat same task, which helps maximize code reuse and minimize redundancy\n",
"- Procedural decomposition: split our program into subtasks (i.e., functions) with separate roles.\n",
"- Make life easier for debugging, testing, doing maintenance on code\n"
]
},
{
"cell_type": "markdown",
"id": "9242d177-dc2e-40d7-b1ad-dbcdf666b393",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"```python\n",
"def function_name(arg1, arg2, arg3):\n",
" \"\"\"\n",
" Description of function task \n",
"\n",
" Inputs: \n",
" arg1(type): description of arg1 \n",
" arg2: description of arg2\n",
" arg3: description of arg2\n",
"\n",
" Outputs:\n",
" Description of what this function returns \n",
" \"\"\"\n",
" statement1\n",
" statement2\n",
" statement3\n",
" return value # optional\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "ff1387d0-8a16-4e8a-a838-6ae2f42479c5",
"metadata": {},
"source": [
"In some languages, you can pass arguments by value or by reference.\n",
"In Python all values are \"passed by assignment\".\n",
"\n",
"```python\n",
"def func(a, b):\n",
" ...\n",
" \n",
"x = 7\n",
"y = [1, 2, 3]\n",
"func(x, y)\n",
"\n",
"# you can think of the function starting with assignments to its parameters\n",
"a = x\n",
"b = y\n",
"```\n",
"\n",
"This means mutability determines whether or not a function can modify a parameter in the outer scope."
]
},
{
"cell_type": "markdown",
"id": "4729a9a2-66af-4d9c-af2e-441c8486a92c",
"metadata": {
"tags": [],
"toc-hr-collapsed": true
},
"source": [
2024-09-30 05:23:37 +00:00
"## I/O"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "markdown",
"id": "59141a54-daf9-4a55-ad87-b80d34260378",
"metadata": {},
"source": [
2024-09-30 05:23:37 +00:00
"### `print()`\n",
2024-09-30 04:53:43 +00:00
"\n",
"`print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False)`\n",
"\n",
"https://docs.python.org/3/library/functions.html#print"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1a2ef2c4",
"metadata": {},
"outputs": [],
"source": [
"print(\"Can\", \"pass\", \"multiple\", {\"objects\": True})\n",
"print(\"Hello\", \"World\", sep=\"~~~~\", end=\"!\")\n",
"print(\"Same line\")"
]
},
{
"cell_type": "markdown",
"id": "a9042da6-838a-4a78-8ac7-c50e318d70db",
"metadata": {},
"source": [
"### `input()`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "89853f8e",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"name = input(\"What is your name: \")\n",
"print(f\"Hello {name}\")\n",
"\n",
"# always a string\n",
"year = input(\"What year is it: \")\n",
"print(year, type(year))"
]
},
{
"cell_type": "markdown",
2024-09-30 05:23:37 +00:00
"id": "d07f8320-b048-477b-8b59-f171b5dbecd3",
2024-09-30 04:53:43 +00:00
"metadata": {},
"source": [
2024-09-30 05:23:37 +00:00
"### pathlib\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"There are a few ways of working with files in Python, mostly due to improvements over time.\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"You'll still sometimes see code that uses the older method with `open`, but there's almost no reason to write code in that style now that `pathlib` is widely available.\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"To use `pathlib`, you'll need to import the `Path` object. (We'll discuss these imports more soon.)"
2024-09-30 04:53:43 +00:00
]
},
{
2024-09-30 05:23:37 +00:00
"cell_type": "code",
"execution_count": 2,
"id": "118ba56e-91c3-4ad9-935e-2a44d1fd064c",
2024-09-30 04:53:43 +00:00
"metadata": {},
2024-09-30 05:23:37 +00:00
"outputs": [],
2024-09-30 04:53:43 +00:00
"source": [
2024-09-30 05:23:37 +00:00
"from pathlib import Path"
2024-09-30 04:53:43 +00:00
]
},
{
2024-09-30 05:23:37 +00:00
"cell_type": "markdown",
"id": "9c24256b-e9df-44da-884c-db0670bda68b",
2024-09-30 04:53:43 +00:00
"metadata": {},
"source": [
2024-09-30 05:23:37 +00:00
"Imports like this should be at the top of the file.\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"To use this type you'll create objects with file paths, for example:"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
2024-09-30 05:23:37 +00:00
"execution_count": 5,
"id": "c07cd9ee-48bc-4ae1-b813-20380bb2733d",
2024-09-30 04:53:43 +00:00
"metadata": {},
"outputs": [],
"source": [
2024-09-30 05:23:37 +00:00
"# this looks like a function call\n",
"# but the capital letter denotes that this is instead a class\n",
"file_path = Path(\"data/names.txt\")"
2024-09-30 04:53:43 +00:00
]
},
{
2024-09-30 05:23:37 +00:00
"cell_type": "markdown",
"id": "cfec4041-a186-40ed-9967-e096d4f11ffb",
2024-09-30 04:53:43 +00:00
"metadata": {},
"source": [
2024-09-30 05:23:37 +00:00
"#### Typical workflow:\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"- Read contents of file(s) from disk into working memory.\n",
"- Parse and/or manipulate data as needed.\n",
"- (Optional) Write data back to disk with modifications.\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"#### Other Workflows\n",
"\n",
"- Append-only (e.g. logging)\n",
"- Streaming data (needed for large files where we can't fit into memory)\n",
"\n",
"#### Text vs. Binary\n",
"\n",
"We're opening our files in the default, text mode. It is also possible to open files in a binary mode where it isn't assumed we're reading strings."
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "markdown",
2024-09-30 05:23:37 +00:00
"id": "9e844faa-6287-4377-ac2b-55a8de1e1c89",
2024-09-30 04:53:43 +00:00
"metadata": {},
"source": [
2024-09-30 05:23:37 +00:00
"### Reading From a File\n",
"\n",
"**emails.txt**\n",
"\n",
"```\n",
"borja@cs.uchicago.edu\n",
"jturk@uchicago.edu\n",
"lamonts@uchicago.edu\n",
"```"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
2024-09-30 05:23:37 +00:00
"execution_count": 7,
"id": "e205aaba",
2024-09-30 04:53:43 +00:00
"metadata": {},
2024-09-30 05:23:37 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"data/emails.txt\n"
]
}
],
2024-09-30 04:53:43 +00:00
"source": [
2024-09-30 05:23:37 +00:00
"# to access a file's contents, we create the path, and then\n",
"# use read_text()\n",
"emails_path = Path(\"data/emails.txt\")\n",
"emails = emails_path.read_text()"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "markdown",
"id": "9f754e26-9527-428c-a18b-48aa2f16406f",
"metadata": {},
"source": [
"### Writing to a File\n",
"\n",
"We need to open the file with write or append permissions."
]
},
{
"cell_type": "code",
2024-09-30 05:23:37 +00:00
"execution_count": 22,
2024-09-30 04:53:43 +00:00
"id": "d0aa3bf0",
"metadata": {},
2024-09-30 05:23:37 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[38;5;8m───────┬────────────────────────────────────────────────────────────────────────\u001b[0m\n",
" \u001b[38;5;8m│ \u001b[0mFile: \u001b[1mdata/animals.txt\u001b[0m <EMPTY>\n",
"\u001b[38;5;8m───────┴────────────────────────────────────────────────────────────────────────\u001b[0m\n"
]
}
],
2024-09-30 04:53:43 +00:00
"source": [
2024-09-30 05:23:37 +00:00
"names_file = Path(\"data/animals.txt\").open(\"w\")\n",
"names_file.write(\"Aardvark\\nChimpanzee\\nElephant\\n\")\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"# (the ! indicates this is is a shell command, not Python)\n",
"!cat data/animals.txt"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "code",
2024-09-30 05:23:37 +00:00
"execution_count": 23,
2024-09-30 04:53:43 +00:00
"id": "d9e2b317",
"metadata": {},
2024-09-30 05:23:37 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[38;5;8m───────┬────────────────────────────────────────────────────────────────────────\u001b[0m\n",
" \u001b[38;5;8m│ \u001b[0mFile: \u001b[1mdata/animals.txt\u001b[0m\n",
"\u001b[38;5;8m───────┼────────────────────────────────────────────────────────────────────────\u001b[0m\n",
"\u001b[38;5;8m 1\u001b[0m \u001b[38;5;8m│\u001b[0m \u001b[37mAardvark\u001b[0m\n",
"\u001b[38;5;8m 2\u001b[0m \u001b[38;5;8m│\u001b[0m \u001b[37mChimpanzee\u001b[0m\n",
"\u001b[38;5;8m 3\u001b[0m \u001b[38;5;8m│\u001b[0m \u001b[37mElephant\u001b[0m\n",
"\u001b[38;5;8m 4\u001b[0m \u001b[38;5;8m│\u001b[0m \u001b[37mKangaroo\u001b[0m\n",
"\u001b[38;5;8m───────┴────────────────────────────────────────────────────────────────────────\u001b[0m\n"
]
}
],
2024-09-30 04:53:43 +00:00
"source": [
2024-09-30 05:23:37 +00:00
"# open(\"w\") erases the file, use \"a\" if you want to append\n",
"names_file = Path(\"data/animals.txt\").open(\"a\")\n",
"names_file.write(\"Kangaroo\\n\")\n",
"names_file.flush()\n",
"!cat data/animals.txt"
2024-09-30 04:53:43 +00:00
]
},
{
"cell_type": "markdown",
2024-09-30 05:23:37 +00:00
"id": "554800e9-bc9e-4c03-94f8-34da10d205fe",
2024-09-30 04:53:43 +00:00
"metadata": {},
"source": [
2024-09-30 05:23:37 +00:00
"#### `flush` and `close`\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"`flush` ensures that the in-memory contents get written to disk, actually saved.\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"(Analogy: program crashes and you lose your unsaved work)\n",
2024-09-30 04:53:43 +00:00
"\n",
2024-09-30 05:23:37 +00:00
"At the end, important to `close` the file.\n",
2024-09-30 04:53:43 +00:00
"\n",
"- Frees resources.\n",
"- Allows other programs to access file contents.\n",
"- Ensures edits are written to disk."
]
},
{
"cell_type": "markdown",
"id": "6ea58e14-15c5-47c5-a34f-16465e4629b4",
"metadata": {},
"source": [
"### `with`\n",
"\n",
"The file object is a \"context manager\", we'll cover those in more detail in a few weeks.\n",
"\n",
"The `with` statement allows us to safely use files without fear of leaving them open.\n",
"\n",
"```python\n",
"\n",
2024-09-30 05:23:37 +00:00
"with path.open() as variable:\n",
2024-09-30 04:53:43 +00:00
" statement1\n",
" statement2\n",
"```\n",
"\n",
"No matter what happens inside `with` block, the file will be closed."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "633efce8",
"metadata": {},
"outputs": [],
"source": [
"f = open(\"names.txt\", \"w\")\n",
"f.write(\"Bob\\n\")\n",
"f.write(\"Phil\\n\")\n",
"1 / 0"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6a58077b",
"metadata": {},
"outputs": [],
"source": [
"!cat names.txt"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "06a143e5",
"metadata": {},
"outputs": [],
"source": [
"# Full Example\n",
"\n",
"# load data into our chosen data structure\n",
"emails = []\n",
"with open(\"data/emails.txt\") as f:\n",
" for email in f:\n",
2024-09-30 05:42:17 +00:00
" emails.append(email)\n",
2024-09-30 04:53:43 +00:00
"print(emails)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c5f481ce",
"metadata": {},
"outputs": [],
"source": [
"# transform data\n",
"cnet_ids = []\n",
"for email in emails:\n",
" cnet_id, domain = email.split(\"@\")\n",
" cnet_ids.append(cnet_id)\n",
"print(cnet_ids)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cfd27918",
"metadata": {},
"outputs": [],
"source": [
"# write new data\n",
"with open(\"data/cnetids.txt\", \"w\") as f:\n",
" for cnet_id in cnet_ids:\n",
" # print() adds newlines by default\n",
2024-09-30 05:42:17 +00:00
" print(cnet_id, file=f)\n",
2024-09-30 04:53:43 +00:00
" # or\n",
2024-09-30 05:42:17 +00:00
" # f.write(cnet_id + \"\\n\")\n",
"\n",
2024-09-30 04:53:43 +00:00
"!cat data/cnetids.txt"
]
},
{
"cell_type": "markdown",
"id": "dccd0d21-f1f6-4c9d-a4c6-b52663941271",
"metadata": {},
"source": [
"#### Useful `file` Methods\n",
"\n",
"| Operation | Purpose |\n",
"|-----------|---------|\n",
"| `f.read()` | Read entire file & return contents. |\n",
"| `f.read(N)` | Read N characters (or bytes). |\n",
"| `f.readline()` | Read up to (and including) next newline. |\n",
"| `f.readlines() ` | Read entire file split into list of lines. |\n",
"| `f.write(aStr)` | Write string `aStr` into file. |\n",
"| `f.writelines(lines)` | Write list of strings into file. |\n",
"| `f.close()` | Close file, prefer `with open()` instead. |\n",
"| `f.flush()` | Manually flush output to disk without closing. |\n",
"| `f.seek(N)` | Move cursor to position N. |\n",
"\n",
"-- Table based on Learning Python 2013"
]
},
{
"cell_type": "markdown",
"id": "2647b979-0e90-4b94-b5b6-6790c3c08f1b",
"metadata": {},
"source": [
"### Common Gotchas\n",
"\n",
"- Relative paths - use `pathlib` https://docs.python.org/3/library/pathlib.html\n",
"- File permissions\n",
"- Mind file mode (read/write/append)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "94aa2e2c",
"metadata": {},
"outputs": [],
"source": []
},
2024-09-30 05:23:37 +00:00
{
"cell_type": "markdown",
"id": "02eb6878-7a2d-46b0-a0f3-e7aab18ebe11",
"metadata": {},
"source": [
"### Note: Relative Paths\n",
"\n",
"You may find that if you are running your code from, for example, the homework1 directory instead of homework1/problem3, you'd need to modify this path to be `Path(\"problem3/towing.csv\")`.\n",
"\n",
"That is because by default, paths are *relative*, meaning that they are assumed to start in the directory that you are running your code from.\n",
"\n",
"This can be frustrating at first, you want your code to work the same regardless of what directory you are in.\n",
"\n",
"### Building an absolute path\n",
"\n",
"To get around this, you can construct an absolute path:\n",
"\n",
"First you can use the special `__file__` variable which always contains the path to the current file.\n",
"\n",
"Then you can use that as the \"anchor\" of your path, and navigate from there.\n",
"\n",
"A common pattern then is to get the current file's parent, and navigate from there:\n",
"\n",
"```python\n",
"from pathlib import Path\n",
"\n",
"path = Path(__file__).parent / \"towing.csv\"\n",
"```\n",
"\n",
"This line uses the special built-in variable `__file__` to get the path of the Python file itself.\n",
"It then gets this file's parent directory (`.parent`) and appends the filename \"towing.csv\" to it.\n",
"\n",
"Using this technique in your code allows you to set paths that don't depend on the current working directory.\n",
"\n"
]
},
2024-09-30 04:53:43 +00:00
{
"cell_type": "code",
"execution_count": null,
2024-09-30 05:23:37 +00:00
"id": "5a9bf4ab-dbcd-4dd3-a928-89d33ce88273",
2024-09-30 04:53:43 +00:00
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"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",
2024-09-30 05:23:37 +00:00
"version": "3.10.15"
2024-09-30 04:53:43 +00:00
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": false,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {
"height": "calc(100% - 180px)",
"left": "10px",
"top": "150px",
"width": "305.8px"
},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 5
}