{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c5145201-7b75-461e-b7bc-705fb9e1bb03",
   "metadata": {},
   "source": [
    "### <center>San Jose State University<br>Department of Applied Data Science<br><br>**DATA 200<br>Computational Programming for Data Analytics**<br><br>Spring 2024<br>Instructor: Ron Mak</center>"
   ]
  },
  {
   "attachments": {
    "855b7850-72a7-4f0d-9bfd-1cbaa1934078.png": {
     "image/png": "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ToolAiIgAiJQCwTillq6w0vM0tHRNhEQAREQgYIgIDEriGpSJkVABERABNIRkJilo6NtIiACIiACBUFAYlYQ1aRMioAIiIAIpCMgMUtHR9tEQAREQAQKgoDErCCqSZkUAREQARFIR0APTaejo20iIAIiIAL7lUC6B6ODm36yOLLM9ms16WAiIAIiIAI1QUCWWU1QVZoFT4CX2sbv/vjOXSHry8vLq12+KKko5Oc8XeHulxwGBmFd+M22bMOunVG595S9rKys4hjZpldT+1HmeLmrW3ZemEt5U4Xqpp8q3WzWh/OfZchzrvIXmAa+lV1PmR5XYpZNTWufkiDA1CNr16716ScaNmxobdq0sXr16lWr7FzATGWybOkyW7turbVu3dratWtnjRo1qla6ud6ZqTfWr19v69atc7Fp0qSJtWzZstpT0Hj5t2z26XwaN25szZo1y0sxQ3go/8qVK7nnsGbNm3n569evnzVqRIFpfJjOZ9WqVc6yffv2fl5V1qBnfdAsdqSOKD9l5xogb5ynnANB2LJI1nfhfGI6G6a1Ib2OHTtaixYtUiaXqZCRgMQsJUZtKHUCNDqvvvqqLV682FFceOGF1r1796yxcJe7ZcsWmzBhgn344Yd+QTdt2tRGjBhhAwcONBr3qly8WWckgx1pdD/55BObMmWKTwrauXNnO/fcc438ZhNoHDds2GCzZs2yhQsX2kcffWQnnniiHXPMMVYdgcgmL5nsw0So5PG1117zyTERna997WvWoUOHTHZPGocbhOnTp9vkyZNtxYoVLma9evWyE044wXr37l1toUh60CxXMhnqiy++aMuWLXNBGz16tA0ePNgaNGiQZYrm9f7GG2/4ecUNHed7nz59/Pxv27ZttXs8Utu8WWdZO4pA4RNAVJgIE2usVatW9tZbb9miRYuynu2Yu10as9mzZ9vvf/d7vxsdNmxYZJ2ts4cfftjXI3b5EEI+mjdvbogY1ujEiRO9Ucsmf+FOf/78+fa73/3Onn/+eXvllVfss88+c6FkO598CuQHq7FHjx4uMohadSeHpfx/+tOf3DobOnSoHX744X5T8+CDD7oFnE8MsMYQmC5duvgNyLx587yuqlNHXENvvvmmderUyUaOHOlpP/300/bCCy84k+qWX5ZZdWpH++YVARphLAqsH74jRuFOkgY5WD27iBcJC/GwGIhHNyLLEIdl165dvTGnW2TOnDnVanBJj7vdZ5991voP6G8XXHCBiyR35Lfffru9/vrrdsghh1Tr7hRrgjIhmjQMDeo3sPK65V4uuofIA+spM5z48BvLiPKHri7i0gXUv39/69u3r836dJZbKdlWNsflQyN25ZVXGtbIr371q5xbZKH8lItA+cvKy6xe3Xq+JA8Eyg+nEI9zg/OE8oc48Oh/6KHWr18/e//9992q8J2r8e/tt992nmPHjrUunbvYzl073dL/7W9/6+k3bdosqqvsxmM5p7ftqX84UBbqlbrke6hb6pvtWEYhHmWHQehChAH1f9pppzmjBQsW+PnBvtkG9kW8jzvuOO+ypE6+XPulp/vSSy/ZeeedV8E+22NIzLIlp/3yigANFP3xU6dO9c/q1av9rvr444/3i/bII4+sGO+iu4sGirttrC0abLp6EBMu7HBRU0C+8+FirM7FTFoclwbtRz/6kd/108B069bNDjzwQB9HYHu2XW40TNw90y06c+ZMF3O6hUifD8JMg4XQLV261MWTLi8a9EGDBtlJJ51kdKXFBZ0807AhCNUNHJuxQT7bt2335Jxn9u3jXlmi/J9//rm9/PLL9vHHH/s2Gk/KRP1iYVA2zhPGgrAM3333Xed02GGHeZcnVmicfx3qfk+9V7fuyRBddaSPxUfdl+0q8+903TKGVla2+2aDuEFU+V5ZIG/ro3NnxowZ3i1MtzhjUeGc57yG+84dO21zNF6JRYyAcIMGHwSGc4Wxq3Duh+Pzm+/x8ofvIU5l+WM7cbmJYV9uNKkHPpyP1EtIM5O0UsWp/lmaKmWtF4H9SAAhw8J55JFHvHsEEUMcrrvuOrv++uttzZo1fvEwqP/AAw/YH/7wB79wGa9iHfH+/ve/+z6psl2VizcxDS5WGlzEg67LIJDlZeXuWBAu7sT9MvnNvoj4r3/9a2/QaMSPOuooH5u56KKLbNKkSRVdhIyD3Xbbbd7Vd9BBB7nlQRfiDTfc4GIYuhgrO24uGh8/RoZzVaXKT8jHe++959YeY5GIE/VPl9bVV1/tDTeODDTmjNndeOON9sQTT3jZGatE2G6++WZnF9JLdbxs15NumzZtja7bIBh0W9L1hpMRY0dhfVWPQTqPPfaY/fznP/ddGYtEMPl9yy23RGNUM10s1m9Y7116XA8IOiKGBUrXL13dX637qkqHriqrcP0wZvrEk0/Y//7v//o1xzmKuEeI9glVOYYss33waUWhEeCEp/uOQfXLL7/cG6myOmVRgzbUDj74YLvnnnv8Yqax4M6dBu2SSy6xo48+2q2V4cOHe5caAkfXGg0LF1e4+Eg/2UXFOixALDwcJUII+/Gbu2PuyLnrDXeibA9xopQrvMQQu2wCDdPjjz/uFkhw0oiOYMcMOcat1d0NxS7n88wzz7j1edNNN3l3D8c7adRJ9uvf/NobfTwWuYsPIZQ9WfkRPqyhhx56yJ1ZdkS/4y0SDTfjgicMPcHqRFZHCHSvxUNgEV+X6XfyhWco9cr41sUXX+xOKtT/kCFDPF9YhcRbtXqV1xM8EC+cOVhP/XMjhOhjwWKtZBIoP+zvu+8+H0+L3wiQLg4OjI0xPkQo32PhEg9vPvLMuXPZZZf5MVlfFRacTwQsbPL+/e9/34444gg/p7lp4jweP368H5f8ICLU1RVXXOFs6ErknIPTo48+ahNfmmhnnHGG759JPtj3nXfe8RsjutATAx6Q5AnBDOmx5CYTKxJnEALnye7Adbbna2xB3kMI6YTf8aXELE5D3wuOAA3Ali1bbdq0d12csDb84ojOf9zdR40a5d14LVu28gsXy4Q4XPQIDBdH4ygeFhp363TR4LFIQ1RZYN8wLkHDwu/4hcf+dKOE9YgpDWtiCPvSyGYTGNMgHHH4EdaxQ8eKbsFGjRvZf/7nf3pDSYNCPCxYGu/Q7cZ+lPXMM8/08nO3HixHtsVDYtn4TZ4plzfksUaH/Si3l+kfOlaRHNv4VDeQxqLFiyo87hCiYOE0bNTQfvjDH3o9h/IjvozPIHzkjf1p1E8//XRvlGnwMxWzkHcadeowzmdnxAImQUhDXJYIII4PdHOSF8Qkm7qnnIx9LVmyxIU5nNMcg3Mf6xxxRrQ5D7nZQ2C4wWjapGlF3WDJk5dPP/3UTj755KTnKGkmBtghmpTf6z8hQtgGl1DXfIf9t771LT8Wzh+MGf7yl7/cp4s7IblKf0rMKkWkCPlMgItkV3Snvym6M8TrkEbLQ9RO0kAgWHQ7RU2rbYsuPO4gGRuhASN4AxSlwbgFjTpdjlyY4eLzSBX/9m18aTS4+8aiSxZINzxDFhosHEoY0whjBQgM+eB3NoG7fPLetFlTb8hD3knv0MiJgd98uCNmTJAGjd9e9uiANIp4rtEg0zCF/SvLC/EQPqxc9ksMHP8fd92JW3f/xoKsTqAM1BllgDUPZFvZnrSj/DEeGUSLxpUP5Sc++aeu+U4+uTFBHDIN7I8lizWYKGahPslTCKxDUB4Z94h9MvMTO/XUU91y51wkrVAfIX5lS/bhuJzTnOeUIaTBkt/hOT7EDKcXfjeLHE12Y8fiiW7monOHPIRuRtLNJMCN8dZevXolFbO6kZNHsMrITxA8jsUxOefg84Mf/MCHAVhPmqEMmeQhHie7qyeegr6LQC0S4MKj0WzVupVbVQgD4sEFwYcLeH7kEs0dKo1V61at3QGCZ8hwjAgNwvJly/2OmbvY+vUyfzDWjx2JKI1aZQEhweqje4VBee7aGcvDCYWGp0KIK0soYTuWBOMmiOS27ds8XcpF+ekGRcSIQ/chjRrWCXfjNByErVu3+bM/NDDkI9PAMWAdxDrZfsSp6QB7RArHFqxuHFZCvTIeRZkpFzc7NJg8HgF/zgcC50hwPUecMw0cgzQ4t0JI1xBzztGdN+OjGW4JYgXTmJN3zqNwsxPSqnQZaRH7UW+MFXIuUcYQSBfx5LxC7OBEHhYuWrg7z3vqnzicO81bRIJehXOf8sM1k3MmiG69KP0GDf7hZck1QTqUo7qh/KdRqG4i2l8EapoAjTIXJY1RYuBi4MJl/IEGmgaGu1W6DHECePLJJ906466U7dOmTfMLn0YAxwC6lh5/4nHfhzEDLnq8vrjAERo+uM7TUHAsGkiEiOPwO10DlphXfuNocsABB7jIIGx4lzFon+rBWcpGPil7aIDj6dIg0EVEOjQs3AHDi0absTTyj4s5DSeNGeWn7MRDBD/88ANnRFcr8UiPMs6fN98ZzJ071wUYocAKxHohH8m6TOP54jt8CByLfUmLB3EZ46EuaECpK+KlEkXEBkEm/+QtMdBALooaaMZvqCMaTsrF2CgP/nJM2LI/wkbXFiwRDwQAIaBOBgwYUPFg8MYNG50fDT3pwIwbEfYnv5SdTyhfyBO/k30o/5+iZ8w4Ds4p1D/lom5wXoEnFmMIIV3OLXhzDsSFiniMt1IGtpFGyBfpwpiuw1BWbtzgQjc7XoyIG/G4AcADduHnC23kqJHWo2cPj8d6rgvS4boiP5wz3CxyPPiFPIY8p1tiPTOuzflHDwn1yU0VXpWkw3UXhC2eLhY/dcl5Ha63VMepvhymSlnrRWA/EaBRpKuPC++pp57yAXEEid9ckLxlgt80PnSLcHEwPoYLN2NHXFQ03tdee613fXBnz8VHw4NIcOFxEeL1h/jQqPCsEJ5w8QsvXXGJRwMwPBqv4g0QOA3QeNFQjhkzxsfwyqI42QQaprPOOss9Oe+88063TmgEaLg47ne/+11vKBALxhAp/9133+0NPNs/i/IwMOICJ9Li9U0L5i+w+x+43xtv2MCDPNOgIHhf//rXnV0m+aVBRgQQFRwQaHRpxBFc6oduX8asEhvrTNIm/23btvFxIG5e7rrrropur/mRRU5+L4scLCg7jTEu6MS7//773UGCvFEH1CU3FH4zEHk9LotuZEgLAaD8fPCUZTvdatR/pm+D4Rikw2MZCCqPhYS6gQVsr7rqKhc4ypNpIC4fnJx4O8k9UZ0iYJzTjKNRTs53urQRPXodvvGNb9gdd9zh9c96zgU+Z599trMhPcQKkcHTkrxjtXItcbNE/hmbI36yG4tUeUfMuTHg+qSHgC5GbhY5Fg4pubDM6kSZpeNUQQTylgCnKBcSgpRqcJ6LBeuFC4/nrLACiEvDSzcQF0toKLgjRcBoULiQiUdjRhdTuNtGwGgMuHMnhH1Jh/wwiN0qcirJ9BmssD/7cneLKLKkYeQ5qGBR0ejEA/EpCw0/jQCCmBiIQ/kRXMSXfCPwNF40POwTLz/HJR6WG40sFlf/Q/vvHt/Y86wT5YYR28N4GHmjHOSVhpCGrbJAfPJHGhwX8YI/v2FNvhAa8hq3TOLpsh9lIw7WdbLAMWBEnSKa5BWxYcyQ/JKP8EFAuJHhnCJQBzBo0TxyCIrKjwv/uoj5nDmznSNxyHM4NxBFBJjzMdPAQ/rcNGBlkdd4oK6w1EI+2UZeCfCnLjgHyGeyQHqc+wgYno2IBOcKIsc+8XOG9HimDUuT+FwbdLlSn5SPvHDjQT1xXPKB4LCeuuLDDQ/l53tVwuZNm23uvLl+84CA8xA99cOxKQPHCCEwghc3JeSTcsTjhLhhKTELJLTMWwKc2JWJWa4zzzERCEK6C6gqxw0NVFX2IR+ZiFmqNBOPGRqJZPET4xInxPclbXDUxiaLlyw91iXGDeklrk+1P+szEbOwf7r0020L+7MkHvlLFT+sJ25VykH8qoZMxIw0Q57Csir5SoxLGvF0wvawLpQhrA+/c7kMx6qKmFVNWnOZW6UlAnlOgG6/ve+h8zzDNZg9b7gy7wFLmZOabAA5aLr0022LZzjEC8v4tnz/nqs8J0sn2bp84iExy6faUF7yhgAX7h5DJG0DmQ8ZrkojU5W4lK2q8fOBR03nIR+Z5DJPpBUso1ymW5V6yea4ErOqEFbckiKQzQVVUoBU2KIlUIjn/j9G3Iq2WlQwERABERCBYicgMSv2Glb5REAERKAECEjMSqCSVUQREAERKHYCErNir2GVTwREQARKgIDErAQqWUUUAREQgWInIDEr9hpW+URABESggAmExwQqK4LErDJC2i4CIiACIlBrBDJ9TEBiVmtVpAOLgAiIgAjkioDELFcklY4IiIAIiECtEZCY1Rp6HVgEREAERCBXBCRmuSKpdERABERABGqNgN7NWE30wdOGQcr492omm3T3MCVJ0o1FvpI5pphXiSkhSi0wl1b4JM53VgosKHuoe+bcKqXAFDCbN/+j/KVUdspKvYd2tbKy15qYkUEaZyorTHpXWWbzbTv5B3YQGcrE3FfMbpvrRoe0mVQwTJSYbyxqMj/cKKxavcpmfTbLZwuuyWPlY9rUO3N6MRkks/vman61fCxrsjwxUSoTRTJ5ZarJOZPtVwzraFuYzy5MFptYpkwb+sT9CuE3ZUMfWDIxa6OGjdKe+7UmZogAM6Iy6+mBBx5ozaJZa+vEZhrNFewgmEAhIDLMkJqpu2e6fDAjK9OUM2tqCFxwzO6bazEjfViVomVCHb744ov2zjvv1AjXUHf5uly7dm3FTMuZzO6cr+XINl8IGbMi9+zZs+TEjJtXZtlesWKF9e/ff1+EUUNfrIGSoRPcvP3iF7/wGa7TlbVWxAylZSrsG2+80WbMmGH/9V//ZWeddZbfdabLbFW20QByHBoCplKfN2+eQ2F6cqbqbtiwoTeM1bnL5W75nnvu8bKEvDFVOR+ss1wGxLdHjx65TLKg0qIxGzlypJ122mkFle/qZpZ6//DDD+3VV1+1U045xXr37l3dJAtu//fff9/+/ve/2z/90z+VXPk3bdpkkyZNsqlTp9oNN9ywV93l4oZ8rwTz8MfChQvtzjvv9Jv4XTt3z4Cdqty1ImYwC91xfKfrJNcBEXviiSfsgQcesA8++MAtMQSOz8CBA+3aa6/1xrFFixYueqkA5TpfSk8EREAEqkpA7VNErJKZzjMSMyycxJAMbmK8dHG6detmP/vZzwzl7devn4+bxY+RmFZ8W7J0w3bEatPGTXbXXXfZfffd5+KF1XfkkUd6lNdff91efvllu/766/1z5plnllzXRWClZeEQ4HoIn3Tnf+GUSDmtKoFSq/dwvsOpDn9RL0W6kJGYBYsGaypZtxwH3RF5m+3atdMPSJzEAxMHjzSWKCzdcJ06drLWrVt7l19iurvT3D3OFQpQNxrvihIOP5Mu2W/au9Ns/PjxLpBXXHGFjRkzxgePGccaNWqUDRo0yP7v//7P7r33XuvZs6cde+yx++Q3aeJaKQK1QMCvmVo4rg6ZHwSo/8T2ND9yth9zkb7Z94wkFTOcJRh4mzNnjnfRMb5Ft13jxo2tS5cudthhh/m4U+NGjQybDdfZp556ygdpBw8ebEcOPtIaNmpYUVL6fenzZ+yK7UcddZRtidxNp7w+xWbNmmUXXnihtWvXzsewcKpYsGCBO1bMnj3b08bbsU2bNj5mxCBox44dU45JMWD65z//2QdNL7jgAvva175mXbt2dRFFMHHQYP3HH39sr7zyik2cONEtw1atWlXkV19EQAREQAQKi8A+YsZdAG6gjDc9+eSTNnfuXBc2HCYQGoQOJ4qLLrrIvn722RaphN81rF692kVk2rRp1vTfmvq4FHcTbilF62699VYXK5wjWP/V+q98UHfKlCl20kknGWKCBTh9+nTvHqQ7EPHhuKxHXNmPQeCLL77YxS8Zarx+GDBG/IYNG2adOnXy/cKdDWkihmdHeX/zzTd9cH3p0qV+/GTpaZ0IiIAIiED+E9hHzMgywvH3yNLCA5CxJrz/8PPneQc8a7BoEA1c0Lt37+4OHKNHj3aPGwTiz3/+i1twCArxGL/CG+3qq6/2Lj66GBE53MxJE4F0gYu+47Dx7LPP2iGHHGKnn366H5f8IKoIH98Rt1Th888/N4T18MMPt55RF2IyF3n6X/v27etdnIsWLfK8MW6nIAIiIAIiUJgE9hEzRIXuxEsvu8yaNGlS0QXHs1mIzvHHH+8P7j733HMuLnThEXr16mXf+ta3/FmoCRNejPY7xBA4nDDoyhs7dqy732MVxUOwmFiHsGFV8XDoNddc496GQYzoyvznf/5n4zmbdA9OImRYkByHLkVEM4SKY0X9r3RrkhYOKDzHoiACIiACIlC4BJK+m7FRNBbG8zwIF67rjEMx7oUlhcPGySef7CVmDCxYVXTfYcX9y7/8i1tD//M//2N33HGHdy9iwX3ve9/zsasKQUlgxv4ElojRl19+6Q8jc8ztkYhizXXu3Nm7AxHWVIEuUvKEULEP6XHM+HH5jmDzSAAiyfEUREAEREAECpdASlWgKw8r59NPPzXGlHAAoYuPz0cffeQWDw8NxwPjWyNGjPD4P/7xj+1Xv/qVW1k3/OQG744MVhb7YDElfhBKugcffvhhf5AaF/pjjjnGH5Q86KCDXMjYJy5M8ePzHSEm7+QNoeJ7EMoQF7FDwBBpnEvIt4IIiIAIiEDhEkgqZrwL7plnnrHbb7/dvQ2xYOhyDC/5RCiCEFD0uMAQD29HHC8Y58L7sHuP7hX7pkJFGuxL92L79u193Iyxs8cff9wtPboecei46qqr0r5hA0FE0LDsKEcy4UPcwnaEDAtOQQREQAREoHAJ7CNmWC28M/GWW27x7joeLqa7kW45hAHLDE/DH/7why5ooej+DFnkqM8Y1KOPPuppIEq8T++RcY/YRf98kVtpQVziS74jMHy6d+tuV155pV34Txfa6mgs6+OPP7K5c+bay6+87N6VOHjQhYlTSkgj5IEl++MZOXPmTCMujh6Jgf1wzeedZ3369Cnp10QlstFvERABEShEAvuMmSFWvC/xs88+8y5DPAoRDt4JxwuBu3bp6sKGJRXvNuRB6JUrV9pjjz1mOIfQPYg7Pvvd88d77LXXXnMHD/YLIZkY1a1X18UIaw6rjufELr/icn/RJB6HiBAWX6pxrvYd2rvTCkL1xhtvuDdlOF5Y0mXKc3GMr3EMxuIUREAEREAECpfAPpYZRUGk+DDmFASHsSeEbvac2d71h5jEx6IQhgkTJthf//pXt8D+7Qf/ZkcedaR3Qf70pz+13//+9+48gjNIwz3vYowLG09f48aP6PFgNsJJtyNdgHQd4vQRnjkjTyFfieiJf/755/vzanRRktYZZ5zheSK/CO7TTz/tb2HnlVonnnhiWu/IxPT1WwREQAREIP8I7CNmjIv16d3HrTGE5U9/+pO/tQORwBFk8uTJxoPRCAMChyAxfsbDzvfff78L3je/+U0bcswQH7vi3Yd4PeLUwXbGvuJdf+zvn0jNcDbhDcn8HjJkiCE2uOGTPtt4YTBWYs/o+THEjXiJosZvrMJzzz3X/vKXv7hHJW8SQRwpG/lkOhG8HXH1Z3wvjAXmX/UoRyIgAiIgApkQ2EfMsMg6de7krvR//OMf/R2Hzz//vFtIiArWElNxMCUBQoN48HwYVhDPa/FSX96uQTwCy0svvdTFiGfI6PrjQWvECLf/tm3bVswvxm/EChHFwiNtnDkQLSxBBOk73/mO7x8Klyho7INgXnLJJX5spo7gTSaIL+OBWJtYa7xFhC5Mjq+w/wgEC58bI6x56pexVc6TuKW//3KkI4mACBQDgX3EDDHAaqGrjjEqRGvZsmVuHfFgNNOn8DAybwIJooR3Iy71bOOlvTRO8cA8XD/60Y/srbfeci9HRJFjICYcg/g0ZAMGDPA32TNehxWGA8fmSHxaRw4djGsdd9xx/qxag8hKJJ+pAtvwpuSZNzwg33vvPU+LblLyQh55JRcNqRrQVBRzv54bj82bNtsnMz+xhx56yB/34DzAeucZRW5CFERABEQgGwL7iBmJIAZYTrxdHoHCoqEhwmpjyQcvQNazDjHiZcGsTxYQDNLiEwJxEZrhw4e7oARxwjobfET0suKocQvHCscNz4xlMiM1x+RuH4HE2iOwjuNIwEIt7N8l9bl4yWKf+ufoo49265mbFrqyqRfOBepaQQREQASqSiCpmMUTCcIWXxe+h4YnLMP6xGUQqvj6VOmyvk75bqsriA6NIN/D73g66b57WjHxSpaPdPsX0jYY4URDGaPbDX8BNLcWTjJaV3EjwHbism3Pd7bxiY8dhnUwDxzZJ6TDjUx8fUiPZaqwfv16t5JJ87vf/a57xeJNypgqosbNDo9VVLWeUx1P60VABEqHQKViVjooCrekCMzqVavsL9E4Iw+DD48sHLqAecaPMUrGBbGcO3fqbGXlu18XxguhX3jhBX+ZNNsZBz3l5FN86h4eNmeskel5wuwDWLfbt223OXPn2Lhx49wqx0mHrl+6nTMJiBnPIbIfXbwh4OHKc4Hr1q5zz9WwXksREAERyJRA3okZd/uJIdm6xDiJv7PZJzGNQvlNWRtEbzLB+xMrh4fWw+u6EA6cLRAvnHO2btvqzwIyA8HAgYPslFNOjbYv8WcDGR+97rrrrH693WOSvLaMRxfo+g3vsOTheSxxxiERzfB+S8YjI5t6b2TRT7qrsfjYhzRw+mBGhBDKy8pcbBlHXfPlGuu5qwcmY9ispQiIgAhkRCDvxCyjXCvSXgQQM0QG4eGBdx6fwMkFxwoEDqEgICx05yFkzGgQrCpe5swsA7fddptbc8cec6w/joFVhyMNnZUPPvigi9E3L/umr0OQevXq5WnifYolh6AlBjxQv/71r7ulSD4QM8QxBDo8sewQPLouJWSBjJYiIAJVISAxqwqtPI6L5dOieQsXNZxnmHKHlzMjEnErFTFjbroBAw7zaXDYxsPoPG/H83k8Q8j+iBsPq/O4xZLIaWP8+PGeFl6u86OZx/FCRYQY32J/vBKTiRmPbyCiBOKST2ZgCIF17EdXaYgXtmkpAiIgApkSkJhlSqoA4jEehljwCjEsMh50D84eIfs8E7j7ZcwN93LgQPQQOcbJEBbGtHDGWLx4cYVDBoJFVyRxTj311IrZBhBCHnVwyyocKFrS7digYQMXOkSTY+BhykStwamHJW9+IXBMfsfF1zfonwiIgAhUQkBiVgmgQtkcRIslgoYghHXxMvCcHeNnCAiPVCAwPl4VWWCMtyFKwZqjG/HDDz/0uFhtOIpgofFuSwSReATGzRCiRBHi5dN1yiJJi/JCQAwRTB6ep2uTfVjyvk26SRHPZHn2nfVPBERABNIQKEuzTZsKhAACgMBgRbFcFXk24vTBb164jONFCDzfhXPISy+9ZLzmiwfiFyxY4FP+sDzhhBMqLC6Ej7ToVhwxYqR3P7766qveHRhmUUCmUrnSYykGIeP4iBnP/fGiaDwtsdAY45s3b553WyJmCiIgAiKQDQFZZtlQy7N96N575ZVXXJDoAsRiojuQZbt27XwOOB5yJzAWxqu+cOj47//+b3e9ZwwLgWPqnfAOS0QIS+zggw92gezTp7dbTYMHD/axOLoLXaj2WF2ZICE/5OOcc87xKYboDuUtL6NGjfJnzNguyywTkoojAiKQSEBilkikAH/jODFmzBj3TmS8i4DQIAx0AcZfE0UXJGNcN910k1tuWF5092GFES9uSdElyIzhiGXTSLx2RundfffdHqdCzKrAi7TpnuRdnXhTLpi/wDp26uivKgvdlPHjVyFpRRUBEShxAhKzAj8BECw+WDU84Jw0RNsjBarYRLcgIseYGCIWvAzjQhLSxVPRQ7R/WfTBO5EQj+srqvAP8eVlzx07dPSHuMMYXxWSUFQREAER2IuAxGwvHIX3I4gKS0Qh04CgIFhh/8T9WJ9sW7J1iftm8pu8ViW/maSpOCIgAqVLQA4gRVD32QpMtvsVATIVQQREoMgISMyKrEJVHBEQAREoRQISs1KsdZVZBERABIqMgMSsyCpUxREBERCBUiQgMSvFWleZRUAERKDICEjMiqxCVRwREAERKEUCErNSrHWVWQREQASKjIDErMgqVMURAREQgVIkIDErxVpXmUVABESgyAhIzIqsQlUcERABEShFAhKzUqx1lVkEREAEioyAxKzIKlTFEQEREIFSJCAxK8VaL8Ayh7f4F2DWq5Vl3p+pd2junqWhVDmUcrkpO9e+MfFH9Jcu6K356ejk2TbmFfOKzbN81XR2OKH5bN++3TZv3lzTh8ur9Jmeh4lT+TBjOBOppprZO68ynsPMUHbqnmWp1T91Trm59kut7JxClJ+6jya6Qs3SBolZWjz5s3FXNOkmDRmfMAFn/uSuZnOCgLdq1coWLFhgL7/8cs0eLM9SZ5qc+fPn28KFC+2dd96xRYsWldwNzbx583wi2ddff934XkqBxvzjjz/2GdlL7dynnlevXm1r1qzJ6JyXmBXIlVEnukNfv359SYoZVlnjxo1t1qxZtnbt2gKpsdxlk4t5+fLl3qghavAopbBy5UpjRnQa9SVLlpRS0b0Rp8wrVqywadOmlVTZOc83btxoGzZsqCh3unNfYlaBKb+/YJ0wk3RkbFdmbed3QbLIHScwF/SQIUNsxIgRWaRQ2Lt89NFHNmnSJDvllFOsd+/eJWeZI2JPP/20jR071g488MDCrswq5p6uRSxSrPJrr722insXfnSu+3vvvTejgkjMMsJU+5Fo0JkdOt2dSe3nsmZygJDzqV+/vjVv3rxmDpKnqVLupk2bVnyaNWtW0eXCNkKxnxONGjWyBg0auHVeavVfr149a9iwoX9Kpezx83rdunUVM9KH9akuVXkzpiKTh+uLvdGqDHmplp9yV5R9t35VhkrbRaDkCEjMSq7KVeCCJlBaw2UFXVXKfHYEKm7cot3j1lh8fbKU1c2YjIrWiUAeE6jsos7jrCtrIpARgXCOI2ZxQUu3syyzdHS0TQREQAREoCAISMwKopqUSRHYlwB3r+EOdt+tWiMCpUVAYlZa9a3SioAIiEBREpCYFWW1qlAiIAIiUFoEJGalVd8qrQiIgAgUJQF5MxZltapQxUQg7tGVqWdXMZVfZSldAvEx4crOfVlmpXueqOQFRqCyi7nAiqPsikBOCUjMcopTiYmACIiACNQGAYlZbVDXMUVABERABHJKQGNmOcWpxDIhEO8ui/eJZ7Kv4oiACIhAMgISs2RUtK5GCCBiTCy6dctW27R5k23dutWnteHN4AoiIAIiUB0CErPq0NO+VSLA1O9MsvjJJ5/4/FzMoHzjjTda9+7drSyafFRBBERABLIloBYkW3J5vB8WUPhgCfEJv0O2+R0P8d/x7/E4fEeQsg1MgT5+/Hj73R13+Nxsixcv9plkyZ+CCIiACFSHgCyz6tDLs323bdvmolVeXu6WjnfpRV15/E7WlUc33/bt2z0uE1/Gx6+2bNkSzb9gLjpl5WV7baObECmsy3EStqVD0rJlSzvvvPPsjDPOcIF9//33Pd34cdPtr20iIAIikIqAxCwVmQJaj7X0xRdf2P33329r1qyxE0880bp27WpvvvmmTZ8+3Zid+JJLLrFevXr5jL1r16611157zV555RVbsWKFz9581FFHuci0atXKNmzYYI888ojNnj3bOnToYKNPGm0HHXyQC9DMmTPtb3/7m23atMmOP/54P1aL5i2sTtneE20FSxChCmKFoLZt29bTIZ9hfTpLsICqQVkVARGoRQISs1qEn6tDIwqNGze2gw8+2CZMmGDPPPOMJ826o48+2ph6fMGCBda7d29bv369Pfroo/bBBx9Yv379bNiwYYa4IXrEufrqqz2tJk2a2Ny5c61bt27WrHkz7w7E8mPq9rp16/q20aNHu8WHM8fmTZvN4nqG6Rb9Ji7T3iNkcWHjexC8XHFQOiIgAqVLQGJWBHWPMDRt2tQQl88++8ymTJligwcPdksLawwR2rx5s3c3sn3q1Kked8SIEdaiRQsXqgMOOMBuv/12e++999ziGjJkiL377rvWuXNnFyEsNY7zjW98w60+uij79u1rDRs0tCmvv24TJ07wLktwRraYC9XOXTvdGjzttNNcFIsAtYogAiKQpwQkZnlaMVXNFt6AWEBYQnQZMjaFQDFeFg9YZD179nSxa9OmjW/C2urfv7+vQ8DYv3379m6F4X2IxTZu3Di32E499VTvfhwwYIALIdbXjh3bXSyxtMIYHAJKQPQUREAERKCmCUjMaprw/kx/j4ci42WIEZZUYqBLEWusQYMGe21C9Nq1a2ezZs1yQSIOYrdkyRJPh+10PWLVzZgxw8466yxPg2MwRjd06FCP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"
    }
   },
   "cell_type": "markdown",
   "id": "10c25cd3-28ae-48bb-bcbd-85c0bc623569",
   "metadata": {},
   "source": [
    "# Axes\n",
    "#### We will frequently encounter the concept of an \"axis\". Unfortunately, it can be confusing.\n",
    "#### axis = 0 is the ***direction across the rows*** of a 2-d array<br>axis = 1 is the ***direction across the columns*** of a 2-d array\n",
    "#### ![Screenshot 2023-04-11 at 4.46.31 PM.png](attachment:855b7850-72a7-4f0d-9bfd-1cbaa1934078.png)\n",
    "Visit: [NUMPY AXES ARE HARD TO UNDERSTAND](https://www.sharpsightlabs.com/blog/numpy-axes-explained/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "95cd3dcf-ee97-4706-b5c0-d7533f5644bc",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "66157be5-7c1f-4b86-947e-278fe1b4de63",
   "metadata": {},
   "outputs": [],
   "source": [
    "matrix = np.array([i for i in range(1, 13)]).reshape(-1, 4)\n",
    "matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "45ea8dfb-52eb-4a14-8d6c-f924b3e13ecd",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.sum(matrix)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a260e115-0d2c-40f7-b574-3575b83544a0",
   "metadata": {},
   "source": [
    "## Sum of each column\n",
    "#### `axis=0` means we're summing ***through the rows*** of each column."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "94fc77ef-2a17-41b0-bb76-9abc7bc9aa40",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.sum(matrix, axis=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8954511c-67f8-41d1-8def-6d660afe43da",
   "metadata": {},
   "source": [
    "## Sum of each row\n",
    "#### `axis=1` means we're summing ***through the columns*** of each row."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "72acd352-cb2c-4919-9d07-61360a2f8cfb",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.sum(matrix, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0810d0f2-6510-4b15-baab-cd873684cf45",
   "metadata": {},
   "source": [
    "## An array of random integers for sorting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "20c4fd84-8da5-4f62-8066-56b864ca75c2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "unsorted = np.array([random.randint(1, 100) for _ in range(1, 13)]).reshape(-1, 4)\n",
    "unsorted"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "86e1d632-8f64-4d73-8749-fcb7b3259964",
   "metadata": {},
   "source": [
    "## Sort each column separately\n",
    "#### `axis=0` means we're sorting ***across the rows*** of each column."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d09a8066-b091-42dc-8f97-ab761e21a263",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.sort(unsorted, axis=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f2ac3ea1-175b-4297-8528-d11c8caa7042",
   "metadata": {},
   "source": [
    "## Sort each row separately\n",
    "#### `axis=1` means we're sorting ***across the columns*** of each column."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6cdcf8ee-326c-4aca-b615-ab1f955f6b82",
   "metadata": {},
   "outputs": [],
   "source": [
    "unsorted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7644661d-80b1-4245-b35d-bc41b28e9843",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.sort(unsorted, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "262f0b52-8fba-4444-9a3d-ce51590b7d5c",
   "metadata": {},
   "source": [
    "#### `axis=1` (sort each row separately) is the default for sorting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd2f4a99-eee1-4d73-a948-09493f8bb099",
   "metadata": {},
   "outputs": [],
   "source": [
    "unsorted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f98552e7-4937-4d43-9cba-e2ae2f22369c",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.sort(unsorted)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bb32b7bf-6af2-451b-b10e-de7a19427aa9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# (C) Copyright 2024 by Ronald Mak"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0ecf06e-23db-4c23-a7bd-3ba74733fd80",
   "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",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
