{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Dictionaries\n",
    "\n",
    "Dictionaries are another type of Python container. Instead of storing values by index, they store them associated with a key.\n",
    "\n",
    "You create dictionaries using curly brackets, assiging values to their keys using a colon, e.g.\n",
    "\n",
    "```python\n",
    "a = { \"cat\" : \"mieow\", \"dog\" : \"woof\", \"horse\" : \"neigh\" }\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = { \"cat\" : \"mieow\", \"dog\" : \"woof\", \"horse\" : \"neigh\"}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'cat': 'mieow', 'dog': 'woof', 'horse': 'neigh'}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can look up values in the dictionary by placing the key in square brackets. For example, we can look up the value associated with the key \"cat\" using `a[\"cat\"]`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'mieow'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[\"cat\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What happens if the key does not exist?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'fish'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-4-104bafb971c1>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fish'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m: 'fish'"
     ]
    }
   ],
   "source": [
    "a['fish']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You insert items into the dictionary by assigning values to keys, e.g."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a[\"fish\"] = \"bubble\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'cat': 'mieow', 'dog': 'woof', 'fish': 'bubble', 'horse': 'neigh'}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can list all of the keys or values of a dictionary using the `keys` or `values` functions (which you can find using tab completion and Python help)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function values:\n",
      "\n",
      "values(...) method of builtins.dict instance\n",
      "    D.values() -> an object providing a view on D's values\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(a.values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['fish', 'dog', 'horse', 'cat'])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_values(['bubble', 'woof', 'neigh', 'mieow'])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.values()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can loop over the dictionary by looping over the keys and looking up the values in a for loop, e.g."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A fish goes bubble\n",
      "A dog goes woof\n",
      "A horse goes neigh\n",
      "A cat goes mieow\n"
     ]
    }
   ],
   "source": [
    "for key in a.keys():\n",
    "    print(\"A %s goes %s\" % (key, a[key]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can put anything as a value into a dictionary, including other dictionaries and even lists. The keys should be either numbers or strings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "b = { \"a\" : [\"aardvark\", \"anteater\", \"antelope\"], \"b\" : [\"badger\", \"beetle\"], 26.5: a}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What do you think is at `b[\"a\"][-1]`? What about `b[26.5][\"fish\"]`?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'bubble'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[26.5][\"fish\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercise\n",
    "\n",
    "Below you have a dictionary that contains the full mapping of every letter to its Morse-code equivalent."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "letter_to_morse = {'a':'.-', 'b':'-...', 'c':'-.-.', 'd':'-..', 'e':'.', 'f':'..-.',\n",
    "                   'g':'--.', 'h':'....', 'i':'..', 'j':'.---', 'k':'-.-', 'l':'.-..', 'm':'--',\n",
    "                   'n':'-.', 'o':'---', 'p':'.--.', 'q':'--.-', 'r':'.-.', 's':'...', 't':'-',\n",
    "                   'u':'..-', 'v':'...-', 'w':'.--', 'x':'-..-', 'y':'-.--', 'z':'--..',\n",
    "                   '0':'-----', '1':'.----', '2':'..---', '3':'...--', '4':'....-',\n",
    "                   '5':'.....', '6':'-....', '7':'--...', '8':'---..', '9':'----.',\n",
    "                   ' ':'/' }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## Exercise 1\n",
    "\n",
    "Use the morse code dictionary to look up the morse code for the letters \"s\" and \"o\". What is the morse code for \"SOS\" (the international emergency distress signal)?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "... --- ...\n"
     ]
    }
   ],
   "source": [
    "print(letter_to_morse[\"s\"], letter_to_morse[\"o\"], letter_to_morse[\"s\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercise 2\n",
    "\n",
    "Here is a string that contains a message that must be converted to morse code. Write a loop that converts each letter into the morse code equivalent, and stores it into a list. Print the list out to see the full morse code message that must be sent. Note that you will need to use the `.lower()` function to get the lower case of capital letters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "message = \"SOS We have hit an iceberg and need help quickly\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['...', '---', '...', '/', '.--', '.', '/', '....', '.-', '...-', '.', '/', '....', '..', '-', '/', '.-', '-.', '/', '..', '-.-.', '.', '-...', '.', '.-.', '--.', '/', '.-', '-.', '-..', '/', '-.', '.', '.', '-..', '/', '....', '.', '.-..', '.--.', '/', '--.-', '..-', '..', '-.-.', '-.-', '.-..', '-.--']\n"
     ]
    }
   ],
   "source": [
    "morse = []\n",
    "for letter in message:\n",
    "    morse.append( letter_to_morse[letter.lower()] )\n",
    "print(morse)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercise 3\n",
    "\n",
    "The inverted form of a dictionary is one where the keys are now looked up by value. For example, the below code inverts `letter_to_morse` such that the morse code is the key, and the letter is the value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "morse_to_letter = {}\n",
    "for letter in letter_to_morse.keys():\n",
    "    morse_to_letter[ letter_to_morse[letter] ] = letter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check that this code works by verifying that `morse_to_letter[\"...\"]` equals \"s\".\n",
    "\n",
    "Next, loop through the morse code message you created in exercise 2 and see if you can convert it back to english. Note that you can join a list of letters together into a string using the code `\"\".join(letters)`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sos we have hit an iceberg and need help quickly\n"
     ]
    }
   ],
   "source": [
    "english = []\n",
    "for code in morse:\n",
    "    english.append( morse_to_letter[code] )\n",
    "print(\"\".join(english))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
