{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "d403c1a2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'brand': 'Ford', 'model': 'Mustang', 'year': 1964}\n",
      "Ford\n",
      "3\n",
      "<class 'dict'>\n"
     ]
    }
   ],
   "source": [
    "# *** REVIEW ***\n",
    "#\n",
    "# Python dictionary: (key,value) pairs\n",
    "# https://www.w3schools.com/python/python_dictionaries.asp\n",
    "#\n",
    "# A dictionary is a collection which is ordered**, changeable and do not allow duplicates.\n",
    "# ** As of Python version 3.7, dictionaries are ordered. \n",
    "# ** In Python 3.6 and earlier, dictionaries are unordered.\n",
    "\n",
    "thisdict = {\n",
    "  \"brand\": \"Ford\",\n",
    "  \"model\": \"Mustang\",\n",
    "  \"year\": 1964\n",
    "}\n",
    "print(thisdict)\n",
    "print(thisdict[\"brand\"])\n",
    "print(len(thisdict))          # number of fields in doctionary\n",
    "print(type(thisdict))         # Print the data type of a dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "4e6ea4c4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'brand': 'Ford', 'model': 'Mustang', 'year': 2020}\n"
     ]
    }
   ],
   "source": [
    "# Duplicate values will overwrite existing values:\n",
    "\n",
    "thisdict = {\n",
    "  \"brand\": \"Ford\",\n",
    "  \"model\": \"Mustang\",\n",
    "  \"year\": 1964,\n",
    "  \"year\": 2020\n",
    "}\n",
    "print(thisdict) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "0e655eeb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'brand': 'Ford', 'electric': False, 'year': 1964, 'colors': ['red', 'white', 'blue']}\n"
     ]
    }
   ],
   "source": [
    "# The values in dictionary items can be of any data type:\n",
    "thisdict = {\n",
    "  \"brand\": \"Ford\",\n",
    "  \"electric\": False,\n",
    "  \"year\": 1964,\n",
    "  \"colors\": [\"red\", \"white\", \"blue\"]     # Can be a list\n",
    "} \n",
    "print(thisdict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f4e3210b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ***********************************************************************\n",
    "# END review\n",
    "# ***********************************************************************"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d057ea18",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'id': 0, 'name': 'Hero'}, {'id': 1, 'name': 'Dunn'}, {'id': 2, 'name': 'Sue'}, {'id': 3, 'name': 'Chi'}, {'id': 4, 'name': 'Thor'}, {'id': 5, 'name': 'Clive'}, {'id': 6, 'name': 'Hicks'}, {'id': 7, 'name': 'Devin'}, {'id': 8, 'name': 'Kate'}, {'id': 9, 'name': 'Klein'}]\n"
     ]
    }
   ],
   "source": [
    "# users is a LIST of DICTIONARIES !!!\n",
    "\n",
    "users = [\n",
    "    { \"id\": 0, \"name\": \"Hero\" },\n",
    "    { \"id\": 1, \"name\": \"Dunn\" },\n",
    "    { \"id\": 2, \"name\": \"Sue\" },\n",
    "    { \"id\": 3, \"name\": \"Chi\" },\n",
    "    { \"id\": 4, \"name\": \"Thor\" },\n",
    "    { \"id\": 5, \"name\": \"Clive\" },\n",
    "    { \"id\": 6, \"name\": \"Hicks\" },\n",
    "    { \"id\": 7, \"name\": \"Devin\" },\n",
    "    { \"id\": 8, \"name\": \"Kate\" },\n",
    "    { \"id\": 9, \"name\": \"Klein\" }\n",
    "]\n",
    "print(users)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "6f7f6685",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'id': 0, 'name': 'Hero'}\n",
      "0\n",
      "Hero\n"
     ]
    }
   ],
   "source": [
    "print(users[0])\n",
    "print(users[0][\"id\"])\n",
    "print(users[0][\"name\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "28c0cd12",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0, 1), (0, 2), (1, 2), (1, 3), (2, 3), (3, 4), (4, 5), (5, 6), (5, 7), (6, 8), (7, 8), (8, 9)]\n"
     ]
    }
   ],
   "source": [
    "friendships = [(0, 1), (0, 2), (1, 2), (1, 3), (2, 3), (3, 4),\n",
    "        (4, 5), (5, 6), (5, 7), (6, 8), (7, 8), (8, 9)]\n",
    "\n",
    "print(friendships)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d0d87fb5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'id': 0, 'name': 'Hero', 'friends': []}, {'id': 1, 'name': 'Dunn', 'friends': []}, {'id': 2, 'name': 'Sue', 'friends': []}, {'id': 3, 'name': 'Chi', 'friends': []}, {'id': 4, 'name': 'Thor', 'friends': []}, {'id': 5, 'name': 'Clive', 'friends': []}, {'id': 6, 'name': 'Hicks', 'friends': []}, {'id': 7, 'name': 'Devin', 'friends': []}, {'id': 8, 'name': 'Kate', 'friends': []}, {'id': 9, 'name': 'Klein', 'friends': []}]\n"
     ]
    }
   ],
   "source": [
    "# Use the \"friendships\" graph to augment the users[] dictionary\n",
    "\n",
    "# (1) add a key \"friends\", the value is an empty list\n",
    "\n",
    "for user in users:\n",
    "    user[\"friends\"] = []\n",
    "    \n",
    "print(users)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "0d2d8e0c",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'id': 0, 'name': 'Hero', 'friends': [{'id': 1, 'name': 'Dunn', 'friends': [{...}, {'id': 2, 'name': 'Sue', 'friends': [{...}, {...}, {'id': 3, 'name': 'Chi', 'friends': [{...}, {...}, {'id': 4, 'name': 'Thor', 'friends': [{...}, {'id': 5, 'name': 'Clive', 'friends': [{...}, {'id': 6, 'name': 'Hicks', 'friends': [{...}, {'id': 8, 'name': 'Kate', 'friends': [{...}, {'id': 7, 'name': 'Devin', 'friends': [{...}, {...}]}, {'id': 9, 'name': 'Klein', 'friends': [{...}]}]}]}, {'id': 7, 'name': 'Devin', 'friends': [{...}, {'id': 8, 'name': 'Kate', 'friends': [{'id': 6, 'name': 'Hicks', 'friends': [{...}, {...}]}, {...}, {'id': 9, 'name': 'Klein', 'friends': [{...}]}]}]}]}]}]}]}, {'id': 3, 'name': 'Chi', 'friends': [{...}, {'id': 2, 'name': 'Sue', 'friends': [{...}, {...}, {...}]}, {'id': 4, 'name': 'Thor', 'friends': [{...}, {'id': 5, 'name': 'Clive', 'friends': [{...}, {'id': 6, 'name': 'Hicks', 'friends': [{...}, {'id': 8, 'name': 'Kate', 'friends': [{...}, {'id': 7, 'name': 'Devin', 'friends': [{...}, {...}]}, {'id': 9, 'name': 'Klein', 'friends': [{...}]}]}]}, {'id': 7, 'name': 'Devin', 'friends': [{...}, {'id': 8, 'name': 'Kate', 'friends': [{'id': 6, 'name': 'Hicks', 'friends': [{...}, {...}]}, {...}, {'id': 9, 'name': 'Klein', 'friends': [{...}]}]}]}]}]}]}]}, {'id': 2, 'name': 'Sue', 'friends': [{...}, {'id': 1, 'name': 'Dunn', 'friends': [{...}, {...}, {'id': 3, 'name': 'Chi', 'friends': [{...}, {...}, {'id': 4, 'name': 'Thor', 'friends': [{...}, {'id': 5, 'name': 'Clive', 'friends': [{...}, {'id': 6, 'name': 'Hicks', 'friends': [{...}, {'id': 8, 'name': 'Kate', 'friends': [{...}, {'id': 7, 'name': 'Devin', 'friends': [{...}, {...}]}, {'id': 9, 'name': 'Klein', 'friends': [{...}]}]}]}, {'id': 7, 'name': 'Devin', 'friends': [{...}, {'id': 8, 'name': 'Kate', 'friends': [{'id': 6, 'name': 'Hicks', 'friends': [{...}, {...}]}, {...}, {'id': 9, 'name': 'Klein', 'friends': [{...}]}]}]}]}]}]}]}, {'id': 3, 'name': 'Chi', 'friends': [{'id': 1, 'name': 'Dunn', 'friends': [{...}, {...}, {...}]}, {...}, {'id': 4, 'name': 'Thor', 'friends': [{...}, {'id': 5, 'name': 'Clive', 'friends': [{...}, {'id': 6, 'name': 'Hicks', 'friends': [{...}, {'id': 8, 'name': 'Kate', 'friends': [{...}, {'id': 7, 'name': 'Devin', 'friends': [{...}, {...}]}, {'id': 9, 'name': 'Klein', 'friends': [{...}]}]}]}, {'id': 7, 'name': 'Devin', 'friends': [{...}, {'id': 8, 'name': 'Kate', 'friends': [{'id': 6, 'name': 'Hicks', 'friends': [{...}, {...}]}, {...}, {'id': 9, 'name': 'Klein', 'friends': [{...}]}]}]}]}]}]}]}]}\n"
     ]
    }
   ],
   "source": [
    "# (2) populate the lists using the friendships data:\n",
    "\n",
    "for i, j in friendships:\n",
    "    # this works because users[i] is the user whose id is i\n",
    "    users[i][\"friends\"].append(users[j]) # add i as a friend of j\n",
    "    users[j][\"friends\"].append(users[i]) # add j as a friend of i\n",
    "\n",
    "print(users[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "60a81467",
   "metadata": {},
   "outputs": [],
   "source": [
    "def number_of_friends(user):\n",
    "    \"\"\"how many friends does _user_ have?\"\"\"\n",
    "    return len(user[\"friends\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "4e95ebb0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "24\n"
     ]
    }
   ],
   "source": [
    "total_connections = sum(number_of_friends(user) for user in users)\n",
    "print(total_connections)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "63e79b47",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n",
      "2.4\n"
     ]
    }
   ],
   "source": [
    "# Compute avg # connection per user\n",
    "\n",
    "from __future__ import division\n",
    "\n",
    "num_users = len(users)\n",
    "print(num_users)\n",
    "avg_connections = total_connections / num_users\n",
    "print(avg_connections)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "f756fbe7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0, 2), (1, 3), (2, 3), (3, 3), (4, 2), (5, 3), (6, 2), (7, 2), (8, 3), (9, 1)]\n",
      "[(1, 3), (2, 3), (3, 3), (5, 3), (8, 3), (0, 2), (4, 2), (6, 2), (7, 2), (9, 1)]\n"
     ]
    }
   ],
   "source": [
    "# Sort users by # of their connections\n",
    "\n",
    "# create a list (user_id, number_of_friends)\n",
    "num_friends_by_id = [(user[\"id\"], number_of_friends(user)) for user in users]\n",
    "print(num_friends_by_id)\n",
    "\n",
    "num_friends_by_id.sort(                                # Sort the list\n",
    "       key=lambda id_and_friends: id_and_friends[1],   # by num_friends\n",
    "       reverse=True)                                   # largest to smallest\n",
    "\n",
    "print(num_friends_by_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "b02dcd3b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 2, 3, 0, 1, 3]"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Find \"friends of a friend\"\n",
    "\n",
    "# Failed version\n",
    "\n",
    "def friends_of_friend_ids_bad(user):\n",
    "    # \"foaf\" is short for \"friend of a friend\"\n",
    "    return [foaf[\"id\"]\n",
    "        for friend in user[\"friends\"] # for each of user's friends\n",
    "        for foaf in friend[\"friends\"]] # get each of _their_ friends\n",
    "\n",
    "friends_of_friend_ids_bad(users[0])\n",
    "\n",
    "# 0 is in list, TWICE !!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "a2d11c0a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2]\n",
      "[0, 2, 3]\n",
      "[0, 1, 3]\n"
     ]
    }
   ],
   "source": [
    "print([friend[\"id\"] for friend in users[0][\"friends\"]])  # 1, and 2\n",
    "print([friend[\"id\"] for friend in users[1][\"friends\"]])  # 1 --> 0\n",
    "print([friend[\"id\"] for friend in users[2][\"friends\"]])  # 2 --> 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87cf7ddf",
   "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.8.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
